<?php

namespace Modules\Agent\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use Modules\Account\Models\AccountModel;
use Modules\Account\Models\PayagentModel;
use Modules\Agent\Models\AgentModel;
use Modules\Paymethod\Models\GeideaWave as ModelsGeideaWave;
use Modules\Company\Models\CompanyModel;

class Payment extends BaseController
{
    protected $Viewpath;
    protected $db;
    protected $userModel;
    protected $userDetailModel;
    protected $agentModel;
    protected $roleModel;
    protected $locationModel;
    protected $agentCommissionModel;
    protected $agentTotal;
    protected $companyModel;
    protected $permissionModel;
    protected $menuModel;
    protected $accountModel;
    protected $geideaWaveModel;
    
    public function __construct()
    {
        $this->accountModel = new AccountModel();
        $this->agentPayment = new PayagentModel();
        $this->geideaWaveModel = new ModelsGeideaWave();
        $this->agentModel = new AgentModel();
        $this->companyModel = new CompanyModel();
    }


    public function payViaGeidea()
    {
        // Load the payment page
        $currentUserId =  $this->session->get('user_id');
        $data['companies'] = $this->companyModel->where("FIND_IN_SET($currentUserId, user_id) >", 0)->where('status', 1)->findAll();
        echo view('Modules\Agent\Views\payagent\geidea_payment',$data);
        // return view('Modules\Agent\Views\payagent\geidea_payment');

    }

    public function processPayment()
    {
        $amount = $this->request->getVar('amount');



        // Geidea API credentials
        $geideaData = $this->geideaWaveModel->first();
        // if ($geideaData) {
        //     $geideaData = $geideaData->toArray();
        // }
        if($geideaData->environment == 0){
            $publicKey = $geideaData->test_public_key;
            $apiPassword = $geideaData->test_api_pass;
        }else{
            $publicKey = $geideaData->live_public_key;
            $apiPassword = $geideaData->live_api_pass;
        }
        // $publicKey = '90e3f9d8-a7b3-42d5-ad70-47e734ac1116';
        // $apiPassword = 'f68bfdf2-c246-4e5f-9d70-3105a4c0dba5';

        // API endpoint
        $url = 'https://api.merchant.geidea.net/payment-intent/api/v2/direct/session';
        $merchantReferenceId = "order".time();
        $timestamp = gmdate("Y-m-d\TH:i:s\Z");
        $signature = $this->generateGeideaSignature($publicKey, $amount, 'EGP', $merchantReferenceId, $apiPassword, $timestamp);

        // Prepare the payload
        $data = [
            'amount' => (float) $amount,
            'currency' => 'EGP',
            'merchantReferenceId' => $merchantReferenceId,
            'timestamp' => $timestamp,
            'signature' => $signature,
            'callbackUrl' => base_url('payment/callback'),
        ];
        // print_r($data);exit;
        // Send the request to Geidea API
        $client = \Config\Services::curlrequest();
        $response = $client->post($url, [
            'auth' => [$publicKey, $apiPassword],
            'json' => $data,
        ]);
        if ($response->getStatusCode() === 200) {
            $responseData = json_decode($response->getBody(), true);

            if (isset($responseData['session']['id'])) {
                return $this->response->setJSON([
                    'sessionId' => $responseData['session']['id'],
                    'merchantReferenceId' => $merchantReferenceId,
                    'csrfTokenName' => csrf_token(),
                    'csrfToken' => csrf_hash(),
                ]);

            } else {
                return $this->response->setJSON(['error' => 'Session ID missing in response.']);
            }
        } else {
            return $this->response->setJSON(['error' => 'Failed to create session.']);
        }
    }

