<?php

/**
 * Bismillahir Rahmanir Raheem
 * 
 * PHP Mikrotik Billing (https://github.com/paybilling/phpnuxbill/)
 *
 * Bksh Payment Gateway for Advanced Hotspot System | PHPNuxBill Plugin
 *
 * @author: Focuslinks Digital Solutions <focuslinkstech@gmail.com>
 * Website: https://focuslinkstech.com.ng/
 * GitHub: https://github.com/Focuslinkstech/
 * Telegram: https://t.me/focuslinkstech/
 *
 **/

register_menu("Hotspot Bkash Gateway", true, "hotspot_pg_bkash_config", 'SETTINGS', '', '', "");
function hotspot_pg_bkash_config()
{
    global $ui, $admin, $config;
    $ui->assign('_title', Lang::T("Hotspot Payment Gateway [BKash]"));
    $ui->assign('_system_menu', 'settings');
    $admin = Admin::_info();
    $ui->assign('_admin', $admin);

    // Check user type for access
    if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
        _alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
        exit;
    }

    $hotspot_pg_bkash_app_key = _post('hotspot_pg_bkash_app_key');
    $hotspot_pg_bkash_app_secret = _post('hotspot_pg_bkash_app_secret');
    $hotspot_pg_bkash_username = _post('hotspot_pg_bkash_username');
    $hotspot_pg_bkash_password = _post('hotspot_pg_bkash_password');
    $hotspot_pg_bkash_env = _post('hotspot_pg_bkash_env');

    if (_post('save') == 'save') {
        $settings = [
            'hotspot_pg_bkash_app_key' => $hotspot_pg_bkash_app_key,
            'hotspot_pg_bkash_app_secret' => $hotspot_pg_bkash_app_secret,
            'hotspot_pg_bkash_username' => $hotspot_pg_bkash_username,
            'hotspot_pg_bkash_password' => $hotspot_pg_bkash_password,
            'hotspot_pg_bkash_env' => $hotspot_pg_bkash_env,

        ];

        // Update or insert settings in the database
        foreach ($settings as $key => $value) {
            $d = ORM::for_table('tbl_appconfig')->where('setting', $key)->find_one();
            if ($d) {
                $d->value = $value;
                $d->save();
            } else {
                $d = ORM::for_table('tbl_appconfig')->create();
                $d->setting = $key;
                $d->value = $value;
                $d->save();
            }
        }

        _log('[' . $admin['username'] . ']: ' . Lang::T('Settings Saved Successfully'), $admin['user_type']);
        r2(U . 'plugin/hotspot_pg_bkash_config', 's', Lang::T('Settings Saved Successfully'));
    }

    $ui->assign('_c', $config);
    $ui->assign('companyName', $config['CompanyName']);
    $ui->display('hotspot_pg_bkash_config.tpl');
}

function hotspot_processPayment_bkash($data)
{
    global $config;
    $phone = $data['phone'];
    $mac_address = $data['mac_address'];
    $ip_address = $data['ip_address'];
    $routername = $data['routername'];
    $txref = $data['txref'];
    $planid = $data['planid'];
    $plan_name = $data['plan_name'];
    $status = $data['status'];
    $amount = $data['amount'];
    $email = $data['email'];
    $paymentGateway = $data['payment_gateway'];

    if (
        empty($config['hotspot_pg_bkash_app_key']) ||
        empty($config['hotspot_pg_bkash_app_secret']) ||
        empty($config['hotspot_pg_bkash_username']) ||
        empty($config['hotspot_pg_bkash_password'])
    ) {

        $message = urlencode(Lang::T("Payment gateway not configured. Please report to "). ' ' . $config['CompanyName']);
        Message::sendTelegram("bKash Hotspot Payment Failed: Payment gateway not configured. Please setup BKASH hotspot system gateway ");
        header('Location: ' . U . "plugin/hotspot_verify&message=" . $message);
        exit();
    }
    
    $json = [
        'intent' => 'sale',
        'mode' => '0011',
        'payerReference' =>  $txref,
        'currency' => 'BDT',
        'amount' => $amount,
        'callbackURL' => U . 'plugin/hotspot_pg_bkash_verify',
        'merchantInvoiceNumber' => $plan_name,
    ];
    $headers = [
        'Authorization: ' . hotspot_pg_bkash_get_token(),
        'X-App-Key: ' . $config['hotspot_pg_bkash_app_key']
    ];

    $response = Http::postJsonData(hotspot_pg_bkash_get_server() . 'checkout/create', $json, $headers);

    if ($response === false) {
        Message::sendTelegram("bKash Hotspot Payment Request Failed: Unable to connect.");
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Failed to create transaction. Please try again later.")));
        exit();
    }

    $result = json_decode($response, true);

    if (!is_array($result) || !isset($result['statusMessage']) || $result['statusMessage'] != 'Successful') {
        Message::sendTelegram("bKash Hotspot Payment Failed\n\n" . json_encode($result, JSON_PRETTY_PRINT));
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Failed to create transaction. Please try again later.")));
        exit();
    }

    $failedMessage = Lang::T("Failed to save transaction. Please try again later.");
    $trx = ORM::for_table('tbl_hotspot_payments')->create();
    $trx->transaction_id = $result['paymentID'];
    $trx->transaction_ref = $txref;
    $trx->amount = $amount;
    $trx->phone_number = $phone;
    $trx->plan_id = $planid;
    $trx->plan_name = $plan_name;
    $trx->mac_address = $mac_address;
    $trx->ip_address = $ip_address;
    $trx->router_name = $routername;
    $trx->voucher_code = '**********';
    $trx->transaction_status = $status;
    $trx->payment_gateway = $paymentGateway;

    try {
        $trx->save();
        header('Location: ' . $result['bkashURL']);
    } catch (Exception $e) {
        _log(Lang::T("Failed to save transaction: ") . $e->getMessage());
        hotspot_throwError($failedMessage);
        exit;
    }
}

