const axios = require("axios");
const moment = require("moment");
const { HttpsProxyAgent } = require("https-proxy-agent");
const pool = require("../models/db");

async function refreshToken(accountId, oldToken, refreshToken, proxy) {
    const accountName = await getAccountName(accountId);
    try {
        console.log(`${accountName} - Refresh Token - Attempting to refresh token - Started`);
        const response = await axios.post(
            "https://api2.datatwix.com/account/v3/token/refresh/", // Correct endpoint
            {
                idfv: false,
                userTimezone: "Asia/Shanghai",
                userTimezoneOffset: -480,
                refreshToken: refreshToken,
                appVersion: "9.7.24",
                userLocale: "en-US"
            },
            {
                headers: {
                    "Host": "api2.datatwix.com",
                    "Accept": "application/json, text/plain, */*",
                    "Authorization": `Bearer ${oldToken}`,
                    "If-None-Match": "undefined",
                    "Content-Type": "application/json",
                    "Accept-Encoding": "gzip, deflate, br",
                    "User-Agent": "okhttp/4.9.2",
                    "Connection": "keep-alive"
                },
                httpsAgent: new HttpsProxyAgent(proxy),
                proxy: false
            }
        );

        const { token: newToken, refreshToken: newRefreshToken } = response.data;
        await pool.query(
            "UPDATE accounts SET token = ?, refresh_token = ?, last_updated = NOW() WHERE id = ?",
            [newToken, newRefreshToken, accountId]
        );
        console.log(`${accountName} - Refresh Token - Successfully refreshed token - Result: Success`);
        return { success: true, newToken };
    } catch (error) {
        const errorMessage = error.response ? `${error.response.status} - ${JSON.stringify(error.response.data)}` : error.message;
        console.log(`${accountName} - Refresh Token - Failed to refresh token - Result: Error ${errorMessage}`);
        return { success: false, error: errorMessage };
    }
}

async function getAccountName(accountId) {
    const [rows] = await pool.query("SELECT name FROM accounts WHERE id = ?", [accountId]);
    return rows.length > 0 ? rows[0].name : `Account ${accountId}`;
}

async function getValidToken(accountId) {
    const [rows] = await pool.query("SELECT token, refresh_token, last_updated, proxy FROM accounts WHERE id = ?", [accountId]);
    const accountName = await getAccountName(accountId);

    if (rows.length === 0) {
        throw new Error("Account not found");
    }

    const { token, refresh_token, last_updated, proxy } = rows[0];
    const lastUpdatedMoment = moment(last_updated);
    const now = moment();

    // Check if token is older than 24 hours
    if (now.diff(lastUpdatedMoment, 'hours') >= 24) {
        console.log(`${accountName} - Validate Token - Token expired (last updated: ${last_updated}) - Refreshing`);
        const result = await refreshToken(accountId, token, refresh_token, proxy);
        if (!result.success) {
            throw new Error(`Failed to refresh token: ${result.error}`);
        }
        return result.newToken;
    }

    // Test token validity with a simple API call
    try {
        console.log(`${accountName} - Validate Token - Testing token validity - Started`);
        await axios.get("https://api2.datatwix.com/rewards/user?voidCache=true&locale=en-US", {
            headers: { "Authorization": `Bearer ${token}` },
            httpsAgent: new HttpsProxyAgent(proxy),
            proxy: false
        });
        console.log(`${accountName} - Validate Token - Token is valid (last updated: ${last_updated}) - Result: Success`);
        return token;
    } catch (error) {
        if (error.response && error.response.status === 401) {
            console.log(`${accountName} - Validate Token - Token invalid (401), attempting refresh - Started`);
            const result = await refreshToken(accountId, token, refresh_token, proxy);
            if (!result.success) {
                throw new Error(`Failed to refresh token after 401: ${result.error}`);
            }
            return result.newToken;
        }
        throw new Error(`Token validation failed: ${error.message}`);
    }
}

module.exports = { getValidToken, refreshToken };