<?php
require_once "./config/db_config.php";
class AuthorizeDotNetPaymentGateway
{
    public $domainURL;  

    public function __construct()
    {
        $this->domainURL = domainURL;
    }
 
    public function createOrder($data)
    {       
        $gatewayJson  = json_decode($data['gatewayConfig'], true);        
        $apiLoginId = $gatewayJson['apiLoginId'];
        $transactionKey = $gatewayJson['transactionKey'];
        $currency  = $gatewayJson['currency'];
        $environment  = $gatewayJson['environment'];
        $date         = date("Y/m/d H:i");
        $invoiceNumber = $gatewayJson['invoiceId'];
        
        // Initialize cURL
        $curl = curl_init();

        // Generate dynamic values
        $refId = rand(100000, 999999);
        $amount = $data['amount'];
        
        $randomPart = rand(1000, 9999);
        $timestampPart = time(); 
        $customerProfileId = $randomPart . $timestampPart;;
        $returnUrl = $this->domainURL."/paymentResponse.php?authInvoiceId=".$invoiceNumber;

        $name = trim($data['name']);
        // Replace multiple spaces with a single space
        $name = preg_replace('/\s+/', ' ', $name);
        // Split into parts
        $nameParts = explode(' ', $name);
        // Get first and last names
        $firstName = $nameParts[0];
        $lastName = end($nameParts);

        // Build the request payload
        $requestPayload = [
            "getHostedPaymentPageRequest" => [
                "merchantAuthentication" => [
                    "name" => $apiLoginId,
                    "transactionKey" => $transactionKey
                ],
                "refId" => $refId,
                "transactionRequest" => [
                    "transactionType" => "authCaptureTransaction",
                    "amount" => $amount,
                    "profile" => [
                        "customerProfileId" => $customerProfileId
                    ],
                    "order" => [
                        "invoiceNumber" => $invoiceNumber
                    ],
                    "customer" => [
                        "email" => isset($data['email']) ? $data['email'] : $data['code'].'@yopmail.com'
                    ],
                    "billTo" => [
                        "firstName" => $firstName,
                        "lastName" => $lastName
                    ]
                ],
                "hostedPaymentSettings" => [
                    "setting" => [
                        [
                            "settingName" => "hostedPaymentReturnOptions",
                            "settingValue" => json_encode([
                                "showReceipt" => true,
                                "url" => $returnUrl,
                                "cancelUrl" => $returnUrl
                            ])
                        ]
                    ]
                ]
            ]
        ];

        $jsonRequest = json_encode($requestPayload);

        // Set cURL options
        curl_setopt_array($curl, [
            CURLOPT_URL => $environment,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $jsonRequest,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json'
            ]
        ]);

        // Execute cURL and handle response
        $response = curl_exec($curl);
       
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        
        curl_close($curl);
        $cleanJson = preg_replace('/^\xEF\xBB\xBF/', '', trim($response));
        $dataResponse = json_decode($cleanJson, true);
        
