/* ===============================
   Dashboard – ARDEM VITU (independent)
   - Loads data ONLY when "Apply" is clicked
   - Uses its own keys: "dashboardFilters", "dashboardFiltersApplied"
   - Sticky per-page; no cross-page effects
=============================== */

let doughnutChart = null;
let barChart = null;

/* ---------- Popup helper (Bootstrap modal if available, else alert) ---------- */
function showWarning(message) {
  try {
    if (typeof $ === "function" && $("#dateWarningModal").length) {
      $("#dateWarningModal .modal-body").text(message || "Please check your inputs.");
      $("#dateWarningModal").modal("show");
      return;
    }
  } catch (e) {
    // ignore and fall back to alert
  }
  alert(message || "Please check your inputs.");
}

/* ---------- Filters ---------- */
function getFiltersFromUI() {
  return {
    fromDate: document.getElementById("fromDate")?.value || "",
    toDate: document.getElementById("toDate")?.value || "",
    state: document.getElementById("stateSelect")?.value || ""
  };
}

function loadFiltersToUI() {
  const saved = localStorage.getItem("dashboardFilters");
  if (!saved) return null;
  const f = JSON.parse(saved);
  const stateEl = document.getElementById("stateSelect");
  const fromEl  = document.getElementById("fromDate");
  const toEl    = document.getElementById("toDate");
  if (stateEl) stateEl.value = f.state || "";
  if (fromEl)  fromEl.value  = f.fromDate || "";
  if (toEl)    toEl.value    = f.toDate || "";
  return f;
}

function saveFilters(f) {
  localStorage.setItem("dashboardFilters", JSON.stringify(f));
}

function setAppliedFlag(on) {
  if (on) {
    localStorage.setItem("dashboardFiltersApplied", JSON.stringify({ applied: true, ts: Date.now() }));
  } else {
    localStorage.removeItem("dashboardFiltersApplied");
  }
}

function isApplied() {
  try {
    const v = JSON.parse(localStorage.getItem("dashboardFiltersApplied") || "{}");
    return !!v.applied;
  } catch { return false; }
}

/* ---------- UI Reset ---------- */
function resetTiles() {
  ["filesReceived","filesProcessed","filesDelivered","filesFailed"].forEach(id => {
    const el = document.getElementById(id);
    if (el) el.innerText = "0";
  });
}
function resetCharts() {
  if (doughnutChart) { doughnutChart.data.datasets[0].data = [0,0]; doughnutChart.update(); }
  if (barChart)      { barChart.data.labels = []; barChart.data.datasets[0].data = []; barChart.update(); }
}
function resetAll() { resetTiles(); resetCharts(); }

