<?php

/**
 * Bismillahir Rahmanir Raheem
 * 
 * PHP Mikrotik Billing (https://github.com/paybilling/phpnuxbill/)
 *
 * PipraPay Payment Gateway for Advanced Hotspot System | PHPNuxBill Plugin
 *
 **/

register_menu("Hotspot PipraPay Gateway", true, "hotspot_pg_piprapay_config", 'SETTINGS', '', '', "");
register_payment_gateway('Hotspot Allpay', 'hotspot_processPayment_allpay');

// ==================== ROUTE REGISTRATION ====================
$routes['hotspot_pg_piprapay_verify']  = 'hotspot_pg_piprapay_verify';
$routes['hotspot_pg_piprapay_webhook'] = 'hotspot_pg_piprapay_webhook';
// ============================================================

function hotspot_pg_piprapay_config()
{
    global $ui, $admin, $config;
    $ui->assign('_title', Lang::T("Hotspot Payment Gateway [PipraPay]"));
    $ui->assign('_system_menu', 'settings');
    $admin = Admin::_info();
    $ui->assign('_admin', $admin);

    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_piprapay_api_key        = _post('hotspot_pg_piprapay_api_key');
    $hotspot_pg_piprapay_base_url       = _post('hotspot_pg_piprapay_base_url');
    $hotspot_pg_piprapay_request_method = _post('hotspot_pg_piprapay_request_method');
    $hotspot_pg_piprapay_currency       = _post('hotspot_pg_piprapay_currency');

    if (_post('save') == 'save') {
        $settings = [
            'hotspot_pg_piprapay_api_key'        => $hotspot_pg_piprapay_api_key,
            'hotspot_pg_piprapay_base_url'       => $hotspot_pg_piprapay_base_url,
            'hotspot_pg_piprapay_request_method' => $hotspot_pg_piprapay_request_method,
            'hotspot_pg_piprapay_currency'       => $hotspot_pg_piprapay_currency,
        ];

        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('PipraPay Hotspot Settings Saved Successfully'), $admin['user_type']);
        r2(U . 'plugin/hotspot_pg_piprapay_config', 's', Lang::T('Settings Saved Successfully'));
    }

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

// ==================== HELPER FUNCTIONS ====================

function hotspot_pg_piprapay_get_base_url()
{
    global $config;
    $baseUrl = trim($config['hotspot_pg_piprapay_base_url'] ?? '');
    if ($baseUrl === '') {
        $baseUrl = 'https://sandbox.piprapay.com';
    }
    return rtrim($baseUrl, '/');
}

function hotspot_pg_piprapay_get_headers()
{
    global $config;
    return [
        'accept: application/json',
        'content-type: application/json',
        'mh-piprapay-api-key: ' . $config['hotspot_pg_piprapay_api_key']
    ];
}

function hotspot_pg_piprapay_verify_payment($ppId)
{
    $response = Http::postJsonData(
        hotspot_pg_piprapay_get_base_url() . '/api/verify-payments',
        ['pp_id' => (string)$ppId],
        hotspot_pg_piprapay_get_headers()
    );
    $result = json_decode($response, true);

    if (!is_array($result)) {
        Message::sendTelegram("PipraPay verification failed for: $ppId\n\nResponse: $response");
        return null;
    }

    return $result;
}

/**
 * Customer create অথবা update
 */
function hotspot_pg_piprapay_upsert_customer($phone, $voucherCode, $config)
{
    // Upsert by MAC (username) — prevents duplicate on reconnect
    $username   = $config['hotspot_voucher_mode'] ? $voucherCode : $phone;
    $serverHost = $_SERVER['HTTP_HOST'] ?? 'localhost';
    $email      = ($serverHost === 'localhost') ? "$phone@$serverHost.com" : "$phone@$serverHost";

    $c = ORM::for_table('tbl_customers')->where('username', $username)->find_one();
    if (!$c) {
        $c = ORM::for_table('tbl_customers')->create();
        $c->username      = $username;
        $c->password      = $username;
        $c->pppoe_password = '0';
        $c->address       = '';
        $c->created_by    = '1';
        $c->service_type  = 'Hotspot';
        _log("New customer created for PipraPay: $phone");
    } else {
        _log("Existing customer updated for PipraPay: $phone");
    }
    // Always update phone, fullname, email
    $c->phonenumber = Lang::phoneFormat($phone);
    $c->fullname    = "Hotspot $phone";
    $c->email       = $email;
    $c->save();

    return $c;
}

