// Desktop dashboard — 3-column layout for the Finanzas prototype.
// Width 1280, height 820 (designed for the design-canvas artboard).

const { useState: dsState, useMemo: dsMemo, useEffect: dsEffect } = React;

const DESK_NAV = [
  { id: "inicio",        label: "Inicio",        icon: "home" },
  { id: "transacciones", label: "Transacciones", icon: "list" },
  { id: "presupuestos",  label: "Presupuestos",  icon: "budget" },
  { id: "cuentas",       label: "Cuentas",       icon: "wallet" },
  { id: "reportes",      label: "Reportes",      icon: "chart" },
];

function DesktopApp({ fullscreen = false } = {}) {
  const Icon = window.FinanzasIcon;
  const [txs, setTxs] = window.usePersistedState(window.finanzasStorage.loadTx, window.finanzasStorage.saveTx);
  const [accs, setAccs] = window.usePersistedState(window.finanzasStorage.loadAccounts, window.finanzasStorage.saveAccounts);
  const [budgets, setBudgets] = window.usePersistedState(window.finanzasStorage.loadBudgets, window.finanzasStorage.saveBudgets);
  const [accFilter, setAccFilter] = dsState("all");
  const [showAdd, setShowAdd] = dsState(false);
  const [editTx, setEditTx] = dsState(null);
  const [route, setRoute] = dsState("inicio");
  const [hide, setHide] = dsState(false);
  const [query, setQuery] = dsState("");
  const [period, setPeriod] = dsState("mes"); // hoy|semana|mes|año
  const [dark, setDark] = dsState(() => !!window.finanzasStorage.loadPrefs().dark);

  const toggleDark = () => {
    const next = !dark;
    setDark(next);
    const prefs = window.finanzasStorage.loadPrefs();
    window.finanzasStorage.savePrefs({ ...prefs, dark: next });
    document.documentElement.classList.toggle("dark", next);
  };

  const balance = window.totalBalance(accs);

  const NOW = new Date();
  const periodCutoff = dsMemo(() => {
    const d = new Date(NOW);
    if (period === "hoy")    { d.setHours(0,0,0,0); return d; }
    if (period === "semana") { d.setDate(d.getDate() - 7); return d; }
    if (period === "mes")    { d.setDate(d.getDate() - 31); return d; }
    if (period === "año")    { d.setDate(d.getDate() - 365); return d; }
    return new Date(0);
  }, [period]);

  const filteredTx = dsMemo(() => {
    const q = query.trim().toLowerCase();
    return txs.filter(t => {
      if (accFilter !== "all" && t.acc !== accFilter) return false;
      if (new Date(t.date) < periodCutoff) return false;
      if (q) {
        const cat = window.catBy(t.cat)?.label.toLowerCase() || "";
        const acc = window.accBy(t.acc)?.name.toLowerCase() || "";
        if (!t.desc.toLowerCase().includes(q) && !cat.includes(q) && !acc.includes(q)) return false;
      }
      return true;
    });
  }, [txs, accFilter, periodCutoff, query]);

  const spend  = window.monthSpending(filteredTx);
  const income = window.monthIncome(filteredTx);
  const byCat  = window.spendByCategory(filteredTx);

  const handleSave = (tx) => {
    if (tx.kind === "transfer") {
      const when = tx.date || new Date().toISOString().slice(0, 16);
      const tid = "tr" + Date.now();
      setTxs(prev => [
        { id: "n" + Date.now() + "o", date: when, amount: -Math.abs(tx.amount),
          desc: tx.desc || `Transferencia a ${window.accBy(tx.to)?.name || ""}`,
          cat: "transfer", acc: tx.from, tags: ["transfer", `tr:${tid}`] },
        { id: "n" + Date.now() + "i", date: when, amount: Math.abs(tx.amount),
          desc: tx.desc || `Transferencia desde ${window.accBy(tx.from)?.name || ""}`,
          cat: "transfer", acc: tx.to, tags: ["transfer", `tr:${tid}`] },
        ...prev,
      ]);
      setShowAdd(false);
      setEditTx(null);
      return;
    }
    if (tx.id) {
      setTxs(prev => {
        const target = prev.find(t => t.id === tx.id);
        const tid = target && (target.tags || []).find(x => x.startsWith?.("tr:"));
        return prev.map(t => {
          if (t.id === tx.id) {
            const merged = { ...t, ...tx };
            if (tid) {
              const sign = t.amount < 0 ? -1 : 1;
              merged.amount = sign * Math.abs(tx.amount);
              merged.cat = "transfer";
              merged.tags = Array.from(new Set([...(tx.tags || []), "transfer", tid]));
            }
            return merged;
          }
          if (tid && (t.tags || []).includes(tid)) {
            const sign = t.amount < 0 ? -1 : 1;
            return {
              ...t,
              amount: sign * Math.abs(tx.amount),
              date: tx.date || t.date,
              desc: tx.desc || t.desc,
            };
          }
          return t;
        });
      });
    } else {
      setTxs(prev => [{
        id: "n" + Date.now(),
        date: tx.date || new Date().toISOString().slice(0, 16),
        ...tx,
      }, ...prev]);
    }
    setShowAdd(false);
    setEditTx(null);
  };

  const handleDelete = (tx) => {
    setTxs(prev => {
      const target = prev.find(t => t.id === tx.id);
      const tid = target && (target.tags || []).find(x => x.startsWith?.("tr:"));
      return prev.filter(t => {
        if (t.id === tx.id) return false;
        if (tid && (t.tags || []).includes(tid)) return false;
        return true;
      });
    });
    setEditTx(null);
  };

  return (
    <div style={{
      width: fullscreen ? "100vw" : 1280,
      height: fullscreen ? "100vh" : 820,
      background: "var(--bx-bg)",
      fontFamily: "Inter, system-ui, sans-serif",
      color: "var(--bx-ink-1)",
      display: "grid",
      gridTemplateColumns: route === "inicio" ? "240px 1fr 360px" : "240px 1fr",
      position: "relative",
      overflow: "hidden",
    }}>
      {/* ────── Sidebar ────── */}
      <aside style={{
        background: "var(--bx-paper)",
        borderRight: "1px solid var(--bx-line)",
        display: "flex", flexDirection: "column",
        padding: "28px 16px 20px",
      }}>
        {/* Logo */}
        <div style={{ padding: "0 8px 24px", display: "flex", alignItems: "center", gap: 10 }}>
          <div style={{
            width: 36, height: 36, borderRadius: 10,
            background: "var(--bx-navy-700)",
            color: "#fff",
            display: "inline-flex", alignItems: "center", justifyContent: "center",
            fontFamily: "'Bebas Neue', sans-serif",
            fontSize: 22, letterSpacing: "0.02em",
          }}>F</div>
          <div>
            <div style={{
              fontFamily: "'Bebas Neue', sans-serif",
              fontSize: 20, color: "var(--bx-ink-1)",
              letterSpacing: "0.06em", lineHeight: 1,
            }}>FINANZAS</div>
            <div style={{ fontSize: 10, color: "var(--bx-ink-3)", letterSpacing: "0.14em", textTransform: "uppercase", marginTop: 2 }}>
              Personal · MXN
            </div>
          </div>
        </div>

        {/* Nav */}
        <nav style={{ display: "flex", flexDirection: "column", gap: 2 }}>
          <div style={{
            fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase",
            color: "var(--bx-ink-3)", fontWeight: 600, padding: "0 10px 10px",
          }}>Menú</div>
          {DESK_NAV.map(item => (
            <button key={item.id} onClick={() => setRoute(item.id)} style={{
              display: "flex", alignItems: "center", gap: 12,
              padding: "10px 12px", borderRadius: 8,
              border: "none", cursor: "pointer", textAlign: "left",
              background: route === item.id ? "var(--bx-bg-tint)" : "transparent",
              color: route === item.id ? "var(--bx-navy-700)" : "var(--bx-ink-2)",
              fontSize: 13, fontWeight: route === item.id ? 600 : 500,
              fontFamily: "Inter, sans-serif",
              transition: "background 120ms",
            }}>
              <Icon name={item.icon} size={18} stroke={2} />
              {item.label}
              {route === item.id && (
                <span style={{ marginLeft: "auto", width: 6, height: 6, borderRadius: 3, background: "var(--bx-navy-700)" }} />
              )}
            </button>
          ))}
        </nav>

        {/* Accounts list */}
        <div style={{ marginTop: 24 }}>
          <div style={{
            fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase",
            color: "var(--bx-ink-3)", fontWeight: 600, padding: "0 10px 10px",
          }}>Cuentas</div>
          {accs.map(a => (
            <button key={a.id} onClick={() => setAccFilter(f => f === a.id ? "all" : a.id)}
              style={{
                display: "flex", alignItems: "center", gap: 10,
                padding: "8px 12px", borderRadius: 8,
                border: "none", cursor: "pointer", textAlign: "left",
                background: accFilter === a.id ? "var(--bx-bg-tint)" : "transparent",
                width: "100%",
              }}>
              <span style={{ width: 8, height: 8, borderRadius: 4, background: a.color }} />
              <span style={{ fontSize: 12, color: "var(--bx-ink-2)", flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                {a.name}
              </span>
              <span style={{
                fontSize: 11, fontFamily: "'JetBrains Mono', monospace",
                color: a.balance < 0 ? "var(--bx-danger)" : "var(--bx-ink-3)",
                fontFeatureSettings: "'tnum'",
              }}>{window.fmtCompact(a.balance)}</span>
            </button>
          ))}
        </div>

        {/* User pill at bottom */}
        {(() => {
          const session = window.finanzasStorage.getSession?.();
          const email = session?.user?.email || "";
          const initials = (email.split("@")[0] || "?").slice(0, 2).toUpperCase();
          const username = email.split("@")[0] || "Usuario";
          return (
        <div style={{ marginTop: "auto", display: "flex", alignItems: "center", gap: 10, padding: "10px 8px" }}>
          <div style={{
            width: 32, height: 32, borderRadius: 16,
            background: "linear-gradient(135deg, #1a2a5e, #2f4a92)",
            display: "inline-flex", alignItems: "center", justifyContent: "center",
            color: "#fff", fontSize: 12, fontWeight: 700,
            fontFamily: "Inter, sans-serif",
          }}>{initials}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: "var(--bx-ink-1)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }} title={email}>{username}</div>
            <div style={{ fontSize: 10, color: "var(--bx-ink-3)" }}>Sesión activa</div>
          </div>
          <button onClick={toggleDark} title="Modo oscuro" style={{
            background: "transparent", border: "none", cursor: "pointer",
            color: "var(--bx-ink-3)", padding: 4,
          }}><Icon name={dark ? "eye" : "eyeOff"} size={16} /></button>
          <button onClick={async () => {
            if (!confirm("¿Cerrar sesión?")) return;
            await window.finanzasStorage.signOut();
            location.reload();
          }} title="Cerrar sesión" style={{
            background: "transparent", border: "none", cursor: "pointer",
            color: "var(--bx-ink-3)", padding: 4,
          }}><Icon name="settings" size={16} /></button>
        </div>
          );
        })()}
      </aside>

      {/* ────── Main column ────── */}
      {route === "inicio" && (<>
      <main style={{
        display: "flex", flexDirection: "column",
        overflow: "hidden",
        padding: "24px 28px 0",
        gap: 20,
      }}>
        {/* Top bar: greeting + search */}
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--bx-ink-3)", fontWeight: 600 }}>
              {NOW.toLocaleDateString("es-MX", { weekday: "long", day: "numeric", month: "long", year: "numeric" })}
            </div>
            <div style={{
              fontFamily: "Manrope, Inter, sans-serif",
              fontSize: 20, fontWeight: 800, color: "var(--bx-ink-1)",
              marginTop: 4, letterSpacing: "-0.01em",
            }}>{(() => {
              const s = window.finanzasStorage.getSession?.();
              const name = s?.user?.email?.split("@")[0] || "Usuario";
              return `Buenos días, ${name.charAt(0).toUpperCase() + name.slice(1)}.`;
            })()}</div>
          </div>
          <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
            <div style={{
              display: "flex", alignItems: "center", gap: 8,
              background: "var(--bx-paper)", border: "1px solid var(--bx-line)",
              borderRadius: 8, padding: "8px 12px", width: 220,
            }}>
              <window.FinanzasIcon name="search" size={14} style={{ color: "var(--bx-ink-3)" }} />
              <input placeholder="Buscar transacción…"
                value={query} onChange={(e) => setQuery(e.target.value)}
                style={{
                  border: "none", outline: "none", background: "transparent",
                  fontSize: 12, color: "var(--bx-ink-1)", width: "100%",
                }} />
              <span style={{ fontSize: 10, color: "var(--bx-ink-4)", border: "1px solid var(--bx-line)", borderRadius: 4, padding: "1px 5px" }}>⌘K</span>
            </div>
            <button style={iconBtnStyle()}><Icon name="bell" size={16} stroke={2} /></button>
          </div>
        </div>

        {/* Balance hero */}
        <div style={{
          background: "var(--bx-paper)",
          border: "1px solid var(--bx-line)",
          borderRadius: 14,
          padding: "24px 28px",
          display: "grid",
          gridTemplateColumns: "1fr auto",
          alignItems: "center",
          gap: 24,
          backgroundImage: `radial-gradient(120% 80% at 100% 0%, rgba(31,58,138,.05) 0%, transparent 55%)`,
        }}>
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <div style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--bx-ink-3)", fontWeight: 600 }}>
                Balance Total · {accs.length} {accs.length === 1 ? "cuenta" : "cuentas"}
              </div>
              <button onClick={() => setHide(h => !h)} style={{
                background: "transparent", border: "none", cursor: "pointer",
                color: "var(--bx-ink-3)", padding: 2,
              }}><Icon name={hide ? "eyeOff" : "eye"} size={14} stroke={2} /></button>
            </div>
            <div style={{
              fontFamily: "'Bebas Neue', sans-serif",
              fontSize: 56, lineHeight: 1, marginTop: 8,
              color: "var(--bx-ink-1)", letterSpacing: "0.01em", fontWeight: 400,
              whiteSpace: "nowrap",
            }}>
              {window.fmtMXN(balance, { hide }).replace("$", "$ ")}
              <span style={{ fontSize: 18, color: "var(--bx-ink-3)", marginLeft: 8, letterSpacing: "0.06em" }}>MXN</span>
            </div>
            <div style={{ display: "flex", gap: 24, marginTop: 14 }}>
              <Delta dir="up"   label={`Ingresos · ${NOW.toLocaleDateString("es-MX",{month:"long"})}`} value={income} />
              <Delta dir="down" label={`Gastos · ${NOW.toLocaleDateString("es-MX",{month:"long"})}`}   value={spend} />
              <Delta dir="net"  label="Disponible" value={income - spend} />
            </div>
          </div>
          <button onClick={() => setShowAdd(true)} style={{
            display: "inline-flex", alignItems: "center", gap: 10,
            padding: "16px 22px",
            background: "var(--bx-navy-700)", color: "#fff",
            border: "none", borderRadius: 10,
            fontSize: 13, fontWeight: 600,
            fontFamily: "Inter, sans-serif",
            letterSpacing: "0.04em", textTransform: "uppercase",
            cursor: "pointer",
            boxShadow: "0 8px 24px -8px rgba(26,42,94,.5)",
          }}>
            <Icon name="plus" size={16} stroke={2.5} />
            Añadir gasto
            <span style={{
              marginLeft: 6, fontSize: 10, opacity: .65,
              border: "1px solid rgba(255,255,255,.3)", borderRadius: 4,
              padding: "1px 5px", letterSpacing: 0, textTransform: "none",
            }}>N</span>
          </button>
        </div>

        {/* Transactions list */}
        <section style={{
          flex: 1,
          background: "var(--bx-paper)",
          border: "1px solid var(--bx-line)",
          borderRadius: 14,
          padding: "20px 24px 0",
          display: "flex", flexDirection: "column",
          minHeight: 0,
        }}>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", paddingBottom: 12 }}>
            <div>
              <div style={{
                fontFamily: "Manrope, Inter, sans-serif",
                fontSize: 18, fontWeight: 800, color: "var(--bx-ink-1)",
              }}>Últimos movimientos</div>
              <div style={{ fontSize: 12, color: "var(--bx-ink-3)", marginTop: 2 }}>
                {accFilter === "all" ? "Todas las cuentas" : window.accBy(accFilter).name} · {filteredTx.length} movimientos
              </div>
            </div>
            <div style={{ display: "flex", gap: 6 }}>
              {[["hoy", "Hoy"], ["semana", "Semana"], ["mes", "Mes"], ["año", "Año"]].map(([k, p]) => {
                const active = period === k;
                return (
                  <button key={k} onClick={() => setPeriod(k)} style={{
                    padding: "6px 12px", fontSize: 11, fontWeight: 600,
                    borderRadius: 999, border: "1px solid var(--bx-navy-700)",
                    background: active ? "var(--bx-navy-700)" : "transparent",
                    color: active ? "#fff" : "var(--bx-navy-700)",
                    cursor: "pointer", fontFamily: "Inter, sans-serif",
                  }}>{p}</button>
                );
              })}
              <button onClick={() => setAccFilter("all")} title="Limpiar filtros"
                style={iconBtnStyle()}><Icon name="filter" size={14} stroke={2} /></button>
            </div>
          </div>

          <div style={{ flex: 1, overflowY: "auto", paddingBottom: 8 }}>
            {filteredTx.length === 0 && (
              <div style={{
                padding: "60px 20px", textAlign: "center", color: "var(--bx-ink-3)",
              }}>
                <div style={{
                  fontFamily: "Manrope, Inter, sans-serif", fontSize: 16, fontWeight: 700,
                  color: "var(--bx-ink-2)", marginBottom: 6,
                }}>Sin movimientos aún</div>
                <div style={{ fontSize: 13, marginBottom: 16 }}>
                  Pulsa <strong>Añadir gasto</strong> para registrar tu primer movimiento.
                </div>
                <button onClick={() => setShowAdd(true)} style={{
                  padding: "10px 18px", background: "var(--bx-navy-700)", color: "#fff",
                  border: "none", borderRadius: 8, fontSize: 12, fontWeight: 600,
                  letterSpacing: "0.04em", textTransform: "uppercase", cursor: "pointer",
                }}>Añadir primero</button>
              </div>
            )}
            {groupByDay(filteredTx).map(([day, items], gi, arr) => (
              <div key={day}>
                <div style={{
                  fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase",
                  color: "var(--bx-ink-3)", fontWeight: 600,
                  padding: "12px 0 4px",
                  display: "flex", justifyContent: "space-between",
                }}>
                  <span>{day}</span>
                  <span style={{ fontFamily: "'JetBrains Mono', monospace", color: "var(--bx-ink-3)" }}>
                    {window.fmtMXN(items.reduce((s, t) => s + t.amount, 0), { sign: true })}
                  </span>
                </div>
                {items.map((t, i) => (
                  <window.TxRow key={t.id} tx={t} onEdit={setEditTx}
                    last={i === items.length - 1 && gi === arr.length - 1} />
                ))}
              </div>
            ))}
          </div>
        </section>
      </main>

      {/* ────── Right column ────── */}
      <aside style={{
        borderLeft: "1px solid var(--bx-line)",
        background: "var(--bx-paper)",
        padding: "24px 22px",
        display: "flex", flexDirection: "column", gap: 22,
        overflow: "hidden",
      }}>
        {/* Donut */}
        <div>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 8 }}>
            <div>
              <div style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--bx-ink-3)", fontWeight: 600 }}>
                Mayo 2026
              </div>
              <div style={{
                fontFamily: "Manrope, Inter, sans-serif",
                fontSize: 16, fontWeight: 800, color: "var(--bx-ink-1)",
              }}>Gastos por categoría</div>
            </div>
            <button style={{
              fontSize: 11, color: "var(--bx-navy-700)", background: "transparent",
              border: "none", cursor: "pointer", fontWeight: 600,
              display: "flex", alignItems: "center", gap: 2,
            }}>Ver todo <Icon name="chevR" size={11} stroke={2.5} /></button>
          </div>
          <div style={{ display: "flex", justifyContent: "center", padding: "8px 0 4px" }}>
            <window.DonutChart data={byCat} total={spend} size={196} thickness={20}
              caption={`de $${(spend * 1.4).toFixed(0)} promedio`} />
          </div>
          <div style={{ marginTop: 8 }}>
            {byCat.slice(0, 4).map(d => (
              <window.LegendItem key={d.id} d={d} total={spend} />
            ))}
          </div>
        </div>

        <div style={{ height: 1, background: "var(--bx-line)" }} />

        {/* Budgets */}
        <div style={{ minHeight: 0, display: "flex", flexDirection: "column" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }}>
            <div>
              <div style={{
                fontFamily: "Manrope, Inter, sans-serif",
                fontSize: 16, fontWeight: 800, color: "var(--bx-ink-1)",
              }}>Presupuestos</div>
              <div style={{ fontSize: 11, color: "var(--bx-ink-3)", marginTop: 2 }}>
                Mayo · 14 de 31 días
              </div>
            </div>
            <button style={{
              fontSize: 11, color: "var(--bx-navy-700)", background: "transparent",
              border: "none", cursor: "pointer", fontWeight: 600,
            }}>Editar</button>
          </div>
          <div style={{ overflowY: "auto", flex: 1 }}>
            {budgets.length === 0 ? (
              <div style={{
                padding: "20px 4px", fontSize: 12, color: "var(--bx-ink-3)", textAlign: "center",
              }}>
                Sin presupuestos. Configúralos en <button onClick={() => setRoute("presupuestos")} style={{
                  background: "transparent", border: "none", padding: 0, cursor: "pointer",
                  color: "var(--bx-navy-700)", fontWeight: 600, fontSize: 12,
                }}>Presupuestos</button>.
              </div>
            ) : budgets.map(b => <window.BudgetRow key={b.cat} b={b} />)}
          </div>
        </div>
      </aside>
      </>)}

      {/* ────── Alternate route main ────── */}
      {route !== "inicio" && (
        <main style={{
          display: "flex", flexDirection: "column",
          overflow: "hidden",
          padding: "28px 32px 24px",
          gap: 18,
        }}>
          <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between" }}>
            <div>
              <div style={{ fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--bx-ink-3)", fontWeight: 600 }}>
                Finanzas
              </div>
              <div style={{
                fontFamily: "Manrope, Inter, sans-serif",
                fontSize: 26, fontWeight: 800, color: "var(--bx-ink-1)",
                marginTop: 4, letterSpacing: "-0.01em", textTransform: "capitalize",
              }}>{routeTitle(route)}</div>
            </div>
            {(route === "transacciones") && (
              <button onClick={() => setShowAdd(true)} style={{
                padding: "10px 18px", background: "var(--bx-navy-700)", color: "#fff",
                border: "none", borderRadius: 8, fontSize: 12, fontWeight: 600,
                letterSpacing: "0.04em", textTransform: "uppercase", cursor: "pointer",
                display: "inline-flex", alignItems: "center", gap: 8,
              }}><Icon name="plus" size={14} stroke={2.5} /> Añadir gasto</button>
            )}
          </div>
          {route === "transacciones" && <window.TransactionsView txs={txs} accs={accs} onEdit={setEditTx} />}
          {route === "presupuestos"  && <window.BudgetsView budgets={budgets} setBudgets={setBudgets} txs={txs} />}
          {route === "cuentas"       && <window.AccountsView accs={accs} setAccs={setAccs} txs={txs} />}
          {route === "reportes"      && <window.ReportsView txs={txs} />}
        </main>
      )}

      {/* Modal */}
      {(showAdd || editTx) && (
        <window.AddExpenseForm variant="modal"
          initial={editTx}
          accs={accs}
          onClose={() => { setShowAdd(false); setEditTx(null); }}
          onSave={handleSave}
          onDelete={handleDelete} />
      )}
    </div>
  );
}

