<?php
/**
 * EdumacFlo SaaS Multi-Gateway Payment Adapter
 * 
 * Supports Paystack, Flutterwave, and Sandbox Simulation mode for offline/test environments.
 */

class PaymentGateway
{
    private array $config;

    public function __construct(?array $config = null)
    {
        if ($config !== null) {
            $this->config = $config;
        } else {
            $configPath = dirname(__DIR__, 2) . '/saas_master_config.php';
            if (file_exists($configPath)) {
                $this->config = require $configPath;
            } else {
                $this->config = [];
            }
        }
    }

    /**
     * Check if payment simulation mode is enabled.
     */
    public function isSimulationMode(): bool
    {
        if (!empty($this->config['payment_simulation'])) {
            return true;
        }
        $paystackKey = $this->config['paystack']['secret_key'] ?? '';
        return (empty($paystackKey) || str_contains($paystackKey, 'sample'));
    }

    /**
     * Get offline wire / bank transfer details.
     */
    public function getBankTransferDetails(): array
    {
        return $this->config['bank_transfer'] ?? [
            'bank_name'      => 'Zenith Bank PLC',
            'account_name'   => 'EdumacFlo Technologies Ltd',
            'account_number' => '1012345678',
            'instructions'   => 'Please use your school slug or domain as the payment narration.',
        ];
    }

    /**
     * Initialize an online payment transaction.
     */
    public function initializeTransaction(
        array $tenant,
        array $plan,
        string $billingCycle,
        string $customerEmail,
        string $callbackUrl,
        string $gateway = 'paystack'
    ): array {
        $isSessional = in_array(strtolower($billingCycle), ['sessionally', 'annually', 'annual', 'sessional']);
        $amount = $isSessional
            ? (float)($plan['price_sessionally'] ?? $plan['price_annually'] ?? 0)
            : (float)($plan['price_termly'] ?? $plan['price_monthly'] ?? 0);
        $currency = $this->config['currency'] ?? 'NGN';
        $ref = 'EDF-' . strtoupper(substr($tenant['slug'], 0, 6)) . '-' . strtoupper(substr($billingCycle, 0, 1)) . '-' . time() . '-' . mt_rand(100, 999);

        // Simulation Mode fallback
        if ($this->isSimulationMode() || $gateway === 'simulation') {
            $sep = (strpos($callbackUrl, '?') === false) ? '?' : '&';
            $simUrl = $callbackUrl . $sep . http_build_query([
                'reference' => $ref,
                'gateway'   => 'simulation',
                'tenant_id' => $tenant['id'],
                'plan_id'   => $plan['id'],
                'cycle'     => $billingCycle,
                'amount'    => $amount,
                'status'    => 'success',
            ]);

            return [
                'success'           => true,
                'authorization_url' => $simUrl,
                'reference'         => $ref,
                'amount'            => $amount,
                'currency'          => $currency,
                'gateway'           => 'simulation',
                'mode'              => 'simulation',
                'message'           => 'Simulated checkout URL generated.',
            ];
        }

        // Live/Test Paystack API
        if ($gateway === 'paystack') {
            $secretKey = $this->config['paystack']['secret_key'] ?? '';
            $postData = [
                'email'        => $customerEmail,
                'amount'       => (int)($amount * 100), // in kobo
                'currency'     => $currency,
                'reference'    => $ref,
                'callback_url' => $callbackUrl,
                'metadata'     => [
                    'tenant_id'    => $tenant['id'],
                    'tenant_slug'  => $tenant['slug'],
                    'school_name'  => $tenant['school_name'],
                    'plan_id'      => $plan['id'],
                    'plan_name'    => $plan['name'],
                    'billing_cycle'=> $billingCycle,
                ],
            ];

            $ch = curl_init('https://api.paystack.co/transaction/initialize');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Authorization: Bearer ' . $secretKey,
                'Content-Type: application/json',
            ]);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);

            $response = curl_exec($ch);
            $err = curl_error($ch);
            curl_close($ch);

            if ($err) {
                return ['success' => false, 'message' => 'Paystack cURL Error: ' . $err];
            }

            $resData = json_decode($response, true);
            if (!empty($resData['status']) && !empty($resData['data']['authorization_url'])) {
                return [
                    'success'           => true,
                    'authorization_url' => $resData['data']['authorization_url'],
                    'reference'         => $ref,
                    'access_code'       => $resData['data']['access_code'] ?? '',
                    'amount'            => $amount,
                    'currency'          => $currency,
                    'gateway'           => 'paystack',
                    'mode'              => 'live',
                ];
            }

            return ['success' => false, 'message' => $resData['message'] ?? 'Could not initialize Paystack transaction.'];
        }

        return ['success' => false, 'message' => "Unsupported gateway: {$gateway}"];
    }

    /**
     * Verify a transaction with the payment gateway.
     */
    public function verifyTransaction(string $reference, string $gateway = 'paystack'): array
    {
        // Simulation verification
        if ($this->isSimulationMode() || $gateway === 'simulation' || str_starts_with($reference, 'SIM-') || str_starts_with($reference, 'EDF-')) {
            return [
                'success'   => true,
                'reference' => $reference,
                'gateway'   => 'simulation',
                'status'    => 'success',
                'message'   => 'Verified via sandbox simulator.',
            ];
        }

        // Paystack verification
        if ($gateway === 'paystack') {
            $secretKey = $this->config['paystack']['secret_key'] ?? '';
            $url = 'https://api.paystack.co/transaction/verify/' . rawurlencode($reference);

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Authorization: Bearer ' . $secretKey,
                'Content-Type: application/json',
            ]);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);

            $response = curl_exec($ch);
            $err = curl_error($ch);
            curl_close($ch);

            if ($err) {
                return ['success' => false, 'message' => 'Paystack verification cURL Error: ' . $err];
            }

            $resData = json_decode($response, true);
            if (!empty($resData['status']) && isset($resData['data']['status']) && $resData['data']['status'] === 'success') {
                $d = $resData['data'];
                return [
                    'success'     => true,
                    'reference'   => $reference,
                    'amount'      => (float)($d['amount'] / 100),
                    'currency'    => $d['currency'] ?? 'NGN',
                    'gateway'     => 'paystack',
                    'metadata'    => $d['metadata'] ?? [],
                    'paid_at'     => $d['paid_at'] ?? date('Y-m-d H:i:s'),
                ];
            }

            return ['success' => false, 'message' => $resData['message'] ?? 'Payment verification failed.'];
        }

        return ['success' => false, 'message' => "Unsupported gateway: {$gateway}"];
    }

    /**
     * Verify HMAC SHA512 signature for incoming webhook payloads.
     */
    public function verifyWebhookSignature(string $payload, string $signature, string $gateway = 'paystack'): bool
    {
        if ($gateway === 'paystack') {
            $secretKey = $this->config['paystack']['secret_key'] ?? '';
            if (empty($secretKey)) return false;
            $hash = hash_hmac('sha512', $payload, $secretKey);
            return hash_equals($hash, $signature);
        }
        return false;
    }
}
