<?php

namespace App\Http\Controllers\App;

use App\Enums\PaymentStatus;
use App\Http\Controllers\Controller;
use App\Models\AffiliateCommission;
use App\Models\PaymentRequest;
use App\Models\ProjectMilestone;
use App\Services\Payments\PaymentProviderInterface;
use App\Support\ActivityLogger;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;

class PaymentController extends Controller
{
    public function store(Request $request, PaymentProviderInterface $paymentProvider): RedirectResponse
    {
        $validated = $request->validate([
            'project_id' => ['required', 'exists:projects,id'],
            'project_milestone_id' => ['required', 'exists:project_milestones,id'],
            'amount' => ['required', 'numeric'],
            'due_date' => ['nullable', 'date'],
        ]);

        $milestone = ProjectMilestone::with('project')->findOrFail($validated['project_milestone_id']);
        Gate::authorize('view-project', $milestone->project);

        $paymentRequest = PaymentRequest::create([
            'project_id' => $validated['project_id'],
            'project_milestone_id' => $milestone->id,
            'client_contact_id' => $milestone->project->client_contact_id,
            'created_by_user_id' => $request->user()->id,
            'amount' => $validated['amount'],
            'currency' => config('payments.default_currency'),
            'provider' => $paymentProvider->providerName(),
            'status' => PaymentStatus::Ready->value,
            'due_date' => $validated['due_date'] ?? null,
        ]);

        $paymentRequest->update([
            'payment_url' => $paymentProvider->createPaymentLink($paymentRequest),
        ]);

        ActivityLogger::log('payment.request_sent', $request->user(), $paymentRequest, [], $paymentRequest->toArray(), $request);

        return back()->with('success', 'Payment request created.');
    }

    public function confirm(Request $request, PaymentRequest $paymentRequest): RedirectResponse
    {
        $paymentRequest->update([
            'status' => PaymentStatus::ManuallyConfirmed->value,
            'paid_at' => now(),
        ]);

        $paymentRequest->events()->create([
            'event_type' => 'manual_confirmation',
            'payload' => ['confirmed_by' => $request->user()->id],
            'occurred_at' => now(),
        ]);

        $project = $paymentRequest->project;
        if ($project?->affiliate_user_id) {
            $rate = $project->affiliate?->affiliateProfile?->default_commission_rate
                ?? config('mtc.default_affiliate_commission_rate');

            AffiliateCommission::updateOrCreate(
                [
                    'project_id' => $project->id,
                    'payment_request_id' => $paymentRequest->id,
                    'affiliate_user_id' => $project->affiliate_user_id,
                ],
                [
                    'gross_amount' => $paymentRequest->amount,
                    'collected_amount' => $paymentRequest->amount,
                    'commission_rate' => $rate,
                    'commission_amount' => round($paymentRequest->amount * ($rate / 100), 2),
                    'status' => 'calculated',
                    'visible_to_affiliate' => true,
                ]
            );
        }

        ActivityLogger::log('payment.confirmed', $request->user(), $paymentRequest, [], $paymentRequest->toArray(), $request);

        return back()->with('success', 'Payment manually confirmed and commission recalculated.');
    }
}
