// Note: This script expects csrfToken to be available globally
// It should be set in the HTML template before this script loads

// ========== 전역 변수 ==========
let CONFIG = {
    grace_minutes: 60,
    recency_hours: 24,
    poll_interval_ms: 10000
};

let monitoringOn = false;
let pollTimer = null;
let lastRenderHash = "";

// ========== Elements ==========
const $ = id => document.getElementById(id);
const $body = $('jobs-body');
const $last = $('last-updated');
const $loading = $('loading-indicator');
const $btn = $('btn-refresh');
const $auto = $('autoRefreshSwitch');
const $ipInput = $('ipInput');
const $ipCount = $('ip-count');
const $btnLoad = $('btn-load-file');
const $btnApply = $('btn-apply');
const $monSw = $('monitorSwitch');
const $statusDot = $('status-dot');
const $statusText = $('status-text');
const $showCompleted = $('showCompletedSwitch');
const $pollInterval = $('poll-interval');

// Stats
const $statTotal = $('stat-total');
const $statRunning = $('stat-running');
const $statCompleted = $('stat-completed');
const $statError = $('stat-error');

// ========== LocalStorage Keys ==========
const LS_IPS = 'idrac_job_ips';
const LS_MON = 'idrac_monitor_on';
const LS_AUTO = 'idrac_monitor_auto';
const LS_SHOW_COMPLETED = 'idrac_show_completed';

// ========== 유틸리티 ==========
function parseIps(text) {
    if (!text) return [];
    const raw = text.replace(/[,;]+/g, '\n');
    const out = [], seen = new Set();
    raw.split('\n').forEach(line => {
        const parts = line.trim().split(/\s+/);
        parts.forEach(p => {
            if (!p || p.startsWith('#')) return;
            if (!seen.has(p)) {
                seen.add(p);
                out.push(p);
            }
        });
    });
    return out;
}

function getIpsFromUI() { return parseIps($ipInput.value); }
function setIpsToUI(ips) {
    $ipInput.value = (ips || []).join('\n');
    updateIpCount();
}
function updateIpCount() {
    const ips = getIpsFromUI();
    $ipCount.textContent = ips.length;
}
function saveIps() {
    localStorage.setItem(LS_IPS, JSON.stringify(getIpsFromUI()));
    updateIpCount();
}
function loadIps() {
    try {
        const v = JSON.parse(localStorage.getItem(LS_IPS) || "[]");
        return Array.isArray(v) ? v : [];
    } catch {
        return [];
    }
}

function escapeHtml(s) {
    return String(s).replace(/[&<>"']/g, m => ({
        '&': '&amp;', '<': '&lt;', '>': '&gt;',
        '"': '&quot;', "'": '&#39;'
    }[m]));
}

function progressBar(pc) {
    const n = parseInt(String(pc ?? "").toString().replace('%', '').trim(), 10);
    if (isNaN(n)) return `<span class="text-muted small">${escapeHtml(pc ?? "")}</span>`;

    let bgClass = 'bg-info';
    if (n === 100) bgClass = 'bg-success';
    else if (n < 30) bgClass = 'bg-warning';

    return `<div class="progress" style="height:8px;">
        <div class="progress-bar ${bgClass}" role="progressbar" 
             style="width:${n}%;" aria-valuenow="${n}" aria-valuemin="0" aria-valuemax="100"></div>
    </div>
    <small class="text-muted">${n}%</small>`;
}

function badgeStatus(status, pc, recently = false) {
    const raw = String(status || "");
    const s = raw.toLowerCase();
    let cls = "bg-secondary";
    let icon = "info-circle";

    if (recently) {
        cls = "bg-success";
        icon = "check-circle";
    } else if (s.includes("completed")) {
        cls = "bg-success";
        icon = "check-circle";
    } else if (s.includes("running") || s.includes("progress")) {
        cls = "bg-info";
        icon = "arrow-repeat";
    } else if (s.includes("scheduled") || s.includes("pending")) {
        cls = "bg-warning text-dark";
        icon = "clock";
    } else if (s.includes("failed") || s.includes("error")) {
        cls = "bg-danger";
        icon = "x-circle";
    }

    const pct = parseInt(String(pc ?? "").toString().replace('%', '').trim(), 10);
    const pctText = isNaN(pct) ? "" : ` (${pct}%)`;
    const text = recently ? `${raw || "Completed"} (최근${pctText})` : `${raw || "-"}${pctText}`;

    return `<span class="badge ${cls}">
        <i class="bi bi-${icon}"></i> ${escapeHtml(text)}
    </span>`;
}