function hotspot_pg_bkash_verify()
{
    global $config;

    if (isset($_GET['paymentID'])) {
        $reference = $_GET['paymentID'] ?? '';

        if (!$reference) {
            _log(Lang::T("Bkash Payment verification: No reference supplied"));
            header('Location: ' . U . "plugin/hotspot_verify&message=" . Lang::T("Bkash Payment verification: No reference supplied"));
            die();
        }

        $trx = ORM::for_table('tbl_hotspot_payments')
            ->where('transaction_id', $reference)
            ->find_one();

        if (!$trx) {
            _log(Lang::T("Bkash Payment verification:  Transaction with this Reference ID: $reference Not Found"));
            header('Location: ' . U . "plugin/hotspot_verify&message=" . Lang::T("Transaction with this Reference ID: $reference Not Found"));
            die();
        }

        // Check if transaction has already been processed
        if (in_array($trx->transaction_status, ['paid', 'failed', 'cancelled'])) {
            _log(Lang::T("[Bkash Payment verification]  Transaction with this Reference ID: $reference has already been processed and its status is") . ' ' . $trx->transaction_status);
            header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Transaction with this Reference ID: $reference has already been processed and its status is") . ' ' . $trx->transaction_status));
            die();
        }

        $maxRetries = 3;
        $retryDelay = 5;
        $statusChecked = false;
        $server = hotspot_pg_bkash_get_server();
        $token = hotspot_pg_bkash_get_token();

        for ($i = 0; $i < $maxRetries; $i++) {
            Http::postJsonData("{$server}checkout/execute", ['paymentID' => $reference], ["Authorization: $token", 'X-App-Key: ' . $config['hotspot_pg_bkash_app_key']]);
            $result = json_decode(Http::postJsonData("{$server}checkout/payment/status", ['paymentID' => $reference], ["Authorization: $token", 'X-App-Key: ' . $config['hotspot_pg_bkash_app_key']]), true);

            if (isset($result['statusCode']) && $result['statusCode'] == '0000') {
                $statusChecked = true;
                break;
            }

            sleep($retryDelay);
        }

        if (!$statusChecked) {
            sendTelegram("Failed to check bKash transaction.\n\n" . json_encode($result, JSON_PRETTY_PRINT));
            header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Failed to verify transaction. Please try again later or contact Admin.")));
            exit;
        }

        // Transaction status and verification
        $status = $result['transactionStatus'] ?? '';
        $verificationStatus = $result['verificationStatus'] ?? '';
        $txid = $result['trxID'] ?? '';

        if ($status == 'Completed' && $verificationStatus == 'Complete') {
            $phone = $trx->phone_number;
            $routername = $trx->router_name;
            $planid = $trx->plan_id;

            $voucherCode = $trx->mac_address; // Use the MAC address stored in the transaction
            $serverHost = $_SERVER['HTTP_HOST'];
            $email = ($serverHost === 'localhost') ? "$phone@$serverHost.com" : "$phone@$serverHost";

            // 1. Customer খোঁজা
$c = ORM::for_table('tbl_customers')->where('phonenumber', $phone)->find_one();
$username = $config['hotspot_voucher_mode'] ? $voucherCode : $phone;
$password = $username;

// 2. Customer না থাকলে নতুন create, থাকলে update
if (!$c) {
    $c = ORM::for_table('tbl_customers')->create();
    $c->username = $username;
    $c->password = $password;
    $c->pppoe_password = '0';
    $c->email = $email;
    $c->fullname = "Hotspot $phone";
    $c->phonenumber = Lang::phoneFormat($phone);
    $c->service_type = 'Hotspot';
    $c->address = '';
    $c->created_by = '1';
    $c->save();
    _log("New customer created for BKash payment: $phone");
} else {
    // Existing customer - update username/password
    $c->username = $username;
    $c->password = $password;
    $c->save();
    _log("Existing customer updated for BKash payment: $phone, Username: $username");
}

// 3. Customer ID নেয়া
$customer_id = $c->id;

if (!Package::rechargeUser($customer_id, $routername, $planid, 'BKASH', 'Payment Channel')) {
                _log('[' . Lang::T("Failed to activate your Package.") . ']: Bkash Hotspot Payment - ' . json_encode($result));
                sendTelegram("Failed to activate the package for transaction ID $reference.");
                header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Failed to activate your Package, try again later. Contact Support")));
                exit;
            }

            $expiration = ORM::for_table('tbl_user_recharges')->where('plan_id', $planid)->where('username', $c['username'])->where('status', 'on')->find_one();
            $expired_date = $expiration->expiration;
            $expired_time = $expiration->time;
            $expired = $expired_date . " " . date("h:i A", strtotime($expired_time));
            $loginCode = $config['hotspot_voucher_mode'] ? $voucherCode : $phone;

            $trx->transaction_id = $txid;
            $trx->voucher_code = $loginCode;
            $trx->payment_method = 'BKASH - Payment Channel';
            $trx->payment_date = date('Y-m-d H:i:s');
            $trx->transaction_status = 'paid';
            $trx->gateway_response = json_encode($result);
            $trx->expired_date = date('Y-m-d H:i:s', strtotime($expired));
            $trx->save();

            // Send SMS/WhatsApp
            hotspot_sendMessage($phone, $expiration->namebp, $voucherCode, $expiration->expiration);
            _log('[' . Lang::T("Notification") . ']: Instant Hotspot Payment Success - ' . json_encode($result));
            header('Location: ' . U . "plugin/hotspot_verify&reference={$trx->transaction_ref}");
        } else {
            // Transaction failed
            $trx->payment_method = 'BKASH - Payment Channel';
            $trx->payment_date = date('Y-m-d H:i:s');
            $trx->transaction_status = 'failed';
            $trx->gateway_response = json_encode($result);
            $trx->save();
            _log('[' . Lang::T("Notification") . ']: Transaction failed - ' . json_encode($result));
            header('Location: ' . U . "plugin/hotspot_verify&reference={$trx->transaction_ref}");
        }
    }
}

