<?php
require_once __DIR__."/conn.php";

/* ================= LOG SYSTEM ================= */

$logFile = __DIR__ . "/balance_repair.log";

function repair_log($msg)
{
    global $logFile;

    file_put_contents(
        $logFile,
        date("Y-m-d H:i:s") . " | " . $msg . PHP_EOL,
        FILE_APPEND
    );
}

/* ================= LOG ROTATION ================= */

if (file_exists($logFile)) {

    $file_age = time() - filemtime($logFile);

    if ($file_age > 600) {
        file_put_contents($logFile, "");
    }
}

echo "🔥 BALANCE REPAIR STARTED\n";

define('BAN_THRESHOLD', 13);

$fixed  = 0;
$banned = 0;

try {

    /* =========================================================
       STEP 0 → PREVENT PARALLEL CRON
    ========================================================= */

    $lock = $pdo->query("SELECT GET_LOCK('balance_repair_lock', 5)")->fetchColumn();

    if (!$lock) {
        echo "⚠️ Cron already running. Exiting.\n";
        exit;
    }

    /* =========================================================
       STEP 1 → EXPIRE OLD WAITING OTP
    ========================================================= */

    echo "⏳ Expiring old waiting OTP...\n";

    $pdo->beginTransaction();

    $expired = $pdo->prepare("
        SELECT id, user_id, price
        FROM otp_history
        WHERE status = 'waiting'
        AND created_at <= (NOW() - INTERVAL 11 MINUTE)
        FOR UPDATE
    ");

    $expired->execute();
    $rows = $expired->fetchAll(PDO::FETCH_ASSOC);

    foreach ($rows as $otp) {

        $otp_id  = $otp['id'];
        $user_id = $otp['user_id'];
        $amount  = (float)$otp['price'];

        $stmt = $pdo->prepare("
            UPDATE otp_history
            SET status = 'cancelled'
            WHERE id = ?
            AND status = 'waiting'
        ");
        $stmt->execute([$otp_id]);

        if ($stmt->rowCount() > 0) {

            $stmt2 = $pdo->prepare("
                UPDATE user_data
                SET balance = balance + ?
                WHERE user_id = ?
            ");
            $stmt2->execute([$amount, $user_id]);

            repair_log("OTP_CANCELLED | otp={$otp_id} | user={$user_id} | refund={$amount}");

            echo "✅ OTP {$otp_id} → Refund ₹{$amount}\n";
        }
    }

    $pdo->commit();

    /* =========================================================
       STEP 2 → RECALCULATE SPEND
    ========================================================= */

   echo "💰 Recalculating spend...\n";

$pdo->exec("
    UPDATE user_data ud
    LEFT JOIN (

        SELECT user_id, SUM(total_spend) AS grand_spend
        FROM (

            /* ✅ OTP SPEND */
            SELECT user_id, SUM(price) AS total_spend
            FROM otp_history
            WHERE status IN ('received', 'waiting')
            GROUP BY user_id

            UNION ALL

            /* ✅ ACCOUNTS SPEND */
            SELECT a.used_by AS user_id, SUM(s.price) AS total_spend
            FROM accounts_stock a
            JOIN account_servers s ON a.server_id = s.id
            WHERE a.used_by IS NOT NULL
            GROUP BY a.used_by

            UNION ALL

            /* ✅ SESSION SPEND */
            SELECT ss.used_by AS user_id, SUM(s.price) AS total_spend
            FROM session_stock ss
            JOIN account_servers s ON ss.server_id = s.id
            WHERE ss.used_by IS NOT NULL
            GROUP BY ss.used_by

        ) combined_spend

        GROUP BY user_id

    ) spend_calc ON ud.user_id = spend_calc.user_id

    SET ud.spend = GREATEST(IFNULL(spend_calc.grand_spend, 0), 0)
");
echo "💳 Recalculating DAMO from deposits...\n";

$pdo->exec("
    UPDATE user_data ud
    LEFT JOIN (
        SELECT user_id, SUM(amount) AS total_deposit
        FROM deposit_history
        WHERE status = 'success'
        GROUP BY user_id
    ) dep_calc ON ud.user_id = dep_calc.user_id

    SET ud.damo = GREATEST(IFNULL(dep_calc.total_deposit, 0), 0)
");

    /* =========================================================
       STEP 3 → BALANCE REPAIR
    ========================================================= */

    $users = $pdo->query("
        SELECT user_id, balance, damo, spend
        FROM user_data
    ")->fetchAll(PDO::FETCH_ASSOC);

    foreach ($users as $u) {

        $user_id = $u['user_id'];

        $balance = (float)$u['balance'];
        $damo    = (float)$u['damo'];
        $spend   = (float)$u['spend'];

        $expected_balance = round($damo - $spend, 2);
        $diff = round($expected_balance - $balance, 2);

        if ($diff == 0) {
            continue;
        }

        echo "👤 USER {$user_id}\n";
        echo "BALANCE={$balance} | EXPECTED={$expected_balance} | DIFF={$diff}\n";
echo "🔓 Auto Unbanning eligible users...\n";

$unbanned = $pdo->exec("
    UPDATE user_data
    SET status = 'ACTIVE'
    WHERE 
        status = 'BANNED'
        AND ROUND(damo - spend, 2) >= 0
");

echo "✅ UNBANNED USERS: {$unbanned}\n";
        /* ================= ADD ================= */

        if ($diff > 0) {

            $stmt = $pdo->prepare("
                UPDATE user_data
                SET balance = balance + ?
                WHERE user_id = ?
            ");
            $stmt->execute([$diff, $user_id]);

            repair_log("ADD | user={$user_id} | amount={$diff}");

            echo "✅ ADDED ₹{$diff}\n";
            $fixed++;
        }

        /* ================= CUT ================= */

        if ($diff < 0) {

            $cut_amount = abs($diff);

            $stmt = $pdo->prepare("
                UPDATE user_data
                SET balance = balance - ?
                WHERE user_id = ?
                AND balance >= ?
            ");
            $stmt->execute([$cut_amount, $user_id, $cut_amount]);

            if ($stmt->rowCount() > 0) {

                repair_log("CUT | user={$user_id} | amount={$cut_amount}");

                echo "✅ CUT ₹{$cut_amount}\n";
                $fixed++;

            } else {

                /* ✅ BAN ONLY IF BIG DIFFERENCE */

                if ($cut_amount >= BAN_THRESHOLD) {

                    $stmt = $pdo->prepare("
                        UPDATE user_data
                        SET status = 'BANNED'
                        WHERE user_id = ?
                    ");
                    $stmt->execute([$user_id]);

                    repair_log("BAN | user={$user_id} | reason=INSUFFICIENT_BALANCE | diff={$cut_amount}");

                    echo "🚫 USER BANNED (DIFF ₹{$cut_amount})\n";
                    $banned++;

                } else {

                    repair_log("SMALL_DIFF_IGNORED | user={$user_id} | diff={$cut_amount}");

                    echo "⚠️ SMALL DIFF ₹{$cut_amount} → NO ACTION\n";
                }
            }
        }

        echo "-----------------------------------\n";
    }

    echo "🔥 BALANCE REPAIR COMPLETED\n";
    echo "✅ FIXED USERS: {$fixed}\n";
    echo "🚫 BANNED USERS: {$banned}\n";

    /* =========================================================
       RELEASE LOCK
    ========================================================= */

    $pdo->query("SELECT RELEASE_LOCK('balance_repair_lock')");

} catch (Throwable $e) {

    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    repair_log("ERROR | ".$e->getMessage());
    echo "❌ ERROR: ".$e->getMessage();
}