/**
 * Payment activate — customer create + package recharge + trx update
 */
function hotspot_pg_piprapay_activate($trx, $ppId, $paymentMethod = 'PipraPay')
{
    global $config;

    $phone      = $trx->phone_number;
    $routername = $trx->router_name;
    $planid     = $trx->plan_id;
    $voucherCode = $trx->mac_address;

    $c         = hotspot_pg_piprapay_upsert_customer($phone, $voucherCode, $config);
    $loginCode = $config['hotspot_voucher_mode'] ? $voucherCode : $phone;

    if (!Package::rechargeUser($c->id, $routername, $planid, $paymentMethod, 'Hotspot Payment')) {
        _log("PipraPay: Failed to activate package - PP_ID: $ppId");
        return false;
    }

    $expiration = ORM::for_table('tbl_user_recharges')
        ->where('plan_id', $planid)
        ->where('username', $c->username)
        ->where('status', 'on')
        ->order_by_desc('id')
        ->find_one();

    $trx->voucher_code       = $loginCode;
    $trx->payment_method     = $paymentMethod;
    $trx->payment_date       = date('Y-m-d H:i:s');
    $trx->transaction_status = 'paid';
    $trx->expired_date       = $expiration
        ? date('Y-m-d H:i:s', strtotime($expiration->expiration . " " . date("h:i A", strtotime($expiration->time))))
        : date('Y-m-d H:i:s', strtotime('+1 day'));
    $trx->save();

    if ($expiration && function_exists('hotspot_sendMessage')) {
        hotspot_sendMessage($phone, $expiration->namebp, $voucherCode, $expiration->expiration);
    }

    // MikroTik host session kill — device auto login হয়ে যাবে
    if (!empty($voucherCode) && !empty($routername)) {
        try {
            $mikrotik = ORM::for_table('tbl_routers')
                ->where('name', $routername)
                ->find_one();

            if ($mikrotik) {
                $iport  = explode(":", $mikrotik['ip_address']);
                $port   = isset($iport[1]) ? (int)$iport[1] : 8728;
                $client = new \PEAR2\Net\RouterOS\Client($iport[0], $mikrotik['username'], $mikrotik['password'], $port);

                $request = new \PEAR2\Net\RouterOS\Request('/ip/hotspot/host/print');
                $request->setQuery(\PEAR2\Net\RouterOS\Query::where('mac-address', strtoupper($voucherCode)));
                $responses = $client->sendSync($request);

                foreach ($responses as $response) {
                    if ($response->getType() === \PEAR2\Net\RouterOS\Response::TYPE_DATA) {
                        $hostId = $response->getProperty('.id');
                        $remove = new \PEAR2\Net\RouterOS\Request('/ip/hotspot/host/remove');
                        $remove->setArgument('numbers', $hostId);
                        $client->sendSync($remove);
                        break;
                    }
                }
            }
        } catch (Exception $e) {
            // Silent fail
        }
    }

    _log("PipraPay Payment Activated - PP_ID: $ppId, Phone: $phone, Method: $paymentMethod");
    return true;
}

// ==================== PAYMENT CREATE ====================

