// /views/js/dashboard.js
(function () {
    const $ = (s) => document.querySelector(s);
    const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
    const fmtMoney = (n) =>
      Number(n || 0).toLocaleString("es-MX", { style: "currency", currency: "MXN" });
    const fmtInt = (n) => Number(n || 0).toLocaleString("es-MX");
    const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
  
    const MONTHS = [
      "Enero","Febrero","Marzo","Abril","Mayo","Junio",
      "Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"
    ];
    const today = new Date();
    const real = { y: today.getFullYear(), m: today.getMonth() + 1 }; // mes real límite
    const state = { y: real.y, m: real.m };
  
    // ===== Animaciones =====
    function animateNumberInt(el, to, formatter = (x) => x, duration = 450) {
      if (!el) return;
      const start = performance.now();
      const target = Number(to || 0);
      function frame(now) {
        const t = clamp((now - start) / duration, 0, 1);
        el.textContent = formatter(Math.round(target * easeOutCubic(t)));
        if (t < 1) requestAnimationFrame(frame);
      }
      requestAnimationFrame(frame);
    }
    function animateNumberFloat(el, to, formatter = (x) => x, duration = 700) {
      if (!el) return;
      const start = performance.now();
      const target = Number(to || 0);
      function frame(now) {
        const t = clamp((now - start) / duration, 0, 1);
        el.textContent = formatter(target * easeOutCubic(t));
        if (t < 1) requestAnimationFrame(frame);
      }
      requestAnimationFrame(frame);
    }
    function animateRing(el, toPct, duration = 800) {
      if (!el) return;
      const start = performance.now();
      const target = clamp(Number(toPct || 0), 0, 100);
      const label = el.querySelector("span");
      function frame(now) {
        const t = clamp((now - start) / duration, 0, 1);
        const p = Math.round(target * easeOutCubic(t));
        el.style.setProperty("--pct", p);
        if (label) label.textContent = `${p}%`;
        if (t < 1) requestAnimationFrame(frame);
      }
      requestAnimationFrame(frame);
    }
  
    // ===== Mes UI =====
    function renderMonth() {
      const lbl = $("#monthLabel");
      if (lbl) lbl.textContent = `${MONTHS[state.m - 1]} ${state.y}`;
      const btnNext = $("#btnNext");
      if (btnNext) btnNext.disabled = (state.y > real.y) || (state.y === real.y && state.m >= real.m);
    }
    function goPrevMonth() {
      state.m -= 1;
      if (state.m < 1) { state.m = 12; state.y -= 1; }
      refresh();
    }
    function goNextMonth() {
      // no permitir ir al futuro
      if (state.y === real.y && state.m === real.m) return;
      state.m += 1;
      if (state.m > 12) { state.m = 1; state.y += 1; }
      // clamp por si nos pasamos del real
      if (state.y > real.y || (state.y === real.y && state.m > real.m)) {
        state.y = real.y; state.m = real.m;
      }
      refresh();
    }
  
    // ===== Carga de datos =====
    async function refresh() {
      renderMonth();
      try {
        const res = await fetch(`views/api/dashboard.php?y=${state.y}&m=${state.m}`, { cache: "no-store" });
        const j = await res.json();
        if (!j.success) throw new Error(j.message || "Error de API");
        const k = j.data.kpis || {};
  
        animateNumberInt($("#kpi-platillos"), k.platillos_activos, fmtInt, 450);
        animateNumberInt($("#kpi-pedidos"),   k.pedidos_mes,       fmtInt, 450);
        animateNumberFloat($("#kpi-ganancias"), k.ganancias_mes, fmtMoney, 800);
  
        animateRing($("#ring-entregados"), k.pct_entregados, 800);
        animateRing($("#ring-cancelados"), k.pct_cancelados, 800);
        animateRing($("#ring-pendientes"), k.pct_pendientes, 800);
      } catch (e) {
        // fallback a ceros
        const setText = (sel, val, fmt) => { const el = $(sel); if (el) el.textContent = fmt(val); };
        setText("#kpi-platillos", 0, fmtInt);
        setText("#kpi-pedidos",   0, fmtInt);
        setText("#kpi-ganancias", 0, fmtMoney);
        ["#ring-entregados", "#ring-cancelados", "#ring-pendientes"].forEach((sel)=> {
          const el = $(sel); if (!el) return; el.style.setProperty("--pct", 0);
          const s = el.querySelector("span"); if (s) s.textContent = "0%";
        });
        // console.error(e);
      }
    }
  
    function bind() {
      const prev = $("#btnPrev"); const next = $("#btnNext");
      if (prev) prev.addEventListener("click", goPrevMonth);
      if (next) next.addEventListener("click", goNextMonth);
    }
  
    // Init
    document.readyState === "loading"
      ? document.addEventListener("DOMContentLoaded", () => { bind(); refresh(); })
      : (bind(), refresh());
  })();
  

  // ===== Topbar menu (mobile) =====
(function(){
  const toggle = document.querySelector('.menu-toggle');
  const menu = document.getElementById('topbarMenu');
  if (!toggle || !menu) return;

  toggle.addEventListener('click', (e)=>{
    e.stopPropagation();
    const open = menu.classList.toggle('show');
    toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
  });

  // Cerrar al tocar fuera
  document.addEventListener('click', (e)=>{
    if (!menu.classList.contains('show')) return;
    if (!menu.contains(e.target) && e.target !== toggle){
      menu.classList.remove('show');
      toggle.setAttribute('aria-expanded','false');
    }
  });

  // Reset si crece la pantalla
  window.addEventListener('resize', ()=>{
    if (window.innerWidth > 720){
      menu.classList.remove('show');
      toggle.setAttribute('aria-expanded','false');
    }
  });
})();