function Delta({ dir, label, value }) {
  const colors = {
    up:   { c: "var(--bx-success)", icon: "arrowUp"   },
    down: { c: "var(--bx-danger)",  icon: "arrowDown" },
    net:  { c: "var(--bx-navy-700)",icon: "money"     },
  };
  const Icon = window.FinanzasIcon;
  const { c, icon } = colors[dir];
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
      <div style={{ fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase", color: "var(--bx-ink-3)", fontWeight: 600 }}>
        {label}
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
        <span style={{
          width: 18, height: 18, borderRadius: 9, background: `${c.replace("var(--bx-", "rgba(").replace(")", ", 0.12)") /* keep simple */}`,
          background: "transparent", color: c,
          display: "inline-flex", alignItems: "center", justifyContent: "center",
        }}><Icon name={icon} size={12} stroke={2.5} /></span>
        <span style={{
          fontFamily: "'JetBrains Mono', monospace",
          fontSize: 15, fontWeight: 700, color: "var(--bx-ink-1)",
          fontFeatureSettings: "'tnum'",
        }}>{window.fmtMXN(value)}</span>
      </div>
    </div>
  );
}

function iconBtnStyle() {
  return {
    width: 36, height: 36, borderRadius: 8,
    background: "var(--bx-paper)", border: "1px solid var(--bx-line)",
    color: "var(--bx-ink-2)", cursor: "pointer",
    display: "inline-flex", alignItems: "center", justifyContent: "center",
  };
}

function routeTitle(r) {
  return { inicio: "Inicio", transacciones: "Transacciones", presupuestos: "Presupuestos", cuentas: "Cuentas", reportes: "Reportes" }[r] || r;
}

function groupByDay(txs) {
  const map = {};
  for (const t of txs) {
    const k = window.dayLabel(t.date);
    if (!map[k]) map[k] = [];
    map[k].push(t);
  }
  return Object.entries(map);
}

Object.assign(window, { DesktopApp });
