<?php

namespace App\Http\Controllers;

use App\Enums\PaymentStatus;
use App\Models\Campaign;
use App\Models\Payment;
use App\Models\Price;
use App\Services\PayPalService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class PaymentController extends Controller
{
    protected PayPalService $paypalService;

    public function __construct(PayPalService $paypalService)
    {
        $this->paypalService = $paypalService;
    }

    public function initiatePayment(Request $request, $campaignId, $priceId)
    {
        $request->validate([
            'payer_email' => 'required|email',
            'payer_name' => 'required|string|max:255',
        ]);

        $campaign = Campaign::findOrFail($campaignId);
        $price = Price::where('campaign_id', $campaignId)->findOrFail($priceId);

        // Create payment record
        $payment = Payment::create([
            'campaign_id' => $campaign->id,
            'price_id' => $price->id,
            'payer_email' => $request->payer_email,
            'payer_name' => $request->payer_name,
            'amount' => $price->amount,
            'currency' => $price->currency,
            'status' => PaymentStatus::Pending,
            'description' => "Payment for {$campaign->data_attribute['name']} - {$price->data_attribute['description']}",
        ]);

        // Create PayPal order
        $returnUrl = route('payment.success', ['payment' => $payment->id]);
        $cancelUrl = route('payment.cancel', ['payment' => $payment->id]);

        $order = $this->paypalService->createOrder(
            $price->amount,
            $price->currency,
            $returnUrl,
            $cancelUrl,
            "Payment for {$campaign->name}"
        );

        if (! $order) {
            $payment->update(['status' => PaymentStatus::Failed]);

            return redirect()->back()->with('error', 'Failed to create PayPal order.');
        }

        // Update payment with PayPal order ID
        $payment->update([
            'paypal_payment_id' => $order['id'],
        ]);

        // Redirect to PayPal
        $approveLink = collect($order['links'])->firstWhere('rel', 'approve');

        return redirect($approveLink['href']);
    }

    /**
     * @throws \Throwable
     */
    public function paymentSuccess(Request $request, Payment $payment)
    {
        DB::beginTransaction();

        try {
            // Capture the payment
            $captureResult = $this->paypalService->captureOrder($payment->paypal_payment_id);

            if ($captureResult && $captureResult['status'] === 'COMPLETED') {
                $payment->update([
                    'status' => PaymentStatus::Completed,
                ]);

                DB::commit();

                // Redirect to campaign's success URL
                $campaign = $payment->campaign;

                return redirect($campaign->success_redirect_url);
            } else {
                $payment->update([
                    'status' => PaymentStatus::Failed,
                ]);

                DB::commit();

                return redirect($payment->campaign->cancel_redirect_url)
                    ->with('error', 'Payment capture failed.');
            }
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Payment Success Error: '.$e->getMessage());

            return redirect($payment->campaign->cancel_redirect_url)
                ->with('error', 'Payment processing error.');
        }
    }

    public function paymentCancel(Payment $payment)
    {
        $payment->update([
            'status' => PaymentStatus::Cancelled,
        ]);

        return redirect($payment->campaign->cancel_redirect_url)
            ->with('error', 'Payment was cancelled.');
    }

    public function paymentWebhook(Request $request)
    {
        // Handle PayPal webhooks for additional payment status updates
        // Implement webhook verification and processing here
    }
}
