const pool = require("../models/db");

/**
 * Get a proxy assigned to an account. If the account has a previously used proxy, reuse it.
 * Otherwise, find an unused proxy with retry logic.
 */
async function getProxy(accountId) {
    try {
        // Check if the account already has an assigned proxy
        const [assignedProxyRows] = await pool.query(
            "SELECT proxy FROM accounts WHERE id = ? AND proxy IS NOT NULL",
            [accountId]
        );

        if (assignedProxyRows.length > 0) {
            const assignedProxy = assignedProxyRows[0].proxy;
            console.log(`🔍 Found assigned proxy ${assignedProxy} for account ${accountId}`);
            return assignedProxy;
        }

        // No assigned proxy found, find a new unused one
        const [proxyRows] = await pool.query(
            "SELECT id, proxy, retry_count FROM proxies WHERE status = 'active' AND assigned_to IS NULL LIMIT 1"
        );

        if (proxyRows.length === 0) {
            console.error("⚠ No unused proxies available.");
            return null;
        }

        const selectedProxy = proxyRows[0];

        // Check if the proxy has reached the retry limit
        if (selectedProxy.retry_count >= 3) {
            await markProxyFailed(selectedProxy.proxy);
            return await getProxy(accountId);  // Retry with a new proxy
        }

        // Assign the new proxy to the account and update the database
        await pool.query("UPDATE accounts SET proxy = ? WHERE id = ?", [selectedProxy.proxy, accountId]);
        await pool.query("UPDATE proxies SET assigned_to = ? WHERE id = ?", [accountId, selectedProxy.id]);

        console.log(`📤 Assigned new proxy ${selectedProxy.proxy} to account ${accountId}`);
        return selectedProxy.proxy;
    } catch (error) {
        console.error(`❌ Error retrieving proxy for account ${accountId}: ${error.message}`);
        return null;
    }
}

/**
 * Mark a proxy as failed and remove its assignment from the account.
 * Increment retry count and mark as failed if retries exceed 3.
 */
async function markProxyFailed(proxy) {
    try {
        // Increment retry count
        await pool.query("UPDATE proxies SET retry_count = retry_count + 1 WHERE proxy = ?", [proxy]);

        // Check if retry count has reached 3
        const [proxyRow] = await pool.query("SELECT retry_count FROM proxies WHERE proxy = ?", [proxy]);
        if (proxyRow.length > 0 && proxyRow[0].retry_count >= 3) {
            console.log(`❌ Proxy ${proxy} marked as failed after 3 retries.`);
            await pool.query("UPDATE proxies SET status = 'failed', assigned_to = NULL WHERE proxy = ?", [proxy]);
            await pool.query("UPDATE accounts SET proxy = NULL WHERE proxy = ?", [proxy]);
        } else {
            console.log(`⚠ Proxy ${proxy} failed, retry count: ${proxyRow[0].retry_count}`);
        }
    } catch (error) {
        console.error(`❌ Error marking proxy as failed: ${error.message}`);
    }
}

/**
 * Reset all proxies to active every month.
 */
async function resetProxies() {
    try {
        await pool.query("UPDATE proxies SET status = 'active', assigned_to = NULL, retry_count = 0");
        console.log("🔄 All proxies reset to active.");
    } catch (error) {
        console.error(`❌ Error resetting proxies: ${error.message}`);
    }
}

module.exports = { getProxy, markProxyFailed, resetProxies };