<?php

namespace App\Helpers;

use GuzzleHttp\Client;

class Flutterwave
{
    /**
     * The base URL for the Flutterwave API.
     */
    protected static string $baseUrl = "https://api.flutterwave.com/v3/";
    /**
     * The secret key for authenticating API requests.
     *
     * @var string
     */
    protected string $secretKey;

    /**
     * Create a new Flutterwave instance.
     *
     * @param string $secretKey The secret key for authenticating API requests.
     */
    public function __construct(string $secretKey)
    {
        $this->secretKey = $secretKey;
    }

    private function expiryInterval($givenDate) {
        // Convert the given date to a DateTime object
        $givenDateTime = \DateTime::createFromFormat('m/d', $givenDate);
    
        // Get the current date as a DateTime object
        $currentDate = new \DateTime;
    
        // Calculate the interval
        $interval = $currentDate->diff($givenDateTime);
    
        // Return the interval in days
        return $interval->format('%a');
    }

    public function listNigerianBanks(): array
    {
        $response = $this->sendRequest('GET', 'bank/NG');

        return [
            'status' => $response['status'],
            'message' => $response['message'],
            'banks' => $response['data'],
        ];
    }

    /**
     * Verify a Paystack transaction.
     *
     * @param string $transaction The transaction reference to verify.
     * @return array An array containing the status, message, bill response, authorization code, channel, card type, bank, and reusable flag of the transaction.
     */
    public function verifyTransaction($reference): array
    {
        $response = $this->sendRequest('GET', "transactions/{$reference}/verify");
        return [
            'status' => $response['data']['status'],
            'message' => $response['message'],
            'bill_response' => $response['data']['processor_response'],
            'authorization' => $response['data']['card']['token'] ?? '',
            'channel' => $response['data']['payment_type'],
            'card' => $response['data']['card']['type'] ?? '',
            'bank' => $response['data']['card']['issuer'] ?? '',
            'reusable' => $response['data']['card']['expiry'] !== null ? $this->expiryInterval($response['data']['card']['expiry']) : '',
        ];
    }

    public function fetchTransaction($transaction): array
    {
        $response = $this->sendRequest('GET', "transaction/{$transaction}");
        return [
            'status' => $response['status'],
            'message' => $response['message'],
            'bill_response' => $response['data']['gateway_response'],
            'customer' => $response['data']['customer']['customer_code'],
            'authorization' => $response['data']['authorization']['authorization_code'] ?? '',
            'channel' => $response['data']['authorization']['channel'],
            'card' => $response['data']['authorization']['card_type'] ?? '',
            'bank' => $response['data']['authorization']['bank'],
            'reusable' => $response['data']['authorization']['reusable'] ?? '',
        ];
    }

    public function chargeToken(int $amount, string $email, string $token): array
    {
        $fields = [
            'email' => $email,
            'amount' => $amount,
            'authorization_code' => $token,
        ];

        $response = $this->sendRequest('POST', 'transaction/charge_authorization', $fields);
        return [
            'status' => $response['data']['status'],
            'message' => $response['message'],
            'bill_response' => $response['data']['gateway_response'],
        ];
    }

    public function verifyAccountNumber(string $accountNumber, string $bankCode): array
    {
        $fields = [
            'account_number' => $accountNumber,
            'bank_code' => $bankCode,
        ];

        $response = $this->sendRequest('GET', 'bank/resolve', $fields);

        return [
            'status' => $response['status'],
            'message' => $response['message'],
            'bill_response' => $response['data']['gateway_response'],
        ];
    }

    protected function sendRequest($method, $endpoint, $fields = []): array
    {
        $client = new Client;

        $config = array(
            'headers' => [
                'Authorization' => "Bearer {$this->secretKey}",
                'Cache-Control' => 'no-cache',
            ],
            'verify' => false, // Disable SSL verification
        );

        if ($method === 'POST' || $method === 'PUT') {
            $config = array(
                'headers' => [
                    'Authorization' => "Bearer {$this->secretKey}",
                    'Cache-Control' => 'no-cache',
                    'Content-Type' => 'application/json',
                ],
                'json' => $fields,
                'verify' => false, // Disable SSL verification
            );
        }

        $flutterWaveUrl = self::$baseUrl;
        $response = $client->request($method, "{$flutterWaveUrl}{$endpoint}", $config);
        $responseArray = json_decode($response->getBody(), true);
        
        if($response->getStatusCode() == 200){
            return $responseArray;
        }

        return array();
    }
}
