const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const dbFilePath = path.join(__dirname, 'proxies.db'); // Jalur ke file database SQLite
const db = new sqlite3.Database(dbFilePath);

// Fungsi untuk memuat semua proxy yang tersedia
const loadAvailableProxies = () => {
    return new Promise((resolve, reject) => {
        const query = `
            SELECT p.*
            FROM proxies p
            LEFT JOIN (
                SELECT proxy_id, status
                FROM used_at
                WHERE times = (
                    SELECT MAX(times)
                    FROM used_at
                    WHERE proxy_id = used_at.proxy_id
                )
            ) ua ON p.id = ua.proxy_id
            WHERE p.status = 'available' AND (ua.status = 'success' OR ua.status IS NULL)
            ORDER BY p.used ASC;
        `;

        db.all(query, (err, rows) => {
            if (err) {
                return reject(err);
            }
            resolve(rows);
        });
    });
};

// Fungsi untuk memilih proxy acak dari daftar
const getProxy = async () => {
    const proxies = await loadAvailableProxies();

    const now = new Date().toLocaleString('id-ID', {
        timeZone: 'Asia/Jakarta'
    });

    // Hanya perbarui waktu "start" jika belum ada nilai pada kolom "start"
    db.run(`UPDATE proxy_list SET start = ? WHERE id = (SELECT MAX(id) FROM proxy_list) AND start IS NULL`, [now], (err) => {
        if (err) {
            console.error('Gagal memperbarui waktu "start":', err);
        }
    });

    if (proxies.length === 0) {
        console.log('Tidak ada proxy yang available.');
        return null;
    }

    // Pilih proxy yang paling sedikit digunakan
    const selectedProxy = proxies[0];
    const id = selectedProxy.id;

    // Cek apakah ada username dan password dalam address
    let proxyAuth = '';
    let proxyAddress = '';
    let addressParts = '';

    if (selectedProxy.address.includes('@')) {
        addressParts = selectedProxy.address.split('@');
        proxyAuth = addressParts[0];
        proxyAddress = addressParts[1];
    } else {
        addressParts = selectedProxy.address.split(':');
        // Jika format adalah host:port:username:password, ubah menjadi username:password@host:port
        if (addressParts.length === 4) {
            // Format host:port:username:password
            const [host, port, username, password] = addressParts;
            proxyAuth = `${username}:${password}@`;
            proxyAddress = `${host}:${port}`;
        } else if (addressParts.length === 2) {
            // Format host:port tanpa autentikasi
            proxyAddress = selectedProxy.address; // Tidak ada autentikasi
        } else {
            // Format tidak dikenal, tambahkan penanganan error atau fallback
            console.log('Format Proxy Tidak Dikenal', selectedProxy.address);
            proxyAddress = selectedProxy.address;
        }
    }

    const status = 'success';
    updateProxyUsage(id, status);

    // Kembalikan proxy dengan autentikasi jika ada
    return {
        id,
        proxyAuth,
        proxyAddress
    };
};

// Fungsi untuk menyimpan data penggunaan proxy (update "used" dan "used_at")
const updateProxyUsage = (proxyId, status) => {
    const now = new Date().toLocaleString('id-ID', {
        timeZone: 'Asia/Jakarta'
    });

    if (status == 'failed') {
        db.run(`UPDATE used_at SET status = ? WHERE proxy_id = ?`, [status, proxyId]);
    } else {
        db.run(`UPDATE proxies SET used = used + 1, status = 'non available' WHERE id = ?`, [proxyId]);
        db.run(
            `INSERT INTO used_at (proxy_id, times, status) VALUES (?, ?, ?)`,
            [proxyId, now, status],
            (err) => {
                if (err) {
                    console.error('Gagal memperbarui penggunaan proxy:', err);
                }
            }
        );
    }
};

// Fungsi untuk mengembalikan proxy ke status 'available'
const resetProxyStatus = (proxyId) => {
    db.run(`UPDATE proxies SET status = 'available' WHERE id = ?`, [proxyId], (err) => {
        if (err) {
            console.error('Gagal memperbarui status proxy:', err);
        }
    });

    const now = new Date().toLocaleString('id-ID', {
        timeZone: 'Asia/Jakarta'
    });

    db.run(`UPDATE proxy_list SET end = ? WHERE id = (SELECT MAX(id) FROM proxy_list)`, [now], (err) => {
        if (err) {
            console.error('Gagal memperbarui waktu "end":', err);
        }
    });
};

// Fungsi untuk update data start dan end
const resetStartAndEndTime = () => {
    db.run(`UPDATE proxy_list SET start = NULL, end = NULL WHERE start IS NOT NULL`, (err) => {
        if (err) {
            console.error('Gagal mereset waktu "start":', err);
        } else {
            console.log('Waktu "start" telah direset');
        }
    });
}

// Fungsi untuk mengupdate waktu end
const updateEndTime = () => {
    const now = new Date().toLocaleString('id-ID', {
        timeZone: 'Asia/Jakarta'
    });

    db.run(`UPDATE proxy_list SET end = ? WHERE id = (SELECT MAX(id) FROM proxy_list)`, [now], (err) => {
        if (err) {
            console.error('Gagal memperbarui waktu "end":', err);
        }
    });
};

module.exports = {
    getProxy,
    updateProxyUsage,
    resetProxyStatus,
    resetStartAndEndTime,
    updateEndTime
};