<?php

namespace App\Services\Gateways;

use App\Contracts\PaymentGatewayInterface;
use App\Models\Order;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * Fenopay gateway.
 *
 * When you receive API credentials, fill in:
 *   - FENOPAY_API_URL         (from Fenopay onboarding docs)
 *   - FENOPAY_API_KEY         (from Fenopay dashboard)
 *   - FENOPAY_MERCHANT_ID
 *   - FENOPAY_WEBHOOK_SECRET
 */
class FenopayGateway implements PaymentGatewayInterface
{
    private string $apiUrl;
    private string $apiKey;
    private string $merchantId;
    private string $webhookSecret;

    public function __construct(string $apiKey, string $merchantId, string $webhookSecret)
    {
        $this->apiUrl        = rtrim(config('payment.fenopay_api_url', 'https://api.fenopay.com/v1'), '/');
        $this->apiKey        = $apiKey;
        $this->merchantId    = $merchantId;
        $this->webhookSecret = $webhookSecret;
    }

    public function createSession(Order $order, string $returnUrl, string $cancelUrl): array
    {
        $response = Http::withHeaders([
                'Authorization' => "Bearer {$this->apiKey}",
                'X-Merchant-ID' => $this->merchantId,
            ])
            ->post("{$this->apiUrl}/checkout/sessions", [
                'reference'   => $order->order_number,
                'amount'      => (int) round($order->total * 100), // pence
                'currency'    => $order->currency ?? 'GBP',
                'description' => "BioSupply UK order {$order->order_number}",
                'email'       => $order->user?->email ?? $order->guest_email,
                'success_url' => $returnUrl,
                'cancel_url'  => $cancelUrl,
            ]);

        if (!$response->successful()) {
            Log::error('Fenopay: createSession failed', ['response' => $response->json()]);
            throw new \RuntimeException('Payment session could not be created. Please try again.');
        }

        $data = $response->json();

        return [
            'session_id'   => $data['session_id'],   // TODO: confirm field name from docs
            'redirect_url' => $data['checkout_url'], // TODO: confirm field name from docs
        ];
    }

    public function getSessionStatus(string $sessionId): string
    {
        $response = Http::withHeaders([
                'Authorization' => "Bearer {$this->apiKey}",
                'X-Merchant-ID' => $this->merchantId,
            ])
            ->get("{$this->apiUrl}/checkout/sessions/{$sessionId}");

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

        $status = $response->json('status'); // TODO: confirm field + value names from docs

        return match ($status) {
            'paid', 'complete', 'success' => 'paid',
            'failed', 'declined', 'expired' => 'failed',
            default => 'pending',
        };
    }

    public function handleWebhook(array $payload, string $rawBody, string $signature): ?string
    {
        $expected = hash_hmac('sha256', $rawBody, $this->webhookSecret);
        if (!hash_equals($expected, $signature)) {
            return null;
        }

        $status = $payload['event'] ?? null; // TODO: confirm event names from docs

        if (in_array($status, ['payment.success', 'payment.completed'])) {
            return $payload['reference'] ?? null; // returns order_number
        }

        return null;
    }
}