    public function paymentsucess()
    {
        $json = $this->request->getJSON(true);
        if (!is_array($json)) {
            $json = [];
        }
        $amount = $json['amount'] ?? $this->request->getVar('amount');
        $company_id = $json['companyId'] ?? $json['company_id'] ?? $this->request->getVar('companyId');
        $paymentRef = isset($json['paymentReference']) ? trim((string) $json['paymentReference']) : '';
        $paymentRef = $paymentRef !== '' ? $paymentRef : trim((string) $this->request->getVar('paymentReference'));
        if ($paymentRef === '' && isset($json['orderId'])) {
            $paymentRef = trim((string) $json['orderId']);
        }
        if ($paymentRef === '' && isset($json['order']['orderId'])) {
            $paymentRef = trim((string) $json['order']['orderId']);
        }
        // Geidea session / payment reference (UUID) in transaction_id; merchant order ref in merchant_reference_id
        $transactionID = $paymentRef;

        $merchantReferenceId = $this->resolveMerchantReferenceId($json);

        $currentUserId =  $this->session->get('user_id');
        $agentDetail =  $this->agentModel->where('user_id',$currentUserId)->first();
        $agentid = $agentDetail->id;

        $agentPaymentData= array(
            "agent_id"=> $agentid,
            "company_id" => $company_id,
            "amount"=> $amount,
            "transaction_id"=> $transactionID,
            "merchant_reference_id" => $merchantReferenceId !== '' ? $merchantReferenceId : null,
            "status"=> 0,
            "payment_mode" => 1
        );

        $this->agentPayment->insert($agentPaymentData);
        $lastInsertId = $this->agentPayment->insertID();

        $payagentController = new \Modules\Account\Controllers\Payagent();
        $payagentController->status($lastInsertId, 1, $amount, $agentid);

        return $this->response->setJSON(['success' => 'Payment Sucessfully added to wallet.']);

    }

    public function createSession()
    {
        $merchantPublicKey = '90e3f9d8-a7b3-42d5-ad70-47e734ac1116';
        $apiPassword = 'f68bfdf2-c246-4e5f-9d70-3105a4c0dba5';

        $url = "https://api.merchant.geidea.net/payment-intent/api/v2/direct/session";

        $data = $this->request->getJSON(true);

        $orderAmount = $data["amount"];
        $orderCurrency = $data["currency"];
        $callbackUrl = $data["callbackUrl"];
        $orderMerchantReferenceId = $data["merchantReferenceId"];
        $language = $data["language"];
        $timestamp = date("Y/m/d H:i:s");

        $signature = $this->generateSignature(
            $merchantPublicKey,
            $orderAmount,
            $orderCurrency,
            $orderMerchantReferenceId,
            $apiPassword,
            $timestamp
        );

        $payload = [
            "amount" => $orderAmount,
            "currency" => $orderCurrency,
            "merchantReferenceId" => $orderMerchantReferenceId,
            "timestamp" => $timestamp,
            "signature" => $signature
        ];

        $client = \Config\Services::curlrequest();
        $response = $client->post($url, [
            'headers' => [
                'Content-Type' => 'application/json',
                'Authorization' => 'Basic ' . base64_encode("$merchantPublicKey:$apiPassword"),
            ],
            'json' => $payload,
        ]);

        $body = $response->getBody();
        $result = json_decode($body, true);

        if ($result['responseCode'] === '000' && $result['detailedResponseCode'] === '000') {
            return $this->response->setBody($result['session']['id']);
        } else {
            return $this->fail($result['detailedResponseMessage']);
        }
    }

    private function generateSignature($merchantPublicKey, $amount, $currency, $referenceId, $apiPassword, $timestamp)
    {
        $amountStr = number_format($amount, 2, '.', '');
        $data = "{$merchantPublicKey}{$amountStr}{$currency}{$referenceId}{$timestamp}";
        $hash = hash_hmac('sha256', $data, $apiPassword, true);
        return base64_encode($hash);
    }
    /**
     * Geidea merchantReferenceId (e.g. order1734567890) from web/iOS success callback.
     */
    private function resolveMerchantReferenceId(array $json): string
    {
        $candidates = [
            $json['merchantReferenceId'] ?? null,
            $json['merchant_reference_id'] ?? null,
            $json['merchant_id'] ?? null,
            $json['order']['merchantReferenceId'] ?? null,
        ];

        foreach ($candidates as $candidate) {
            $value = trim((string) ($candidate ?? ''));
            if ($value !== '') {
                return $value;
            }
        }

        foreach (['merchantReferenceId', 'merchant_reference_id', 'merchant_id'] as $key) {
            $value = trim((string) ($this->request->getVar($key) ?? ''));
            if ($value !== '') {
                return $value;
            }
        }

        return '';
    }

    private function generateGeideaSignature($merchantPublicKey, $orderAmount, $orderCurrency, $orderMerchantReferenceId, $apiPassword, $timestamp) {
        // Ensure the amount is properly formatted
        $amountStr = number_format($orderAmount, 2, '.', '');

        // Build the string to hash
        $data = "{$merchantPublicKey}{$amountStr}{$orderCurrency}{$orderMerchantReferenceId}{$timestamp}";

        // Generate the HMAC SHA256 hash
        $hash = hash_hmac('sha256', $data, $apiPassword, true);

        // Return the signature as a base64 encoded string
        return base64_encode($hash);
    }
}
