<?php
require_once "./config/db_config.php";

class DokuPaymentGateway
{
    public $domainURL;
    const CHECKOUT_URL_PATH = 'checkout/v1/payment';
    const FETCH_ORDER_URL_PATH = 'orders/v1/status/';
    public function __construct()
    {
        $this->domainURL = domainURL;
    }

    public function createOrder($data)
    {
        try {
            // Decode and validate gateway configuration
            $gatewayJson = json_decode($data['gatewayConfig'], true);
            $requiredKeys = ['environment', 'clientId', 'secretKey', 'currencyCode', 'itemName','dueDate'];
            foreach ($requiredKeys as $key) {
                if (empty($gatewayJson[$key])) {
                    return ['status' => 'ERROR', 'message' => "Missing required gateway parameter: $key"];
                }
            }
            $environment = $gatewayJson['environment'];
            $clientId = $gatewayJson['clientId'];
            $secretKey = $gatewayJson['secretKey'];
            $currencyCode = $gatewayJson['currencyCode'];
            $item_name = $gatewayJson['itemName'];

            // Remove country code (any + followed by digits and optional space/dash)            
            $phone = preg_replace('/^\s*(\+?\d{1,4})[\s-]*/', '', $data['phoneNo']);
            // Remove country code (+ or without +) at start
            $phone = preg_replace('/[\s-]+/', '', $phone);            

            // Use provided transaction ID as invoice number
            $invoice_number = $data['txnId'];

            // Generate session ID
            $session_id = bin2hex(random_bytes(16));           
            
            // Prepare line items with dynamic item name
            $line_items = [
                [
                    'name' => $item_name,
                    'price' => $data['amount'],
                    'quantity' => 1
                ]
            ];

            // Prepare customer details
            $customer = [
                'name' => $data['name'],
                'email' => $data['email'],
                'phone' => $phone,
                'address' => 'Indore', // Default value                
            ];

            // Prepare order details
            $order = [
                'amount' => $data['amount'],         
                'currency' => $currencyCode,
                'invoice_number' => $invoice_number,
                'line_items' => $line_items,
                'session_id' => $session_id,
                'disable_retry_payment'=> is_bool($gatewayJson['retry'])?$gatewayJson['retry']:FALSE
            ];

            // Prepare payment details
            $payment = [
                'payment_due_date' => (!empty($gatewayJson['dueDate'])&&is_int($gatewayJson['dueDate'])) ? $gatewayJson['dueDate'] : 60
,
            ];

            // Compose request body
            $body = [
                'customer' => $customer,
                'order' => $order,
                'payment' => $payment
            ];
            $body_json = json_encode($body);           
            // Generate signature
            $request_id = $invoice_number;
            $request_timestamp = gmdate('Y-m-d\TH:i:s\Z');
            $request_target = '/'.self::CHECKOUT_URL_PATH;
            $digest = base64_encode(hash('sha256', $body_json, true));
            $rawSignature = "Client-Id:{$clientId}\n" .
                            "Request-Id:{$request_id}\n" .
                            "Request-Timestamp:{$request_timestamp}\n" .
                            "Request-Target:{$request_target}\n" .
                            "Digest:{$digest}";
            $signature = base64_encode(hash_hmac('sha256', $rawSignature, $secretKey, true));

            // Set headers
           
            $headers = [
                'Content-Type: application/json',
                'Signature: HMACSHA256=' . $signature,
                'Request-Id: ' . $request_id,
                'Client-Id: ' . $clientId,
                'Request-Timestamp: ' . $request_timestamp
            ];            
            // Make POST request to Doku API
            $ch = curl_init($environment . self::CHECKOUT_URL_PATH);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body_json);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Adjust in production
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);           
            // Handle response
            if ($http_code == 200) {
                $response_data = json_decode($response, true);
                if (isset($response_data['response']['payment']['url'])) {
                    return [
                        'status' => 'SUCCESS',
                        'url' => $response_data['response']['payment']['url'],
                        'txnId' => $invoice_number
                    ];
                }
                return [
                    'status' => 'ERROR',
                    'message' => 'Payment URL not found in response'
                ];
            } else {
                $response_data = json_decode($response, true);
                $error_message = isset($response_data['message']) ? $response_data['message'] : 'Unknown error';
                return [
                    'status' => 'ERROR',
                    'message' => $error_message
                ];
            }
        } catch (Exception $e) {
            return ['status' => 'ERROR', 'message' => $e->getMessage()];
        }
    }

    /**
     * Fetches the transaction status from Doku API using the transaction ID and gateway configuration.
     *
     * @param array $data Contains 'txnId' (transaction ID) and 'gatewayConfig' (JSON string with environment, clientId, secretKey)
     * @return array Response with status, transaction state, and optional error message or full JSON response
     */
    public function fetchOrder($data)
    {
        try {
            // Decode and validate gateway configuration
            $gatewayJson = json_decode($data['gatewayConfig'], true);
            $requiredKeys = ['environment', 'clientId', 'secretKey'];
            foreach ($requiredKeys as $key) {
                if (empty($gatewayJson[$key])) {
                    return ['status' => 'ERROR', 'message' => "Missing required gateway parameter: $key"];
                }
            }
            $environment = $gatewayJson['environment'];
            $clientId = $gatewayJson['clientId'];
            $secretKey = $gatewayJson['secretKey'];
            $txnId = $data['txnId'];

            // Generate request details
            $requestId = bin2hex(random_bytes(16)); // Unique request ID
            $requestTimestamp = gmdate('Y-m-d\TH:i:s\Z'); // UTC timestamp
            $requestTarget = '/'.self::FETCH_ORDER_URL_PATH . $txnId; // API endpoint
            $targetTosend = self::FETCH_ORDER_URL_PATH . $txnId;
            // Create the string to sign for HMAC-SHA256 signature
            $stringToSign = "Client-Id:{$clientId}\n" .
                            "Request-Id:{$requestId}\n" .
                            "Request-Timestamp:{$requestTimestamp}\n" .
                            "Request-Target:{$requestTarget}";

            // Generate HMAC-SHA256 signature
            $signature = base64_encode(hash_hmac('sha256', $stringToSign, $secretKey, true));

            // Set request headers
            $headers = [
                'Client-Id: ' . $clientId,
                'Request-Id: ' . $requestId,
                'Request-Timestamp: ' . $requestTimestamp,
                'Signature: HMACSHA256=' . $signature
            ];

            // Initialize and configure cURL for GET request
            $ch = curl_init($environment . $targetTosend);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable in dev; enable in production with proper certs
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            // Process API response
            if ($httpCode == 200) {
                $responseData = json_decode($response, true);
                if (isset($responseData['transaction']['status'])) {
                    return [
                        'status' => 'SUCCESS',
                        'transactionState' => $responseData['transaction']['status'],
                        'jsonResponse' => $responseData
                    ];
                }
                return [
                    'status' => 'ERROR',
                    'message' => 'Transaction status not found in response'
                ];
            }
            return [
                'status' => 'ERROR',
                'message' => 'Failed to fetch transaction details. HTTP Code: ' . $httpCode,
                'response'=> $response
            ];
        } catch (Exception $e) {
            return [
                'status' => 'ERROR',
                'message' => 'Exception occurred: ' . $e->getMessage()
            ];
        }
    }
}