function  hotspot_pg_bkash_get_server()
{
    global $config;

    $environment = $config['hotspot_pg_bkash_env'];

    // Select environment
    return match ($environment) {
        "live" => 'https://tokenized.pay.bka.sh/v1.2.0-beta/tokenized/',
        "sandbox" => 'https://tokenized.sandbox.bka.sh/v1.2.0-beta/tokenized/',
        default => json_encode(["Message" => "Invalid application status"]),
    };
}

function hotspot_pg_bkash_get_token()
{
    global $config;
    $json = [
        'app_key' => $config['hotspot_pg_bkash_app_key'],
        'app_secret' => $config['hotspot_pg_bkash_app_secret']
    ];
    $url = hotspot_pg_bkash_get_server() . 'checkout/token/grant';
    $headers = ['username: ' . $config['hotspot_pg_bkash_username'], 'password: ' . $config['hotspot_pg_bkash_password']];
    $result = json_decode(Http::postJsonData($url, $json, $headers), true);
    switch ($result['statusMessage']) {
        case 'Successful':
            return $result['id_token'];
        default:
            sendTelegram("bKash hotspot payment failed\n\n" . json_encode($result, JSON_PRETTY_PRINT));
            $errors[] = "Failed to create transaction." . " " . $result['errorMessage'];
            $response = [
                'ResultCode' => "202",
                'message' => $errors
            ];
            echo json_encode($response, JSON_PRETTY_PRINT);
            break;
    }
}

