// Route views: Transacciones, Presupuestos, Cuentas, Reportes.
// Shared between desktop main column and mobile tabs.

const { useState: rtState, useMemo: rtMemo } = React;

// ──────────────────────────────────────────────────────────────
// TransactionsView — full list, group by day, filter chips
// ──────────────────────────────────────────────────────────────
function TransactionsView({ txs, accs, onEdit, dense = false }) {
  const [q, setQ] = rtState("");
  const [catSel, setCatSel] = rtState("all");
  const [accSel, setAccSel] = rtState("all");

  const filtered = rtMemo(() => {
    const qq = q.trim().toLowerCase();
    return txs.filter(t => {
      if (catSel !== "all" && t.cat !== catSel) return false;
      if (accSel !== "all" && t.acc !== accSel) return false;
      if (qq) {
        const cat = window.catBy(t.cat)?.label.toLowerCase() || "";
        if (!t.desc.toLowerCase().includes(qq) && !cat.includes(qq)) return false;
      }
      return true;
    });
  }, [txs, q, catSel, accSel]);

  const groups = rtMemo(() => {
    const map = {};
    for (const t of filtered) {
      const k = window.dayLabel(t.date);
      (map[k] ||= []).push(t);
    }
    return Object.entries(map);
  }, [filtered]);

  return (
    <div style={{
      display: "flex", flexDirection: "column", gap: 16,
      flex: 1, minHeight: 0, padding: dense ? "0 16px" : "0",
    }}>
      <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
        <input value={q} onChange={(e) => setQ(e.target.value)}
          placeholder="Buscar…"
          style={{
            flex: 1, minWidth: 180,
            padding: "10px 14px", fontSize: 13,
            background: "var(--bx-paper)", border: "1px solid var(--bx-line)",
            borderRadius: 8, outline: "none", color: "var(--bx-ink-1)",
          }} />
        <select value={catSel} onChange={(e) => setCatSel(e.target.value)} style={selectStyle()}>
          <option value="all">Todas las categorías</option>
          {window.FINANZAS_CATEGORIES.map(c => (
            <option key={c.id} value={c.id}>{c.label}</option>
          ))}
        </select>
        <select value={accSel} onChange={(e) => setAccSel(e.target.value)} style={selectStyle()}>
          <option value="all">Todas las cuentas</option>
          {accs.map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
        </select>
        <button onClick={() => {
          if (!filtered.length) { window.toast?.show("Sin movimientos para exportar"); return; }
          const csv = window.exportTxCsv(filtered);
          const stamp = new Date().toISOString().slice(0, 10);
          window.downloadFile(`finanzas-${stamp}.csv`, csv);
          window.toast?.success("CSV descargado");
        }} style={{
          padding: "9px 14px", fontSize: 12, fontWeight: 600,
          background: "var(--bx-paper)", color: "var(--bx-ink-2)",
          border: "1px solid var(--bx-line)", borderRadius: 8,
          cursor: "pointer", fontFamily: "Inter, sans-serif",
        }}>Exportar CSV</button>
      </div>

      <div style={{
        flex: 1, overflowY: "auto",
        background: "var(--bx-paper)",
        border: "1px solid var(--bx-line)",
        borderRadius: 14,
        padding: "8px 20px",
      }}>
        {groups.length === 0 ? (
          <div style={{ padding: 40, textAlign: "center", color: "var(--bx-ink-3)", fontSize: 13 }}>
            Sin movimientos con esos filtros.
          </div>
        ) : groups.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: "14px 0 4px",
              display: "flex", justifyContent: "space-between",
            }}>
              <span>{day}</span>
              <span style={{ fontFamily: "'JetBrains Mono', monospace" }}>
                {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={onEdit}
                last={i === items.length - 1 && gi === arr.length - 1} />
            ))}
          </div>
        ))}
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// BudgetsView — list with edit limit inline
// ──────────────────────────────────────────────────────────────
function BudgetsView({ budgets, setBudgets, txs }) {
  const [editCat, setEditCat] = rtState(null);
  const [draft, setDraft] = rtState("");

  // Recompute spent from current month txs
  const monthCutoff = window.monthStart();
  const enriched = rtMemo(() => budgets.map(b => {
    const spent = txs
      .filter(t => t.cat === b.cat && t.amount < 0 && new Date(t.date) >= monthCutoff)
      .reduce((s, t) => s + Math.abs(t.amount), 0);
    return { ...b, spent };
  }), [budgets, txs]);

  const startEdit = (b) => { setEditCat(b.cat); setDraft(String(b.limit)); };
  const saveEdit = () => {
    const n = parseFloat(draft);
    if (!Number.isFinite(n) || n <= 0) { setEditCat(null); return; }
    setBudgets(prev => prev.map(b => b.cat === editCat ? { ...b, limit: n } : b));
    setEditCat(null);
  };

  // Categories without a budget yet
  const used = new Set(budgets.map(b => b.cat));
  const available = window.FINANZAS_CATEGORIES.filter(c => !used.has(c.id) && c.id !== "ingreso");

  const addBudget = (cat) => {
    setBudgets(prev => [...prev, { cat, limit: 1000, spent: 0 }]);
  };

  const removeBudget = (cat) => {
    if (!confirm("¿Eliminar este presupuesto?")) return;
    setBudgets(prev => prev.filter(b => b.cat !== cat));
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16, flex: 1, minHeight: 0 }}>
      <div style={{
        background: "var(--bx-paper)",
        border: "1px solid var(--bx-line)",
        borderRadius: 14,
        padding: "8px 20px",
        flex: 1, overflowY: "auto",
      }}>
        {enriched.map(b => {
          const cat = window.catBy(b.cat);
          const pct = Math.min(1, b.spent / b.limit);
          const over = pct >= 0.9;
          const isEditing = editCat === b.cat;
          return (
            <div key={b.cat} style={{
              display: "flex", flexDirection: "column", gap: 8,
              padding: "14px 0", borderBottom: "1px solid var(--bx-line)",
            }}>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                  <window.CatBadge catId={b.cat} size={32} />
                  <div>
                    <div style={{ fontSize: 14, fontWeight: 600, color: "var(--bx-ink-1)" }}>{cat.label}</div>
                    <div style={{ fontSize: 11, color: "var(--bx-ink-3)" }}>
                      {window.fmtMXN(b.spent)} de {window.fmtMXN(b.limit)}
                    </div>
                  </div>
                </div>
                {isEditing ? (
                  <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                    <input value={draft} onChange={(e) => setDraft(e.target.value)}
                      autoFocus type="number" step="100"
                      onKeyDown={(e) => e.key === "Enter" && saveEdit()}
                      style={{
                        width: 100, padding: "6px 10px", fontSize: 13,
                        border: "1px solid var(--bx-navy-700)", borderRadius: 6,
                        outline: "none", fontFamily: "'JetBrains Mono', monospace",
                      }} />
                    <button onClick={saveEdit} style={smBtn(true)}>OK</button>
                    <button onClick={() => setEditCat(null)} style={smBtn(false)}>×</button>
                  </div>
                ) : (
                  <div style={{ display: "flex", gap: 6 }}>
                    <button onClick={() => startEdit(b)} style={smBtn(false)}>Editar</button>
                    <button onClick={() => removeBudget(b.cat)} style={{ ...smBtn(false), color: "var(--bx-danger)" }}>Borrar</button>
                  </div>
                )}
              </div>
              <div style={{ height: 6, borderRadius: 999, background: "var(--bx-line)", overflow: "hidden" }}>
                <div style={{
                  width: `${pct * 100}%`, height: "100%",
                  background: over ? "var(--bx-danger)" : cat.color,
                  borderRadius: 999,
                  transition: "width 360ms cubic-bezier(0.16,1,0.3,1)",
                }} />
              </div>
            </div>
          );
        })}
      </div>

      {available.length > 0 && (
        <div>
          <div style={labelStyleRt()}>Añadir presupuesto</div>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
            {available.map(c => (
              <button key={c.id} onClick={() => addBudget(c.id)} style={{
                display: "flex", alignItems: "center", gap: 8,
                padding: "8px 12px",
                background: "var(--bx-paper)",
                border: `1px solid var(--bx-line)`,
                borderRadius: 999, cursor: "pointer",
                fontSize: 12, color: "var(--bx-ink-1)", fontWeight: 500,
              }}>
                <span style={{ width: 8, height: 8, borderRadius: 4, background: c.color }} />
                {c.label}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// AccountsView — list + create
// ──────────────────────────────────────────────────────────────
function AccountsView({ accs, setAccs, txs }) {
  const [adding, setAdding] = rtState(false);
  const [draft, setDraft] = rtState({ name: "", type: "Débito", balance: "", color: "#1a2a5e", last4: "" });

  const addAcc = () => {
    if (!draft.name.trim()) return;
    const id = draft.name.toLowerCase().replace(/[^a-z0-9]+/g, "").slice(0, 12) + Date.now().toString(36).slice(-4);
    setAccs(prev => [...prev, {
      id, name: draft.name.trim(), type: draft.type,
      balance: parseFloat(draft.balance) || 0,
      color: draft.color, last4: draft.last4 || null,
    }]);
    setDraft({ name: "", type: "Débito", balance: "", color: "#1a2a5e", last4: "" });
    setAdding(false);
  };

  const removeAcc = (id) => {
    if (!confirm("¿Eliminar cuenta? Las transacciones asociadas se mantendrán.")) return;
    setAccs(prev => prev.filter(a => a.id !== id));
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14, flex: 1, minHeight: 0 }}>
      <div style={{
        flex: 1, overflowY: "auto",
        background: "var(--bx-paper)",
        border: "1px solid var(--bx-line)",
        borderRadius: 14,
        padding: "8px 20px",
      }}>
        {accs.map(a => {
          const count = txs.filter(t => t.acc === a.id).length;
          return (
            <div key={a.id} style={{
              padding: "14px 0", borderBottom: "1px solid var(--bx-line)",
              display: "flex", alignItems: "center", gap: 14,
            }}>
              <span style={{ width: 12, height: 12, borderRadius: 6, background: a.color, flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 600, color: "var(--bx-ink-1)" }}>
                  {a.name}{a.last4 ? ` ··${a.last4}` : ""}
                </div>
                <div style={{ fontSize: 11, color: "var(--bx-ink-3)" }}>
                  {a.type} · {count} movimientos
                </div>
              </div>
              <div style={{
                fontFamily: "'JetBrains Mono', monospace", fontSize: 16, fontWeight: 700,
                color: a.balance < 0 ? "var(--bx-danger)" : "var(--bx-ink-1)",
                fontFeatureSettings: "'tnum'",
              }}>{window.fmtMXN(a.balance)}</div>
              <button onClick={() => removeAcc(a.id)} style={{ ...smBtn(false), color: "var(--bx-danger)" }}>Borrar</button>
            </div>
          );
        })}
      </div>

      {adding ? (
        <div style={{
          background: "var(--bx-paper)", border: "1px solid var(--bx-navy-700)",
          borderRadius: 14, padding: 16,
          display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr auto", gap: 10, alignItems: "end",
        }}>
          <Lbl label="Nombre">
            <input value={draft.name} onChange={(e) => setDraft({ ...draft, name: e.target.value })}
              placeholder="ej. Santander" style={inputStyleRt()} />
          </Lbl>
          <Lbl label="Tipo">
            <select value={draft.type} onChange={(e) => setDraft({ ...draft, type: e.target.value })} style={inputStyleRt()}>
              <option>Débito</option><option>Crédito</option><option>Cash</option><option>Inversión</option>
            </select>
          </Lbl>
          <Lbl label="Saldo inicial">
            <input value={draft.balance} type="number" onChange={(e) => setDraft({ ...draft, balance: e.target.value })}
              placeholder="0" style={inputStyleRt()} />
          </Lbl>
          <Lbl label="Últimos 4">
            <input value={draft.last4} onChange={(e) => setDraft({ ...draft, last4: e.target.value })}
              placeholder="0000" maxLength={4} style={inputStyleRt()} />
          </Lbl>
          <div style={{ display: "flex", gap: 6 }}>
            <button onClick={addAcc} style={smBtn(true)}>Guardar</button>
            <button onClick={() => setAdding(false)} style={smBtn(false)}>×</button>
          </div>
        </div>
      ) : (
        <button onClick={() => setAdding(true)} style={{
          padding: "12px 18px", border: "1px dashed var(--bx-line-2)",
          background: "transparent", borderRadius: 12,
          color: "var(--bx-ink-2)", fontSize: 13, fontWeight: 600, cursor: "pointer",
        }}>+ Nueva cuenta</button>
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// ReportsView — month vs month bars + top categories
// ──────────────────────────────────────────────────────────────
function ReportsView({ txs }) {
  const NOW = new Date();
  const curMonthStart = new Date(NOW.getFullYear(), NOW.getMonth(), 1);
  const prevMonthStart = new Date(NOW.getFullYear(), NOW.getMonth() - 1, 1);
  const prevMonthEnd = curMonthStart;

  const cur = txs.filter(t => new Date(t.date) >= curMonthStart);
  const prev = txs.filter(t => {
    const d = new Date(t.date);
    return d >= prevMonthStart && d < prevMonthEnd;
  });

  // Spend by cat for each month
  const byCat = (list) => {
    const m = {};
    for (const t of list) {
      if (t.amount >= 0) continue;
      m[t.cat] = (m[t.cat] || 0) + Math.abs(t.amount);
    }
    return m;
  };
  const curByCat = byCat(cur);
  const prevByCat = byCat(prev);
  const cats = Array.from(new Set([...Object.keys(curByCat), ...Object.keys(prevByCat)]));
  const rows = cats.map(c => ({
    cat: c,
    cur: curByCat[c] || 0,
    prev: prevByCat[c] || 0,
  })).sort((a, b) => (b.cur + b.prev) - (a.cur + a.prev));

  const maxVal = Math.max(1, ...rows.map(r => Math.max(r.cur, r.prev)));
  const curSpend = cur.filter(t => t.amount < 0).reduce((s, t) => s + Math.abs(t.amount), 0);
  const prevSpend = prev.filter(t => t.amount < 0).reduce((s, t) => s + Math.abs(t.amount), 0);
  const diff = prevSpend === 0 ? 0 : ((curSpend - prevSpend) / prevSpend) * 100;

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16, flex: 1, minHeight: 0, overflowY: "auto" }}>
      {/* Summary */}
      <div style={{
        display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12,
      }}>
        <SummaryCard label="Mayo 2026" value={window.fmtMXN(curSpend)} sub="Gasto total" />
        <SummaryCard label="Abril 2026" value={window.fmtMXN(prevSpend)} sub="Mes anterior" muted />
        <SummaryCard label="Cambio" value={`${diff >= 0 ? "+" : ""}${diff.toFixed(1)}%`}
          sub={diff >= 0 ? "Más que abril" : "Menos que abril"}
          color={diff >= 0 ? "var(--bx-danger)" : "var(--bx-success)"} />
      </div>

      {/* Bar chart */}
      <div style={{
        background: "var(--bx-paper)",
        border: "1px solid var(--bx-line)",
        borderRadius: 14,
        padding: "20px 22px",
      }}>
        <div style={{
          display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 16,
        }}>
          <div style={{
            fontFamily: "Manrope, Inter, sans-serif", fontSize: 16, fontWeight: 800, color: "var(--bx-ink-1)",
          }}>Mayo vs Abril · por categoría</div>
          <div style={{ display: "flex", gap: 12, fontSize: 11, color: "var(--bx-ink-3)" }}>
            <span style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <span style={{ width: 10, height: 10, borderRadius: 2, background: "var(--bx-navy-700)" }} /> Mayo
            </span>
            <span style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <span style={{ width: 10, height: 10, borderRadius: 2, background: "var(--bx-ink-5)" }} /> Abril
            </span>
          </div>
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          {rows.length === 0 ? (
            <div style={{ padding: 24, textAlign: "center", color: "var(--bx-ink-3)", fontSize: 13 }}>
              Sin datos para comparar.
            </div>
          ) : rows.map(r => {
            const cat = window.catBy(r.cat);
            return (
              <div key={r.cat} style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}>
                  <span style={{ color: "var(--bx-ink-1)", fontWeight: 600 }}>{cat?.label || r.cat}</span>
                  <span style={{ fontFamily: "'JetBrains Mono', monospace", color: "var(--bx-ink-3)" }}>
                    {window.fmtMXN(r.cur)} vs {window.fmtMXN(r.prev)}
                  </span>
                </div>
                <div style={{ display: "flex", flexDirection: "column", gap: 3 }}>
                  <Bar value={r.cur} max={maxVal} color="var(--bx-navy-700)" />
                  <Bar value={r.prev} max={maxVal} color="var(--bx-ink-5)" />
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function Bar({ value, max, color }) {
  return (
    <div style={{ height: 10, borderRadius: 4, background: "var(--bx-bg)", overflow: "hidden" }}>
      <div style={{
        width: `${(value / max) * 100}%`, height: "100%", background: color,
        transition: "width 360ms cubic-bezier(0.16,1,0.3,1)",
      }} />
    </div>
  );
}

function SummaryCard({ label, value, sub, muted, color }) {
  return (
    <div style={{
      background: "var(--bx-paper)",
      border: "1px solid var(--bx-line)",
      borderRadius: 12,
      padding: "16px 18px",
    }}>
      <div style={{
        fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase",
        color: "var(--bx-ink-3)", fontWeight: 600,
      }}>{label}</div>
      <div style={{
        fontFamily: "'Bebas Neue', sans-serif", fontSize: 32, marginTop: 6, fontWeight: 400,
        letterSpacing: "0.01em", lineHeight: 1,
        color: color || (muted ? "var(--bx-ink-3)" : "var(--bx-ink-1)"),
      }}>{value}</div>
      <div style={{ fontSize: 11, color: "var(--bx-ink-3)", marginTop: 4 }}>{sub}</div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Small helpers
// ──────────────────────────────────────────────────────────────
function selectStyle() {
  return {
    padding: "10px 12px", fontSize: 13,
    background: "var(--bx-paper)", border: "1px solid var(--bx-line)",
    borderRadius: 8, outline: "none", color: "var(--bx-ink-1)",
    fontFamily: "Inter, sans-serif", cursor: "pointer",
  };
}

function inputStyleRt() {
  return {
    width: "100%", padding: "8px 10px", fontSize: 13,
    border: "1px solid var(--bx-line)", borderRadius: 6,
    outline: "none", background: "var(--bx-bg)", color: "var(--bx-ink-1)",
    fontFamily: "Inter, sans-serif",
  };
}

function labelStyleRt() {
  return {
    fontSize: 11, letterSpacing: "0.16em", textTransform: "uppercase",
    color: "var(--bx-ink-3)", fontWeight: 600, marginBottom: 8,
  };
}

function smBtn(primary) {
  return {
    padding: "6px 12px", fontSize: 12, fontWeight: 600,
    background: primary ? "var(--bx-navy-700)" : "transparent",
    color: primary ? "#fff" : "var(--bx-ink-2)",
    border: primary ? "none" : "1px solid var(--bx-line)",
    borderRadius: 6, cursor: "pointer", fontFamily: "Inter, sans-serif",
  };
}

function Lbl({ label, children }) {
  return (
    <div>
      <div style={{
        fontSize: 10, letterSpacing: "0.14em", textTransform: "uppercase",
        color: "var(--bx-ink-3)", fontWeight: 600, marginBottom: 6,
      }}>{label}</div>
      {children}
    </div>
  );
}

Object.assign(window, { TransactionsView, BudgetsView, AccountsView, ReportsView });