function updateStats(items) {
    let total = 0, running = 0, completed = 0, error = 0;

    items.forEach(it => {
        if (!it.ok) {
            error++;
            return;
        }
        if (it.jobs && it.jobs.length) {
            total++;
            it.jobs.forEach(j => {
                const s = (j.Status || "").toLowerCase();
                if (s.includes("running") || s.includes("progress") || s.includes("starting")) {
                    running++;
                } else if (s.includes("completed") || s.includes("success")) {
                    completed++;
                } else if (s.includes("failed") || s.includes("error")) {
                    error++;
                }
            });
        }
    });

    $statTotal.textContent = items.length;
    $statRunning.textContent = running;
    $statCompleted.textContent = completed;
    $statError.textContent = error;
}

// ========== 렌더링 ==========
function renderTable(items) {
    if (!items) return;

    const hash = JSON.stringify(items);
    if (hash === lastRenderHash) return;
    lastRenderHash = hash;

    if (!items.length) {
        $body.innerHTML = `<tr><td colspan="7" class="text-center text-muted py-4">
            <i class="bi bi-inbox fs-2 d-block mb-2"></i>
            현재 모니터링 중인 Job이 없습니다.
        </td></tr>`;
        updateStats([]);
        return;
    }

    const rows = [];
    for (const it of items) {
        if (!it.ok) {
            rows.push(`<tr class="table-danger">
                <td><code>${escapeHtml(it.ip)}</code></td>
                <td colspan="6">
                    <i class="bi bi-exclamation-triangle"></i> 
                    오류: ${escapeHtml(it.error || "Unknown")}
                </td>
            </tr>`);
            continue;
        }

        if (!it.jobs || !it.jobs.length) continue;

        for (const j of it.jobs) {
            const recent = !!j.RecentlyCompleted;
            const timeText = j.CompletedAt
                ? `완료: ${escapeHtml(j.CompletedAt.split('T')[1]?.split('.')[0] || j.CompletedAt)}`
                : escapeHtml(j.LastUpdateTime || "");

            rows.push(`<tr ${recent ? 'class="table-success"' : ''}>
                <td><code>${escapeHtml(it.ip)}</code></td>
                <td><small class="font-monospace">${escapeHtml(j.JID || "")}</small></td>
                <td><strong>${escapeHtml(j.Name || "")}</strong></td>
                <td>${badgeStatus(j.Status || "", j.PercentComplete || "", recent)}</td>
                <td>${progressBar(j.PercentComplete || "0")}</td>
                <td><small>${escapeHtml(j.Message || "")}</small></td>
                <td><small class="text-muted">${timeText}</small></td>
            </tr>`);
        }
    }

    $body.innerHTML = rows.length
        ? rows.join("")
        : `<tr><td colspan="7" class="text-center text-success py-4">
            <i class="bi bi-check-circle fs-2 d-block mb-2"></i>
            현재 진행 중인 Job이 없습니다. ✅
        </td></tr>`;

    updateStats(items);
}

// ========== 서버 요청 ==========
async function fetchJobs(auto = false) {
    if (!monitoringOn) {
        $body.innerHTML = `<tr><td colspan="7" class="text-center text-muted py-4">
            <i class="bi bi-power fs-2 d-block mb-2"></i>
            모니터링이 꺼져 있습니다. 상단 스위치를 켜면 조회가 시작됩니다.
        </td></tr>`;
        $last.textContent = "";
        updateStats([]);
        return;
    }

    const ips = getIpsFromUI();
    if (!ips.length) {
        $body.innerHTML = `<tr><td colspan="7" class="text-center text-warning py-4">
            <i class="bi bi-exclamation-triangle fs-2 d-block mb-2"></i>
            IP 목록이 비어 있습니다.
        </td></tr>`;
        $last.textContent = "";
        updateStats([]);
        return;
    }

    try {
        $loading.classList.remove('d-none');
        $last.textContent = "조회 중… " + new Date().toLocaleTimeString();

        const res = await fetch("/jobs/scan", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "X-CSRFToken": csrfToken
            },
            body: JSON.stringify({
                ips,
                method: "redfish",  // Redfish 사용
                recency_hours: CONFIG.recency_hours,
                grace_minutes: CONFIG.grace_minutes,
                include_tracked_done: $showCompleted.checked
            })
        });

        const data = await res.json();
        if (!data.ok) throw new Error(data.error || "Scan failed");

        renderTable(data.items);
        $last.textContent = "업데이트: " + new Date().toLocaleString();
    } catch (e) {
        $body.innerHTML = `<tr><td colspan="7" class="text-danger text-center py-4">
            <i class="bi bi-exclamation-circle fs-2 d-block mb-2"></i>
            로드 실패: ${escapeHtml(e.message)}
            <br><button class="btn btn-sm btn-outline-primary mt-2" onclick="fetchJobs(false)">
                <i class="bi bi-arrow-clockwise"></i> 재시도
            </button>
        </td></tr>`;
        $last.textContent = "에러: " + new Date().toLocaleString();
        console.error(e);
    } finally {
        $loading.classList.add('d-none');
    }
}

