<?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 PaystackGateway implements PaymentGatewayInterface
{
    public function createPaymentIntent(Booking $booking): Payment
    {
        // TODO: replace with real Paystack transaction init and auth URL
        // Example: POST /transaction/initialize and read authorization_url
        $authUrl = 'https://paystack.com/pay/' . Str::random(10);

        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' => 'paystack',
                'authorization_url' => $authUrl,
            ],
        ]);
    }

    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, 'data.reference');
        $status = data_get($decoded, 'data.status');

        $payment = Payment::where('transaction_id', $transactionId)->first();
        if ($payment) {
            if ($status === 'success') {
                $payment->update(['status' => 'captured', 'captured_at' => now(), 'payload' => $decoded]);
            } elseif ($status === 'failed') {
                $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('x-paystack-signature');
        $expected = hash_hmac('sha512', $payload, (string) $gateway->webhook_secret);

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