<?php

namespace App\Libraries\PaymentGateways;

/**
 * Easypaisa's integration is structurally similar to JazzCash: a signed
 * redirect flow rather than a server-to-server REST charge.
 */
class EasypaisaGateway implements PaymentGatewayInterface
{
    private string $storeId;
    private string $hashKey;
    private string $postUrl = 'https://easypay.easypaisa.com.pk/easypay/Index.jsf';

    public function __construct()
    {
        $this->storeId = env('easypaisa.storeId');
        $this->hashKey = env('easypaisa.hashKey');
    }

    public function charge(float $amount, string $currency, array $metadata = []): array
    {
        $orderRefNum = 'EP' . date('YmdHis') . bin2hex(random_bytes(3));

        $params = [
            'storeId'        => $this->storeId,
            'amount'         => number_format($amount, 2, '.', ''),
            'postBackURL'    => base_url('api/v1/webhooks/easypaisa'),
            'orderRefNum'    => $orderRefNum,
            'expiryDate'     => date('YmdHis', strtotime('+1 hour')),
            'merchantHashedReq' => '', // filled below
            'autoRedirect'   => '1',
            'paymentMethod'  => 'MA_Wallet',
            'emailAddr'      => $metadata['email'] ?? '',
            'mobileNum'      => $metadata['phone'] ?? '',
        ];

        $params['merchantHashedReq'] = $this->generateHash($params);

        return [
            'status'            => 'pending',
            'redirect_url'      => $this->postUrl,
            'client_secret'     => null,
            'gateway_reference' => $orderRefNum,
            'form_fields'       => $params,
        ];
    }

    public function verifyWebhook(string $rawPayload, array $headers): array
    {
        parse_str($rawPayload, $data);

        $receivedHash = $data['merchantHashedReq'] ?? '';
        $forVerification = $data;
        unset($forVerification['merchantHashedReq']);
        $expectedHash = $this->generateHash($forVerification);

        return [
            'verified'               => hash_equals($expectedHash, $receivedHash),
            'gateway_transaction_id' => $data['orderRefNum'] ?? null,
            'status'                 => ($data['status'] ?? '') === '0000' ? 'succeeded' : 'failed',
            'raw'                    => $data,
        ];
    }

    public function refund(string $gatewayTransactionId, float $amount): array
    {
        return ['status' => 'manual_processing_required', 'raw' => []];
    }

    public function getStatus(string $gatewayTransactionId): array
    {
        return ['status' => 'unknown', 'raw' => ['note' => 'Easypaisa status requires their Inquiry API — implement per merchant agreement.']];
    }

    private function generateHash(array $params): string
    {
        ksort($params);
        $filtered = array_filter($params, static fn ($v) => $v !== null && $v !== '');
        $string = implode('&', array_map(static fn ($k, $v) => "{$k}={$v}", array_keys($filtered), $filtered));
        return hash_hmac('sha256', $string, $this->hashKey);
    }
}
