const axios = require('axios');
const db = require('../database');

const PTERO_URL = 'https://panel.firefrostgaming.com/api/client/servers';

function getHeaders() {
    return {
        'Authorization': `Bearer ${process.env.PTERO_CLIENT_KEY}`,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    };
}

// Rate limit helper - 200ms between calls
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

/**
 * Sync a single server's schedule to Pterodactyl
 */
async function syncToPterodactyl(serverId) {
    const result = await db.query('SELECT * FROM server_restart_schedules WHERE server_id = $1', [serverId]);
    const server = result.rows[0];
    
    if (!server) {
        return { success: false, error: 'Server not found in database' };
    }
    
    const [hour, minute] = server.effective_time.split(':');
    const pteroUrl = `${PTERO_URL}/${server.server_id}/schedules`;
    
    const payload = {
        name: "[Trinity] Daily Restart",
        minute, 
        hour, 
        day_of_week: "*", 
        day_of_month: "*", 
        month: "*",
        is_active: !server.skip_restart
    };

    try {
        let scheduleId = server.ptero_schedule_id;

        if (!scheduleId) {
            // Create new schedule
            const res = await axios.post(pteroUrl, payload, { headers: getHeaders() });
            scheduleId = res.data.attributes.id;

            // Attach the restart task
            await sleep(200);
            await axios.post(`${pteroUrl}/${scheduleId}/tasks`, {
                action: "power", 
                payload: "restart", 
                time_offset: 0
            }, { headers: getHeaders() });
        } else {
            // Update existing schedule
            await axios.post(`${pteroUrl}/${scheduleId}`, payload, { headers: getHeaders() });
        }

        await db.query(
            `UPDATE server_restart_schedules 
             SET ptero_schedule_id = $1, sync_status = $2, last_error = NULL, last_synced_at = NOW() 
             WHERE server_id = $3`,
            [scheduleId, 'SUCCESS', server.server_id]
        );
        
        // Log success
        await db.query(
            `INSERT INTO sync_logs (server_id, action, status) VALUES ($1, $2, $3)`,
            [server.server_id, 'Created/Updated Schedule', 'SUCCESS']
        );
        
        return { success: true, scheduleId };
    } catch (err) {
        const errorMsg = err.response?.data?.errors?.[0]?.detail || err.message;
        await db.query(
            `UPDATE server_restart_schedules 
             SET sync_status = $1, last_error = $2 
             WHERE server_id = $3`,
            ['FAILED', errorMsg, server.server_id]
        );
        
        await db.query(
            `INSERT INTO sync_logs (server_id, action, status, error_message) VALUES ($1, $2, $3, $4)`,
            [server.server_id, 'Sync Failed', 'FAILED', errorMsg]
        );
        
        return { success: false, error: errorMsg };
    }
}

/**
 * Find existing restart schedules NOT owned by Trinity
 */
async function auditServerSchedules(serverId, serverName) {
    const pteroUrl = `${PTERO_URL}/${serverId}/schedules`;
    
    try {
        const res = await axios.get(pteroUrl, { headers: getHeaders() });
        const schedules = res.data.data || [];
        
        // Find ANY schedule not created by Trinity
        const rogueSchedules = schedules
            .filter(s => !s.attributes.name.startsWith('[Trinity]'))
            .map(s => ({
                id: s.attributes.id,
                name: s.attributes.name,
                cron: `${s.attributes.minute} ${s.attributes.hour} * * *`,
                isActive: s.attributes.is_active
            }));
        
        return { serverId, serverName, rogueSchedules };
    } catch (err) {
        console.error(`Audit failed for ${serverName}:`, err.message);
        return { serverId, serverName, rogueSchedules: [], error: err.message };
    }
}

/**
 * Delete a specific schedule from Pterodactyl
 */
async function deleteSchedule(serverId, scheduleId, scheduleName) {
    const pteroUrl = `${PTERO_URL}/${serverId}/schedules/${scheduleId}`;
    
    try {
        await axios.delete(pteroUrl, { headers: getHeaders() });
        
        await db.query(
            `INSERT INTO sync_logs (server_id, action, status) VALUES ($1, $2, $3)`,
            [serverId, `Deleted Rogue Schedule: ${scheduleName}`, 'SUCCESS']
        );
        
        return { success: true };
    } catch (err) {
        const errorMsg = err.response?.data?.errors?.[0]?.detail || err.message;
        
        await db.query(
            `INSERT INTO sync_logs (server_id, action, status, error_message) VALUES ($1, $2, $3, $4)`,
            [serverId, `Failed to Delete: ${scheduleName}`, 'FAILED', errorMsg]
        );
        
        return { success: false, error: errorMsg };
    }
}

/**
 * Sync all servers for a node
 */
async function syncAllForNode(node) {
    const result = await db.query(
        'SELECT server_id FROM server_restart_schedules WHERE node = $1 ORDER BY sort_order',
        [node]
    );
    
    const results = [];
    for (const row of result.rows) {
        const syncResult = await syncToPterodactyl(row.server_id);
        results.push({ serverId: row.server_id, ...syncResult });
        await sleep(200); // Rate limiting
    }
    
    return results;
}

module.exports = { 
    syncToPterodactyl, 
    auditServerSchedules, 
    deleteSchedule,
    syncAllForNode,
    sleep
};
