<?php
/**
 * order_lib.php
 * The actual order-creation logic, extracted out of payment/create_order.php
 * so it can be called two ways:
 *   1. Over HTTP, via /api/create-order (payment/create_order.php - used by
 *      external merchant sites, the JS SDK, etc.)
 *   2. Directly, in-process, via create_neopay_order() (used by anything
 *      that lives on this same server - Payment Link, Static Paylink,
 *      Wallet top-up, subscription purchase) - this is what makes those
 *      features immune to the "does this domain's rewrite rules even
 *      work" class of bug: there's no self-HTTP-call and therefore no
 *      domain to get wrong in the first place.
 *
 * Returns ['http_code' => int, 'body' => array] - same shape either way,
 * so callers can treat it identically to decoding the HTTP JSON response.
 */

function isInteger($value) {
    return filter_var($value, FILTER_VALIDATE_INT) !== false;
}

function isCustomerNumberValid($value) {
    return isInteger($value) && strlen($value) <= 10;
}

function GenRandomString($length = 10) {
    $characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $charactersLength = strlen($characters);
    $randomString = "";
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

function generateUniqueToken() {
    $token = time() . bin2hex(random_bytes(16)) . rand(1, 50);
    return hash("sha256", $token);
}

/**
 * $input keys expected: customer_mobile, user_token, amount, order_id,
 * redirect_url, remark1, remark2, route (optional), origin_domain (optional -
 * which public domain the resulting payment_url should use; falls back to
 * the merchant's white-label domain, then to whatever domain THIS call
 * happens to be running on).
 */
function create_neopay_order($conn, array $input) {
    $customer_mobile = $input['customer_mobile'] ?? '';
    $user_token      = $input['user_token'] ?? '';
    $amount          = $input['amount'] ?? '';
    $order_id        = $input['order_id'] ?? '';
    $redirect_url    = $input['redirect_url'] ?? '';
    $remark1         = $input['remark1'] ?? '';
    $remark2         = $input['remark2'] ?? '';
    $origin_domain   = trim($input['origin_domain'] ?? '');

    $byteorderid = "BYTE" . rand(1111, 9999) . time();

    $user_token_esc = $conn->real_escape_string($user_token);
    $slq_pbbyt = "SELECT * FROM users where user_token='$user_token_esc'";
    $res_pslq_pbbyt = getXbyY($slq_pbbyt);

    if (empty($res_pslq_pbbyt)) {
        return ['http_code' => 400, 'body' => ["status" => false, "message" => "Invalid user token"]];
    }

    $user = $res_pslq_pbbyt[0];
    $bydb_unq_user_id = $user["id"];

    if (($user["acc_ban"] ?? 'No') === 'Yes' || ($user["acc_lock"] ?? 'No') === 'Yes') {
        return ['http_code' => 403, 'body' => ["status" => false, "message" => "Account is banned or locked"]];
    }

    $order_id_esc = $conn->real_escape_string($order_id);
    $check_order_id_query = "SELECT * FROM orders WHERE order_id='$order_id_esc' AND user_token='$user_token_esc'";
    $existing_order_result = getXbyY($check_order_id_query);
    if (!empty($existing_order_result)) {
        return ['http_code' => 400, 'body' => ["status" => false, "message" => "Order ID already exists for this user"]];
    }

    // Skip the platform account's own transaction quota for the platform's
    // own "buy a plan" orders (remark1=test1/remark2=test2) and wallet
    // top-up orders (remark1=WALLET_TOPUP) - both are a merchant paying
    // the platform, not a real merchant order.
    $isPlanPurchaseOrder = ($remark1 === 'test1' && $remark2 === 'test2');
    $isWalletTopupOrder = ($remark1 === 'WALLET_TOPUP');

    if (!$isPlanPurchaseOrder && !$isWalletTopupOrder) {
        $quota = checkTransactionQuota($conn, $bydb_unq_user_id);
        if (!$quota['allowed']) {
            return ['http_code' => 403, 'body' => ["status" => false, "message" => $quota['message']]];
        }
    }

    $today = date("Y-m-d");
    if (!empty($user["expiry"]) && $user["expiry"] < $today) {
        return ['http_code' => 400, 'body' => ["status" => false, "message" => "Your Plan Expired Please Renew"]];
    }

    $merchantDefs = [
        'hdfc'       => ['folder' => 'payment',  'method' => 'HDFC'],
        'phonepe'    => ['folder' => 'payment2', 'method' => 'PhonePe'],
        'paytm'      => ['folder' => 'payment3', 'method' => 'Paytm'],
        'bharatpe'   => ['folder' => 'payment4', 'method' => 'Bharatpe'],
        'googlepay'  => ['folder' => 'payment5', 'method' => 'Googlepay'],
        'freecharge' => ['folder' => 'payment6', 'method' => 'FreeCharge'],
        'sbi'        => ['folder' => 'payment7', 'method' => 'SBI'],
        'mobikwik'   => ['folder' => 'payment8', 'method' => 'MOBIKWIK'],
        'fampay'     => ['folder' => 'payment9', 'method' => 'FamPay'],
    ];

    $connectedMap = buildConnectedMapFromUserRow($user);
    $mode = $user['merchant_mode'] ?? 'all';
    $activeType = $user['active_merchant_type'] ?? null;
    $chosenType = pickMerchantType($connectedMap, $mode, $activeType);

    if ($chosenType === null || !isset($merchantDefs[$chosenType])) {
        return ['http_code' => 400, 'body' => ["status" => false, "message" => "Merchant Not Linked"]];
    }

    $def = $merchantDefs[$chosenType];

    $link_token = generateUniqueToken();
    $cxrtoday = date("Y-m-d H:i:s");
    $link_token_esc = $conn->real_escape_string($link_token);
    $sql_insert_link = "INSERT INTO payment_links (link_token, order_id, created_at) VALUES ('$link_token_esc', '$order_id_esc', '$cxrtoday')";
    setXbyY($sql_insert_link);

    $linkDomain = get_merchant_domain($conn, $bydb_unq_user_id, $origin_domain !== '' ? $origin_domain : null);
    $payment_link = "https://" . $linkDomain . "/" . $def['folder'] . "/instant-pay/" . $link_token;
    $gateway_txn = uniqid();
    $currentTimestamp = date("Y-m-d H:i:s");

    $isTestOrder = (($user['api_mode'] ?? 'live') === 'test') ? 1 : 0;

    $amount_esc = $conn->real_escape_string($amount);
    $customer_mobile_esc = $conn->real_escape_string($customer_mobile);
    $redirect_url_esc = $conn->real_escape_string($redirect_url);
    $remark1_esc = $conn->real_escape_string($remark1);
    $remark2_esc = $conn->real_escape_string($remark2);

    if ($chosenType === 'paytm' || $chosenType === 'freecharge' || $chosenType === 'sbi' || $chosenType === 'mobikwik' || $chosenType === 'fampay') {
        $bytetxn_ref_id = ($chosenType === 'paytm')
            ? GenRandomString() . time()
            : "ATC" . substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 0, 5) . time();

        $sql = "INSERT INTO orders (paytm_txn_ref, gateway_txn, amount, order_id, status, is_test, user_token, utr, customer_mobile, redirect_url, Method, byteTransactionId, create_date, remark1, remark2, user_id)
            VALUES ('$bytetxn_ref_id', '$gateway_txn', '$amount_esc', '$order_id_esc', 'PENDING', $isTestOrder, '$user_token_esc', '', '$customer_mobile_esc', '$redirect_url_esc', '{$def['method']}', '$byteorderid', '$currentTimestamp', '$remark1_esc', '$remark2_esc', '$bydb_unq_user_id')";
    } elseif ($chosenType === 'hdfc') {
        $mTxnid = "";
        $sql = "INSERT INTO orders (gateway_txn, amount, order_id, status, is_test, user_token, utr, customer_mobile, redirect_url, method, upiLink, description, create_date, remark1, remark2, user_id, byteTransactionId, HDFC_TXNID)
            VALUES ('$gateway_txn', '$amount_esc', '$order_id_esc', 'PENDING', $isTestOrder, '$user_token_esc', '', '$customer_mobile_esc', '$redirect_url_esc', '{$def['method']}', '', '', '$currentTimestamp', '$remark1_esc', '$remark2_esc', '$bydb_unq_user_id', '$byteorderid', '$mTxnid')";
    } else {
        $sql = "INSERT INTO orders (gateway_txn, amount, order_id, status, is_test, user_token, utr, customer_mobile, redirect_url, Method, byteTransactionId, create_date, remark1, remark2, user_id)
            VALUES ('$gateway_txn', '$amount_esc', '$order_id_esc', 'PENDING', $isTestOrder, '$user_token_esc', '', '$customer_mobile_esc', '$redirect_url_esc', '{$def['method']}', '$byteorderid', '$currentTimestamp', '$remark1_esc', '$remark2_esc', '$bydb_unq_user_id')";
    }

    setXbyY($sql);

    $upiString = null;
    if ($chosenType === 'fampay') {
        $fpRes = getXbyY("SELECT upi_id FROM fampay_tokens WHERE user_token='$user_token_esc'");
        if (!empty($fpRes[0]['upi_id'])) {
            $upiTxnRef = "TXN" . rand(111, 999) . time() . rand(1, 100);
            $upiString = "upi://pay?pa=" . urlencode($fpRes[0]['upi_id']) . "&am=" . urlencode($amount) . "&pn=" . urlencode($user['name'] ?? 'Merchant') . "&tn=" . urlencode($upiTxnRef) . "&tr=" . urlencode($byteorderid);
        }
    }

    return [
        'http_code' => 201,
        'body' => [
            "status" => true,
            "message" => "Order Created Successfully",
            "result" => [
                "orderId" => $order_id,
                "payment_url" => $payment_link,
                "upi_string" => $upiString,
            ],
        ],
    ];
}