        return [
            'token' => isset($dataResponse['token']) ? $dataResponse['token'] : '',
            'paymentRequest' => $jsonRequest
        ];
    }

    public function fetchOrder($data)
    {
        $gatewayJson  = json_decode($data['gatewayConfig'], true);
        $apiLoginId = $gatewayJson['apiLoginId'];
        $transactionKey = $gatewayJson['transactionKey'];     
        $environment  = $gatewayJson['environment'];
        $invoiceNumber = $gatewayJson['invoiceId'];
        $txnId = $data['txnId'];
       
        // If txnId is empty, try to fetch via unsettled transactions or batch ID
        if (empty($txnId)) {            
            
            if ($invoiceNumber) {
                //Checking for unsettled transactions
                $unsettledResponse = $this->fetchUnsettledTransactions($apiLoginId, $transactionKey, $invoiceNumber, $environment);
                if (isset($unsettledResponse['txnId']) && !empty($unsettledResponse['txnId'])) {
                    return $unsettledResponse;
                }
                
                $fromDate = date('Y-m-d\TH:i:s\Z', strtotime($data['paymentDate'].' -1 day'));
                $toDate = date('Y-m-d\TH:i:s\Z', strtotime($data['paymentDate'].' +1 day')); 
                $batchResponse = $this->fectBatchId($toDate, $fromDate, $apiLoginId, $transactionKey , $environment);
                
                if (isset($batchResponse['batchList']) && !empty($batchResponse['batchList'])) {
                    foreach ($batchResponse['batchList'] as $batch) {
                        $batchId = $batch['batchId'];
                        $transactionResponse = $this->fetchTransactionViaBatchID($batchId, $apiLoginId, $transactionKey, $invoiceNumber , $environment);
                        
                        if (isset($transactionResponse['txnId']) && !empty($transactionResponse['txnId'])) {
                            return $transactionResponse;
                        }
                    }
                }
                error_log("No transaction found for invoiceNumber $invoiceNumber, paymentDate {$data['paymentDate']}");
                return ['status' => 'INVALID-ORDER', 'error' => 'No matching transaction found'];
            }
            error_log("Invoice number not found for paymentDate {$data['paymentDate']}");
            return ['status' => 'INVALID-ORDER', 'error' => 'Invoice number not found'];
        }

        $jsonRequest = '{
            "getTransactionDetailsRequest": {
                "merchantAuthentication": {
                    "name": "'.$apiLoginId.'",
                    "transactionKey": "'.$transactionKey.'"
                },
                "transId": "'.$txnId.'"
            }
        }';
        $curl = curl_init();
        curl_setopt_array($curl, array(
        CURLOPT_URL => $environment,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $jsonRequest,
        CURLOPT_HTTPHEADER => array(
            'Content-Type: application/json'
        ),
        ));

        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        $cleanJson = preg_replace('/^\xEF\xBB\xBF/', '', trim($response));
        $jsonResponse = json_decode($cleanJson, true);
        //   echo "<pre>";  print_r($jsonResponse);
        $transactionStatus = '';
        if(isset($jsonResponse['transaction']['transactionStatus']) && isset($jsonResponse['transaction']['transId']) && $jsonResponse['transaction']['transId'] == $txnId){
            $transactionStatus = $jsonResponse['transaction']['transactionStatus'];
        }

        return [
            'transactionStatus' => $transactionStatus,
            'status' => ($transactionStatus == 'settledSuccessfully' || $transactionStatus == 'capturedPendingSettlement') ? 'SUCCESS' : 'FAILED',
            'txnId' => $txnId,
            'notificationResponse' => $jsonResponse
        ];
    }

    public function fectBatchId($to_date, $from_date, $apiLoginId, $transactionKey,$environment)
    {
        $jsonRequest = '{
            "getSettledBatchListRequest": {
                "merchantAuthentication": {
                    "name": "'.$apiLoginId.'",
                    "transactionKey": "'.$transactionKey.'"
                },
                "firstSettlementDate": "'.$from_date.'",
                "lastSettlementDate": "'.$to_date.'"
            }
        }';

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $environment,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $jsonRequest,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        $cleanJson = preg_replace('/^\xEF\xBB\xBF/', '', trim($response));
        $jsonResponse = json_decode($cleanJson, true);

        if ($httpCode == 200 && isset($jsonResponse['messages']['resultCode']) && $jsonResponse['messages']['resultCode'] == 'Ok') {
            return [
                'batchList' => $jsonResponse['batchList'] ?? [],
                'status' => 'SUCCESS',
                'notificationResponse' => $jsonResponse
            ];
        } else {
            return [
                'batchList' => [],
                'status' => 'FAILED',
                'error' => $jsonResponse['messages']['message'][0]['text'] ?? 'Unknown error',
                'notificationResponse' => $jsonResponse
            ];
        }
    }

    private function fetchTransactionViaBatchID($batch_id, $merchant_name, $transactionKey, $invoiceNumber,$environment)
    {
        $jsonRequest = '{
            "getTransactionListRequest": {
                "merchantAuthentication": {
                    "name": "'.$merchant_name.'",
                    "transactionKey": "'.$transactionKey.'"
                },
                "batchId": "'.$batch_id.'",
                "sorting": {
                    "orderBy": "submitTimeUTC",
                    "orderDescending": "true"
                },
                "paging": {
                    "limit": "1000",
                    "offset": "1"
                }
            }
        }';

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $environment, 
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $jsonRequest,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        $cleanJson = preg_replace('/^\xEF\xBB\xBF/', '', trim($response));
        $jsonResponse = json_decode($cleanJson, true);

        $transactionStatus = '';
        $txnId = '';
        
        if ($httpCode == 200 && isset($jsonResponse['messages']['resultCode']) && $jsonResponse['messages']['resultCode'] == 'Ok') {
            if (isset($jsonResponse['transactions']) && !empty($jsonResponse['transactions'])) {
                foreach ($jsonResponse['transactions'] as $transaction) {
                    if (isset($transaction['invoiceNumber']) && $transaction['invoiceNumber'] == $invoiceNumber) {
                        $transactionStatus = $transaction['transactionStatus'];
                        $txnId = $transaction['transId'];
                        return [
                            'transactionStatus' => $transactionStatus,
                            'status' => ($transactionStatus == 'settledSuccessfully' || $transactionStatus == 'capturedPendingSettlement') ? 'SUCCESS' : 'FAILED',
                            'txnId' => $txnId,
                            'notificationResponse' => $jsonResponse
                        ];
                    }
                }
            }
        }
        
        return [
            'transactionStatus' => '',
            'status' => 'FAILED',
            'txnId' => '',
            'notificationResponse' => $jsonResponse,
            'error' => 'No matching transaction found for invoice number'
        ];
    }

    private function fetchUnsettledTransactions($merchant_name, $transactionKey, $invoiceNumber, $environment)
    {
        $jsonRequest = '{
            "getUnsettledTransactionListRequest": {
                "merchantAuthentication": {
                    "name": "'.$merchant_name.'",
                    "transactionKey": "'.$transactionKey.'"
                },
                "sorting": {
                    "orderBy": "submitTimeUTC",
                    "orderDescending": "true"
                },
                "paging": {
                    "limit": "1000",
                    "offset": "1"
                }
            }
        }';

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $environment, 
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $jsonRequest,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json'
            ),
        ));

        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        $cleanJson = preg_replace('/^\xEF\xBB\xBF/', '', trim($response));
        $jsonResponse = json_decode($cleanJson, true);

        $transactionStatus = '';
        $txnId = '';
        
        if ($httpCode == 200 && isset($jsonResponse['messages']['resultCode']) && $jsonResponse['messages']['resultCode'] == 'Ok') {
            if (isset($jsonResponse['transactions']) && !empty($jsonResponse['transactions'])) {
                foreach ($jsonResponse['transactions'] as $transaction) {
                    if (isset($transaction['invoiceNumber']) && $transaction['invoiceNumber'] == $invoiceNumber) {
                        $transactionStatus = $transaction['transactionStatus'];
                        $txnId = $transaction['transId'];
                        return [
                            'transactionStatus' => $transactionStatus,
                            'status' => ($transactionStatus == 'capturedPendingSettlement' || $transactionStatus == 'settledSuccessfully') ? 'SUCCESS' : 'FAILED',
                            'txnId' => $txnId,
                            'notificationResponse' => $jsonResponse
                        ];
                    }
                }
            }
        }
        
        error_log("No unsettled transaction found for invoiceNumber $invoiceNumber");
        return [
            'transactionStatus' => '',
            'status' => 'FAILED',
            'txnId' => '',
            'notificationResponse' => $jsonResponse,
            'error' => 'No matching unsettled transaction found'
        ];
    }

}