function hotspot_processPayment_allpay($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'];
    $amount         = $data['amount'];
    $email          = $data['email'];
    $paymentGateway = $data['payment_gateway'];

    if (
        empty($config['hotspot_pg_piprapay_api_key']) ||
        empty($config['hotspot_pg_piprapay_base_url'])
    ) {
        Message::sendTelegram("PipraPay Hotspot Payment Failed: Payment gateway not configured.");
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(
            Lang::T("PipraPay payment gateway not configured. Please report to ") . ' ' . $config['CompanyName']
        ));
        exit();
    }

    $metadata = [
        'invoiceid'   => (string)$txref,
        'username'    => $phone,
        'plan_name'   => $plan_name,
        'mac_address' => $mac_address,
        'router'      => $routername
    ];

    $payload = [
        'full_name'    => "Hotspot $phone",
        'email_mobile' => !empty($email) ? $email : $phone,
        'amount'       => (string)$amount,
        'metadata'     => $metadata,
        'redirect_url' => U . 'plugin/hotspot_pg_piprapay_verify',
        'return_type'  => $config['hotspot_pg_piprapay_request_method'] ?? 'GET',
        'cancel_url'   => U . 'plugin/hotspot_verify',
        'webhook_url'  => U . 'plugin/hotspot_pg_piprapay_webhook',
        'currency'     => !empty($config['hotspot_pg_piprapay_currency'])
                            ? $config['hotspot_pg_piprapay_currency']
                            : 'BDT'
    ];

    $response = Http::postJsonData(
        hotspot_pg_piprapay_get_base_url() . '/api/create-charge',
        $payload,
        hotspot_pg_piprapay_get_headers()
    );
    $result = json_decode($response, true);

    if (!is_array($result) || empty($result['status']) || !$result['status'] || empty($result['pp_id']) || empty($result['pp_url'])) {
        Message::sendTelegram("PipraPay Hotspot Payment Failed\n\n" . $response);
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Failed to create transaction. Please try again later.")));
        exit();
    }

    // Transaction save — pp_id এখনই save হয়
    $trx = ORM::for_table('tbl_hotspot_payments')->create();
    $trx->transaction_id     = $result['pp_id'];
    $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 = 'pending';
    $trx->payment_gateway    = $paymentGateway;
    $trx->gateway_response   = json_encode(['request' => $payload, 'response' => $result]);

    try {
        $trx->save();
        header('Location: ' . $result['pp_url']);
        exit();
    } catch (Exception $e) {
        _log("PipraPay: Failed to save transaction: " . $e->getMessage());
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Failed to save transaction. Please try again later.")));
        exit();
    }
}

// ==================== VERIFY (Redirect থেকে) ====================

function hotspot_pg_piprapay_verify()
{
    global $config;

    _log("PipraPay Verify - GET: " . json_encode($_GET));
    _log("PipraPay Verify - POST: " . json_encode($_POST));

    $ppId = $_POST['pp_id'] ?? $_GET['pp_id'] ?? '';

    if (empty($ppId)) {
        _log("PipraPay Verify: No payment ID supplied");
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("No payment reference supplied")));
        exit();
    }

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

    if (!$trx) {
        _log("PipraPay Verify: Transaction not found - PP_ID: $ppId");
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Transaction not found")));
        exit();
    }

    // Webhook আগেই process করে থাকলে redirect করো
    if ($trx->transaction_status === 'paid') {
        _log("PipraPay Verify: Already paid by webhook - PP_ID: $ppId");
        header('Location: ' . U . "plugin/hotspot_verify&reference={$trx->transaction_ref}&success=1&voucher={$trx->voucher_code}");
        exit();
    }

    if (in_array($trx->transaction_status, ['failed', 'cancelled'])) {
        header('Location: ' . U . "plugin/hotspot_verify&reference={$trx->transaction_ref}&failed=1");
        exit();
    }

    // API দিয়ে verify
    $verify = hotspot_pg_piprapay_verify_payment($ppId);

    if (!$verify) {
        header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Unable to verify payment")));
        exit();
    }

    $payment = isset($verify['data']) ? $verify['data'] : $verify;
    $status  = strtolower((string)($payment['status'] ?? ''));

    if ($status === 'completed') {

        $paymentMethod = 'PipraPay - ' . ($payment['payment_method'] ?? 'Hotspot');
        $trx->gateway_response = json_encode(['verify' => $verify]);

        if (!hotspot_pg_piprapay_activate($trx, $ppId, $paymentMethod)) {
            header('Location: ' . U . "plugin/hotspot_verify&message=" . urlencode(Lang::T("Failed to activate package")));
            exit();
        }

        header('Location: ' . U . "plugin/hotspot_verify&reference={$trx->transaction_ref}&success=1&voucher={$trx->voucher_code}");

    } else {

        $trx->payment_method     = 'PipraPay - Hotspot';
        $trx->payment_date       = date('Y-m-d H:i:s');
        $trx->transaction_status = in_array($status, ['pending', 'processing']) ? 'pending' : 'failed';
        $trx->gateway_response   = json_encode(['verify' => $verify]);
        $trx->save();

        _log("PipraPay Verify: Status $status - PP_ID: $ppId");
        header('Location: ' . U . "plugin/hotspot_verify&reference={$trx->transaction_ref}&message=" . urlencode(Lang::T("Payment status: ") . ucfirst($status)));
    }
}