/* ---------- Charts ---------- */
function initCharts() {
  const doughnutEl = document.getElementById("doughnutChart");
  const barEl = document.getElementById("barChart");

  if (doughnutEl) {
    doughnutChart = new Chart(doughnutEl.getContext("2d"), {
      type: "doughnut",
      data: {
        labels: ["Success","Failed"],
        datasets: [{
          data: [0,0],
          backgroundColor: ["#28a745","#ab251c"],
          borderColor: ["#ffffff","#ffffff"],
          borderWidth: 2
        }]
      },
      options: { responsive: true, maintainAspectRatio: false }
    });
  }
  if (barEl) {
    barChart = new Chart(barEl.getContext("2d"), {
      type: "bar",
      data: {
        labels: [],
        datasets: [{
          label: "Files",
          data: [],
          backgroundColor: "#007bff"
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        scales: { y: { beginAtZero: true } }
      }
    });
  }
}

function labelsFromEdges(edges) {
  if (!Array.isArray(edges) || edges.length < 2) return [];
  const labels = [];
  for (let i=0;i<edges.length-1;i++) {
    labels.push(`${Math.round(edges[i])}–${Math.round(edges[i+1])}s`);
  }
  return labels;
}

/* ---------- Small helpers for robust client-side counts ---------- */
function isRejectedOrDuplicateRow(r) {
  if (!r) return false;
  const s = (r.status || "").toString().toUpperCase();
  if (s === "FAILED" || s === "DUPLICATE") return true;
  if (r.is_duplicate === 1 || r.is_duplicate === true) return true;
  if (typeof r.rejected_for === "string" && r.rejected_for.trim() !== "") return true;
  if (typeof r.rejection_reason === "string" && r.rejection_reason.trim() !== "") return true;
  return false;
}

function matchesStateRow(row, state) {
  if (!state) return true; // empty state means all states
  if (!row) return false;
  const s = String(state).trim().toLowerCase();
  const candidates = [row.state, row.state_code, row.stateName, row.location, row.region, row.stateShort];
  for (const v of candidates) {
    if (!v) continue;
    const vs = String(v).trim().toLowerCase();
    if (vs === s) return true;
    if (vs.includes(s)) return true;
    if (s.includes(vs)) return true;
  }
  return false;
}

/* ---------- Fetch + Render (updated to prefer file-derived counts filtered by state) ---------- */
async function fetchAndRender() {
  const { fromDate, toDate, state } = getFiltersFromUI();
  if (!fromDate || !toDate || !state || !isApplied()) { resetAll(); return; }

  try {
    // KPIs (server-provided summary; we still fetch it but prefer file-derived counts when available)
    const kRes = await fetch(
      `/api/kpis?from=${encodeURIComponent(fromDate)}&to=${encodeURIComponent(toDate)}&state=${encodeURIComponent(state)}`,
      { credentials: "include" }
    );
    if (!kRes.ok) throw new Error(`KPIs HTTP ${kRes.status}`);
    const kpis = await kRes.json();

    // Attempt to fetch file-level rows (more accurate for per-state counts)
    let filesResp = null;
    try {
      const fRes = await fetch(
        `/api/files?from=${encodeURIComponent(fromDate)}&to=${encodeURIComponent(toDate)}&state=${encodeURIComponent(state)}`,
        { credentials: "include" }
      );
      if (fRes.ok) filesResp = await fRes.json();
    } catch (e) {
      // ignore and fallback to KPIs
      filesResp = null;
    }

    // Default to KPI-derived counts
    let received  = Number(kpis?.received || 0);
    let processed = Number(kpis?.processed || 0);
    let rejected  = Number(kpis?.rejected || 0);

    // If we have file rows, filter them defensively by state and compute counts client-side
    if (Array.isArray(filesResp)) {
      const filesForState = filesResp.filter(r => matchesStateRow(r, state));
      received = filesForState.length;
      let procCount = 0;
      let rejCount = 0;
      for (const r of filesForState) {
        const st = String((r.status || "")).toUpperCase();
        if (isRejectedOrDuplicateRow(r) || st === "FAILED" || st === "DUPLICATE") {
          rejCount++;
          continue;
        }
        if (st === "SUCCESS") procCount++;
        // otherwise ignore for processed
      }
      processed = procCount;
      rejected = rejCount;
    }

    const delivered = Number(processed); // delivered == processed per requirement

    // Update tiles
    const rEl = document.getElementById("filesReceived");
    const pEl = document.getElementById("filesProcessed");
    const dEl = document.getElementById("filesDelivered");
    const fEl = document.getElementById("filesFailed");
    if (rEl) rEl.innerText = received;
    if (pEl) pEl.innerText = processed;
    if (dEl) dEl.innerText = delivered;
    if (fEl) fEl.innerText = rejected;

    // Charts
    const cRes = await fetch(
      `/api/charts?from=${encodeURIComponent(fromDate)}&to=${encodeURIComponent(toDate)}&state=${encodeURIComponent(state)}`,
      { credentials: "include" }
    );
    if (!cRes.ok) throw new Error(`Charts HTTP ${cRes.status}`);
    const charts = await cRes.json();

    // --- IMPORTANT: keep doughnut in sync with tiles by using client-derived counts ---
    // Use processed/rejected derived above (prefer file-derived), not charts.status_pie which may be unfiltered.
    if (doughnutChart) {
      doughnutChart.data.datasets[0].data = [Number(processed || 0), Number(rejected || 0)];
      doughnutChart.update();
    }

    // Bar chart still uses server charting data
    const edges = charts?.time_hist?.bin_edges || [];
    const counts = charts?.time_hist?.counts || [];
    if (barChart) {
      barChart.data.labels = labelsFromEdges(edges);
      barChart.data.datasets[0].data = counts || [];
      barChart.update();
    }
  } catch (err) {
    console.error("Dashboard fetch error:", err);
    resetAll();
  }
}

/* ---------- Init ---------- */
document.addEventListener("DOMContentLoaded", () => {
  // Only initialize if this script is running on the dashboard page.
  const currentPage = (location.pathname.split("/").pop() || "").toLowerCase();
  if (!currentPage.includes("dashboard")) {
    // Not the dashboard page — do not initialize or wire up handlers.
    return;
  }

  // Restore UI + charts
  loadFiltersToUI();
  initCharts();

  // Render if previously applied; else keep blank
  if (isApplied()) fetchAndRender(); else resetAll();

  // Apply
  const applyBtn = document.getElementById("applyFilters");
  if (applyBtn) {
    applyBtn.addEventListener("click", () => {
      const f = getFiltersFromUI();

      // Warn if only one date is selected
      const onlyOneDate = (!!f.fromDate && !f.toDate) || (!f.fromDate && !!f.toDate);
      if (onlyOneDate) {
        showWarning("Please select both Start and End date.");
        return;
      }

      // If any of the three are missing, keep dashboard blank (no popup here)
      if (!f.fromDate || !f.toDate || !f.state) {
        resetAll();
        setAppliedFlag(false);
        return;
      }

      saveFilters(f);
      setAppliedFlag(true);
      fetchAndRender();
    });
  }

  // Clear (only this page’s keys)
  const clearBtn = document.getElementById("clearFilters");
  if (clearBtn) {
    clearBtn.addEventListener("click", () => {
      localStorage.removeItem("dashboardFilters");
      setAppliedFlag(false);
      const s = document.getElementById("stateSelect");
      const fd = document.getElementById("fromDate");
      const td = document.getElementById("toDate");
      if (s) s.value = "";
      if (fd) fd.value = "";
      if (td) td.value = "";
      resetAll();
    });
  }

  // Cross-tab sync (dashboard-only)
  window.addEventListener("storage", (event) => {
    // If this page isn't the dashboard page, ignore the event (defensive)
    const page = (location.pathname.split("/").pop() || "").toLowerCase();
    if (!page.includes("dashboard")) return;

    if (event.key === "dashboardFilters") {
      loadFiltersToUI();
      if (isApplied()) fetchAndRender();
    }
    if (event.key === "dashboardFiltersApplied") {
      if (isApplied()) { loadFiltersToUI(); fetchAndRender(); }
      else { resetAll(); }
    }
  });
});
