<?php

namespace App\Services\Finance\Gateways;

use App\Contracts\Finance\PaymentGatewayDriver;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\PaymentAllocation;
use App\Models\User;
use App\Services\Accounting\AccountLookupService;
use App\Services\Finance\DocumentNumberService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use InvalidArgumentException;

class PayChanguGateway implements PaymentGatewayDriver
{
    public function key(): string
    {
        return 'paychangu';
    }

    public function initiate(Invoice $invoice, User $payer, float $amount, array $context = []): array
    {
        $config = config('payments.paychangu');

        if (! ($config['enabled'] ?? false) || empty($config['public_key'])) {
            throw new InvalidArgumentException('PayChangu is not configured. Set PAYCHANGU_ENABLED and API keys in .env');
        }

        $txRef = 'PC-'.Str::upper(Str::random(12));

        $payment = DB::transaction(function () use ($invoice, $payer, $amount, $txRef, $context) {
            $payment = Payment::query()->create([
                'payment_number' => app(DocumentNumberService::class)->next('PAY', Payment::class, 'payment_number'),
                'payee_name' => $invoice->student?->full_name,
                'amount' => number_format($amount, 2, '.', ''),
                'payment_date' => now()->toDateString(),
                'payment_method' => 'paychangu',
                'account_id' => app(AccountLookupService::class)->configured('cash')->id,
                'status' => 'pending',
                'gateway' => 'paychangu',
                'gateway_reference' => $txRef,
                'gateway_status' => 'initiated',
                'recorded_by' => $payer->id,
                'notes' => $context['notes'] ?? null,
                'gateway_payload' => [
                    'invoice_id' => $invoice->id,
                    'invoice_number' => $invoice->invoice_number,
                ],
            ]);

            PaymentAllocation::query()->create([
                'payment_id' => $payment->id,
                'invoice_id' => $invoice->id,
                'allocated_amount' => $payment->amount,
            ]);

            return $payment;
        });

        $names = explode(' ', $payer->name, 2);

        return [
            'payment' => $payment,
            'redirect_url' => null,
            'view' => 'parent.fees.paychangu-redirect',
            'view_data' => [
                'payment' => $payment,
                'invoice' => $invoice,
                'hostedUrl' => $config['hosted_url'],
                'publicKey' => $config['public_key'],
                'txRef' => $txRef,
                'amount' => $amount,
                'currency' => config('payments.default_currency', 'MWK'),
                'callbackUrl' => route('payments.paychangu.callback'),
                'returnUrl' => route('payments.paychangu.return'),
                'email' => $payer->email,
                'firstName' => $names[0] ?? 'Parent',
                'lastName' => $names[1] ?? 'Guardian',
                'title' => 'School Fee — '.$invoice->invoice_number,
                'description' => 'Payment for '.$invoice->student?->full_name,
            ],
            'message' => 'Redirecting to PayChangu checkout…',
        ];
    }

    public function verify(Payment $payment): bool
    {
        $secret = config('payments.paychangu.secret_key');
        $txRef = $payment->gateway_reference;

        if (! $secret || ! $txRef) {
            return false;
        }

        $verifyUrl = rtrim(config('payments.paychangu.verify_url'), '/').'/'.$txRef;

        $response = \Illuminate\Support\Facades\Http::withToken($secret)
            ->acceptJson()
            ->get($verifyUrl);

        if (! $response->successful()) {
            return false;
        }

        $status = data_get($response->json(), 'data.status');

        return in_array($status, ['success', 'successful', 'completed'], true);
    }
}