// ==================== WEBHOOK (User page বন্ধ করলেও চলবে) ====================

function hotspot_pg_piprapay_webhook()
{
    global $config;

    header('Content-Type: application/json');

    // API Key validate
    $headers          = getallheaders();
    $received_api_key = $headers['mh-piprapay-api-key']
        ?? $headers['Mh-Piprapay-Api-Key']
        ?? $_SERVER['HTTP_MH_PIPRAPAY_API_KEY']
        ?? '';

    if ($received_api_key !== $config['hotspot_pg_piprapay_api_key']) {
        http_response_code(401);
        echo json_encode(['status' => false, 'message' => 'Unauthorized request.']);
        exit;
    }

    // Payload পড়া
    $raw  = file_get_contents('php://input');
    $data = json_decode($raw, true);

    if (!$data) {
        http_response_code(200);
        echo json_encode(['status' => 'error', 'message' => 'Invalid payload']);
        exit;
    }

    _log("PipraPay Webhook received: " . $raw);

    $ppId   = $data['pp_id']  ?? '';
    $status = strtolower($data['status'] ?? '');

    if (empty($ppId)) {
        http_response_code(200);
        echo json_encode(['status' => 'ok']);
        exit;
    }

    // Transaction খোঁজা
    $trx = ORM::for_table('tbl_hotspot_payments')
        ->where('transaction_id', $ppId)
        ->find_one();

    // Fallback: metadata invoiceid দিয়ে
    if (!$trx && !empty($data['metadata']['invoiceid'])) {
        $trx = ORM::for_table('tbl_hotspot_payments')
            ->where('transaction_ref', $data['metadata']['invoiceid'])
            ->find_one();
    }

    if (!$trx) {
        _log("PipraPay Webhook: Transaction not found - PP_ID: $ppId");
        http_response_code(200);
        echo json_encode(['status' => 'ok']);
        exit;
    }

    // Already processed
    if (in_array($trx->transaction_status, ['paid', 'failed', 'cancelled'])) {
        _log("PipraPay Webhook: Already processed - PP_ID: $ppId");
        http_response_code(200);
        echo json_encode(['status' => 'ok']);
        exit;
    }

    if ($status === 'completed') {

        $paymentMethod         = 'PipraPay - ' . ($data['payment_method'] ?? 'Hotspot');
        $trx->gateway_response = json_encode($data);
        $trx->transaction_id   = $ppId; // নিশ্চিত করা

        hotspot_pg_piprapay_activate($trx, $ppId, $paymentMethod);

    } else {

        $trx->payment_date       = date('Y-m-d H:i:s');
        $trx->transaction_status = in_array($status, ['pending', 'processing']) ? 'pending' : 'failed';
        $trx->gateway_response   = json_encode($data);
        $trx->save();

        _log("PipraPay Webhook: Status $status - PP_ID: $ppId");
    }

    http_response_code(200);
    echo json_encode(['status' => 'ok']);
    exit;
}
