<?php
/**
 * fampay_order_watcher.php
 * =========================
 * Runs independently of any customer's browser. Without this, the
 * webhook only ever fires while pay_now.php's JS is actively polling
 * (every 2 seconds) - if the customer closes the tab right after paying
 * (before that poll catches the success), the webhook would never fire
 * at all until they came back to the page.
 *
 * This scans all still-PENDING FamPay orders from the last little while
 * and runs the exact same match-check + webhook logic on its own -
 * completely independent of whether any browser is watching.
 *
 * SETUP: add this as a cron job. Shared cPanel hosting usually can't run
 * cron more often than once a minute, so that's the realistic floor for
 * "instant" here - still a huge improvement over "never, unless the
 * customer's tab happens to still be open":
 *   * * * * * php -q /home/USER/neopay.mgamer.online/crons/fampay_order_watcher.php
 *
 * Safe to run every minute - it only touches orders still PENDING.
 */

define('ROOT_DIR', realpath(dirname(__FILE__)) . '/../');
include ROOT_DIR . 'pages/dbFunctions.php';
include ROOT_DIR . 'auth/config.php';
include ROOT_DIR . 'pages/dbInfo.php';
include ROOT_DIR . 'auth/fampay_mail_check.php';
include ROOT_DIR . 'includes/google_oauth.php';
include ROOT_DIR . 'includes/fampay_gmail_api.php';
include ROOT_DIR . 'includes/fampay_order_resolver.php';
include_once ROOT_DIR . 'includes/cron_lib.php';

if (!cron_is_enabled($conn, 'fampay_order_watcher')) {
    exit("Disabled from Website Manage.\n");
}

// Don't bother re-checking orders that are ancient/abandoned - keeps this
// fast and keeps IMAP/API usage reasonable. 20 minutes covers the normal
// "customer paid but closed the tab" window with room to spare.
$cutoff = date('Y-m-d H:i:s', strtotime('-20 minutes'));

$sql = "SELECT * FROM orders WHERE status = 'PENDING' AND Method = 'FamPay' AND create_date >= ?";
$stmt = $conn->prepare($sql);
if (!$stmt) {
    exit("Query prepare failed - has sql/RUN_THIS_ALL_IN_ONE.sql been run?\n");
}
$stmt->bind_param("s", $cutoff);
$stmt->execute();
$result = $stmt->get_result();
$pendingOrders = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();

$checked = 0;
$resolved = 0;

// Cache FamPay credentials per user_token so a merchant with several
// pending orders at once doesn't trigger a separate DB lookup for each.
$famCache = [];

foreach ($pendingOrders as $order) {
    $checked++;

    $order_id      = $order['order_id'];
    $db_amount     = $order['amount'];
    $order_created = strtotime($order['create_date']);
    $user_token    = $order['user_token'];
    $cxrremark1    = $order['remark1'];

    if (!isset($famCache[$user_token])) {
        $fRes = getXbyY("SELECT * FROM fampay_tokens WHERE user_token='" . $conn->real_escape_string($user_token) . "'");
        $famCache[$user_token] = $fRes[0] ?? null;
    }
    $rowFam = $famCache[$user_token];

    if (!$rowFam || $rowFam['status'] !== 'Active') {
        continue;
    }

    $gmail = $rowFam['gmail'];
    $app_password = $rowFam['app_password'];

    if (!empty($rowFam['refresh_token'])) {
        $accessToken = google_oauth_get_valid_access_token($conn, $rowFam, $site_settings);
        $check = $accessToken
            ? fampay_check_payment_oauth($accessToken, $db_amount, $order_id, null, null, $order_created, $conn)
            : ['matched' => false, 'utr' => null, 'error' => 'Google access token could not be refreshed'];
    } else {
        $check = fampay_check_payment($gmail, $app_password, $db_amount, $order_id, null, null, $order_created, $conn);
    }

    if ($check['matched']) {
        $uRes = getXbyY("SELECT * FROM users WHERE user_token='" . $conn->real_escape_string($user_token) . "'");
        $rowUser = $uRes[0] ?? null;
        if (!$rowUser) continue;

        $ok = resolve_fampay_order_success(
            $conn, $order_id, $check['utr'], $db_amount, $user_token,
            $cxrremark1, $rowUser['id'], $rowUser['callback_url'], $gmail
        );
        if ($ok) $resolved++;
    } elseif (!empty($check['error'])) {
        error_log('fampay_order_watcher: verify error for order ' . $order_id . ': ' . $check['error']);
    }
}

echo "Checked: {$checked}, Resolved: {$resolved}\n";
cron_mark_ran($conn, 'fampay_order_watcher', "Checked {$checked}, Resolved {$resolved}");