// ========== 모니터링 제어 ==========
function startAuto() {
    stopAuto();
    pollTimer = setInterval(() => fetchJobs(true), CONFIG.poll_interval_ms);
}

function stopAuto() {
    if (pollTimer) {
        clearInterval(pollTimer);
        pollTimer = null;
    }
}

function updateMonitorUI() {
    $btn.disabled = !monitoringOn;
    $auto.disabled = !monitoringOn;

    if (monitoringOn) {
        $statusDot.classList.add('active');
        $statusText.textContent = '모니터링 중';
    } else {
        $statusDot.classList.remove('active');
        $statusText.textContent = '모니터링 꺼짐';
    }
}

async function setMonitoring(on) {
    monitoringOn = !!on;
    localStorage.setItem(LS_MON, monitoringOn ? "1" : "0");
    updateMonitorUI();

    if (!monitoringOn) {
        stopAuto();
        $last.textContent = "";
        $body.innerHTML = `<tr><td colspan="7" class="text-center text-muted py-4">
            <i class="bi bi-power fs-2 d-block mb-2"></i>
            모니터링이 꺼져 있습니다.
        </td></tr>`;
        lastRenderHash = "";
        updateStats([]);
        return;
    }

    await fetchJobs(false);
    if ($auto.checked) startAuto();
}

// ========== 초기화 ==========
document.addEventListener('DOMContentLoaded', async () => {
    // 설정 로드
    try {
        const res = await fetch('/jobs/config');
        const data = await res.json();
        if (data.ok) {
            CONFIG = data.config;
            $pollInterval.textContent = Math.round(CONFIG.poll_interval_ms / 1000);
        }
    } catch (e) {
        console.error("Failed to load config:", e);
    }

    // IP 복원
    const savedIps = loadIps();
    if (savedIps.length) {
        setIpsToUI(savedIps);
    } else {
        try {
            const res = await fetch('/jobs/iplist', {
                headers: { 'X-CSRFToken': csrfToken }
            });
            const data = await res.json();
            if (data.ok && data.ips) {
                setIpsToUI(data.ips);
                saveIps();
            }
        } catch (e) {
            console.error(e);
        }
    }

    // 설정 복원
    const savedMon = localStorage.getItem(LS_MON);
    const savedAuto = localStorage.getItem(LS_AUTO);
    const savedShowCompleted = localStorage.getItem(LS_SHOW_COMPLETED);

    $monSw.checked = savedMon === "1";
    $auto.checked = savedAuto === "1";
    $showCompleted.checked = savedShowCompleted !== "0";

    // 이벤트
    $ipInput.addEventListener('input', updateIpCount);
    $btn.addEventListener('click', () => { if (monitoringOn) fetchJobs(false); });
    $auto.addEventListener('change', e => {
        localStorage.setItem(LS_AUTO, e.target.checked ? "1" : "0");
        if (!monitoringOn) return;
        if (e.target.checked) startAuto();
        else stopAuto();
    });
    $monSw.addEventListener('click', e => setMonitoring(e.target.checked));
    $showCompleted.addEventListener('change', e => {
        localStorage.setItem(LS_SHOW_COMPLETED, e.target.checked ? "1" : "0");
        if (monitoringOn) fetchJobs(false);
    });
    $btnLoad.addEventListener('click', async () => {
        try {
            const res = await fetch('/jobs/iplist', {
                headers: { 'X-CSRFToken': csrfToken }
            });
            const data = await res.json();
            if (data.ok) {
                setIpsToUI(data.ips || []);
                saveIps();
                if (monitoringOn) await fetchJobs(false);
            }
        } catch (e) {
            alert('IP 목록 불러오기 실패: ' + e.message);
        }
    });
    $btnApply.addEventListener('click', () => {
        saveIps();
        if (monitoringOn) fetchJobs(false);
    });

    // 초기 상태
    updateMonitorUI();
    updateIpCount();

    if ($monSw.checked) {
        setMonitoring(true);
    }
});
