<?php

namespace App\Services\Payments;

use App\Models\Booking;
use App\Models\Payment;
use App\Models\PaymentGateway;
use App\Models\WebhookEvent;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class PayPalGateway implements PaymentGatewayInterface
{
    public function createPaymentIntent(Booking $booking): Payment
    {
        // TODO: replace with real PayPal order creation and approval URL
        // Example: POST /v2/checkout/orders and read links[].href where rel=approve
        $approvalUrl = 'https://www.sandbox.paypal.com/checkoutnow?token=' . Str::random(16);

        return Payment::create([
            'booking_id' => $booking->id,
            'payment_gateway_id' => $booking->payment_gateway_id,
            'amount' => $booking->amount,
            'currency' => $booking->currency,
            'transaction_id' => Str::uuid()->toString(),
            'status' => 'initiated',
            'payload' => [
                'provider' => 'paypal',
                'approval_url' => $approvalUrl,
            ],
        ]);
    }

    public function handleWebhook(Request $request, PaymentGateway $gateway): ?Payment
    {
        $payload = $request->getContent();
        $decoded = json_decode($payload, true);

        if (! $this->verifySignature($request, $gateway, $payload)) {
            throw new AccessDeniedHttpException('Invalid signature');
        }

        $transactionId = data_get($decoded, 'resource.id');
        $eventType = data_get($decoded, 'event_type');

        $payment = Payment::where('transaction_id', $transactionId)->first();
        if ($payment) {
            if ($eventType === 'PAYMENT.CAPTURE.COMPLETED') {
                $payment->update(['status' => 'captured', 'captured_at' => now(), 'payload' => $decoded]);
            } elseif ($eventType === 'PAYMENT.CAPTURE.DENIED') {
                $payment->update(['status' => 'failed', 'payload' => $decoded]);
            }
        }

        return $payment;
    }

    public function capture(Payment $payment): Payment
    {
        $payment->update(['status' => 'captured', 'captured_at' => now()]);

        return $payment;
    }

    public function refund(Payment $payment, float $amount): Payment
    {
        $payment->update([
            'status' => $amount < $payment->amount ? 'partial_refund' : 'refunded',
            'refunded_at' => now(),
            'payload' => array_merge($payment->payload ?? [], ['refunded_amount' => $amount]),
        ]);

        return $payment;
    }

    public function payout(Payment $payment): bool
    {
        return true;
    }

    private function verifySignature(Request $request, PaymentGateway $gateway, string $payload): bool
    {
        $signature = $request->header('Paypal-Transmission-Sig');
        $expected = hash_hmac('sha256', $payload, (string) $gateway->webhook_secret);

        return $signature && hash_equals($expected, $signature);
    }
}
