"use client";
import { useEffect, useState } from "react";
import {
  Home,
  Settings,
  Bell,
  Wallet,
  Camera,
  ShoppingCart,
  PiggyBank,
  Users,
  History,
  Trash2,
  Save,
  Plus,
  ScanLine,
  TrendingUp,
  CalendarClock,
  ReceiptText,
  Image as ImageIcon,
  FileText,
} from "lucide-react";

const API = process.env.NEXT_PUBLIC_API_URL || "http://b2jdev.com.br:4000";
const money = (v: any) =>
  (Number(v) || 0).toLocaleString("pt-BR", {
    style: "currency",
    currency: "BRL",
  });
const nv = (v: any) => Number(String(v ?? 0).replace(",", ".")) || 0;
const authHeaders = (token: string) => ({ Authorization: `Bearer ${token}` });
const jsonHeaders = (token: string) => ({
  "Content-Type": "application/json",
  Authorization: `Bearer ${token}`,
});

export default function Page() {
  const [token, setToken] = useState("");
  const [email, setEmail] = useState("admin@tudocerto.local");
  const [password, setPassword] = useState("admin123");
  const [tab, setTab] = useState("dashboard");
  const [dash, setDash] = useState<any>(null);
  const [categories, setCategories] = useState<any[]>([]);
  const [expenses, setExpenses] = useState<any[]>([]);
  const [receipts, setReceipts] = useState<any[]>([]);
  const [bills, setBills] = useState<any[]>([]);
  const [shopping, setShopping] = useState<any[]>([]);
  const [members, setMembers] = useState<any[]>([]);
  const [audit, setAudit] = useState<any[]>([]);
  const [month, setMonth] = useState(new Date().toISOString().slice(0, 7));
  async function login() {
    const r = await fetch(`${API}/auth/login`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, password }),
    });
    const d = await r.json();
    if (d.token) {
      localStorage.setItem("tc_token", d.token);
      setToken(d.token);
    } else alert("Login inválido");
  }
  async function load(t = token) {
    if (!t) return;
    const h = authHeaders(t);
    const [d, c, e, r, b, s, m, a] = await Promise.all([
      fetch(`${API}/dashboard?month=${month}`, { headers: h }).then((x) =>
        x.json(),
      ),
      fetch(`${API}/categories`).then((x) => x.json()),
      fetch(`${API}/expenses?month=${month}`, { headers: h }).then((x) =>
        x.json(),
      ),
      fetch(`${API}/receipts`, { headers: h }).then((x) => x.json()),
      fetch(`${API}/bill-reminders`, { headers: h }).then((x) => x.json()),
      fetch(`${API}/shopping-sessions`, { headers: h }).then((x) => x.json()),
      fetch(`${API}/members`, { headers: h }).then((x) => x.json()),
      fetch(`${API}/audit-logs`, { headers: h }).then((x) => x.json()),
    ]);
    setDash(d);
    setCategories(c);
    setExpenses(e);
    setReceipts(r);
    setBills(b);
    setShopping(s);
    setMembers(m);
    setAudit(a);
  }
  useEffect(() => {
    const t = localStorage.getItem("tc_token") || "";
    setToken(t);
    if (t) load(t);
  }, []);
  useEffect(() => {
    if (token) load(token);
  }, [token, month]);
  if (!token)
    return (
      <main className="min-h-screen grid place-items-center bg-gradient-to-br from-emerald-50 to-slate-100 p-4">
        <div className="card max-w-md w-full">
          <h1 className="text-4xl font-black">TudoCerto</h1>
          <p className="text-slate-500 mt-2">
            Controle familiar por mês, OCR, cofre e investimentos.
          </p>
          <div className="grid gap-3 mt-6">
            <Field label="E-mail">
              <input
                className="input"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
              />
            </Field>
            <Field label="Senha">
              <input
                className="input"
                type="password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
              />
            </Field>
            <button className="btn bg-emerald-600 text-white" onClick={login}>
              Entrar
            </button>
            <small className="text-slate-400">
              Demo: admin@tudocerto.local / admin123
            </small>
          </div>
        </div>
      </main>
    );
  const tabs: any[] = [
    ["dashboard", "Dashboard", Home],
    ["settings", "Parametrização", Settings],
    ["bills", "Contas", Bell],
    ["expenses", "Gastos", Wallet],
    ["ocr", "Cupons OCR", Camera],
    ["shopping", "Mercado", ShoppingCart],
    ["vault", "Cofre", PiggyBank],
    ["invest", "Investimentos", TrendingUp],
    ["report", "Relatório do Mês", FileText],
    ["family", "Família", Users],
    ["audit", "Logs", History],
  ];
  return (
    <main className="min-h-screen bg-[#f6f8fb]">
      <header className="sticky top-0 z-20 bg-white/90 backdrop-blur border-b border-slate-100">
        <div className="max-w-7xl mx-auto p-4 flex flex-wrap gap-3 items-center justify-between">
          <div>
            <h1 className="text-2xl font-black">TudoCerto</h1>
            <p className="text-xs text-slate-500">
              Mês em controle: <b>{dash?.month?.label || month}</b> •{" "}
              {new Date(dash?.month?.generatedAt || Date.now()).toLocaleString(
                "pt-BR",
              )}
            </p>
          </div>
          <div className="flex gap-2 items-end">
            <Field label="Mês">
              <input
                className="input"
                type="month"
                value={month}
                onChange={(e) => setMonth(e.target.value)}
              />
            </Field>
            <button
              onClick={() => {
                localStorage.removeItem("tc_token");
                setToken("");
              }}
              className="btn bg-slate-900 text-white"
            >
              Sair
            </button>
          </div>
        </div>
      </header>
      <div className="max-w-7xl mx-auto p-4 grid lg:grid-cols-[250px_1fr] gap-4">
        <nav className="card h-fit lg:sticky lg:top-24 grid grid-cols-2 lg:grid-cols-1 gap-2">
          {tabs.map(([id, label, Icon]) => (
            <button
              key={id}
              onClick={() => setTab(id)}
              className={`btn justify-start ${tab === id ? "bg-emerald-600 text-white" : "bg-slate-50"}`}
            >
              <Icon size={17} />
              {label}
            </button>
          ))}
        </nav>
        <section>
          {tab === "dashboard" && <Dashboard dash={dash} />}{" "}
          {tab === "settings" && (
            <SettingsPage
              token={token}
              dash={dash}
              categories={categories}
              reload={() => load()}
            />
          )}{" "}
          {tab === "bills" && (
            <Bills token={token} bills={bills} reload={() => load()} />
          )}{" "}
          {tab === "expenses" && (
            <Expenses
              token={token}
              expenses={expenses}
              categories={categories}
              reload={() => load()}
            />
          )}{" "}
          {tab === "ocr" && (
            <OCR
              token={token}
              categories={categories}
              receipts={receipts}
              reload={() => load()}
            />
          )}{" "}
          {tab === "shopping" && (
            <Shopping token={token} shopping={shopping} reload={() => load()} />
          )}{" "}
          {tab === "vault" && (
            <Vault token={token} dash={dash} reload={() => load()} />
          )}{" "}
          {tab === "invest" && <Investments token={token} dash={dash} />}{" "}
          {tab === "report" && <MonthlyReport token={token} month={month} />}{" "}
          {tab === "family" && (
            <Family token={token} members={members} reload={() => load()} />
          )}{" "}
          {tab === "audit" && <AuditLogs audit={audit} />}
        </section>
      </div>
    </main>
  );
}

function Field({ label, help, children }: any) {
  return (
    <label className="block">
      <span className="label">{label}</span>
      {children}
      {help && <small className="help">{help}</small>}
    </label>
  );
}
function UploadGuidance({ type }: any) {
  const isBill = type === "bill";
  const isLabel = type === "label";
  return (
    <div className="guidance mt-3">
      <p className="font-black text-slate-800">Como fotografar para o OCR funcionar melhor</p>
      <ul className="list-disc pl-5 mt-2 text-slate-700 space-y-1">
        <li>Use boa iluminação, sem sombra forte e sem reflexo sobre o papel.</li>
        <li>Enquadre o documento inteiro, mantendo texto e valores bem nítidos.</li>
        {!isLabel && <li>Em cupons grandes, envie por partes: cabeçalho, bloco de itens e total.</li>}
        {isBill && <li>Para contas agendadas, capture obrigatoriamente o código de barras ou linha digitável.</li>}
        {isLabel && <li>Na etiqueta de mercado, aproxime a câmera do nome do produto e do preço na mesma foto.</li>}
      </ul>
    </div>
  );
}

function Bar({ used, limit }: any) {
  const p = limit ? Math.round((used / limit) * 100) : 0;
  const cls = p > 100 ? "bg-rose-500" : "bg-emerald-500";
  return (
    <div>
      <div className="bar">
        <div className={cls} style={{ width: `${Math.min(p, 100)}%` }} />
      </div>
      <small className={p > 100 ? "text-rose-600" : "text-emerald-700"}>
        {p}% usado
      </small>
    </div>
  );
}

function Dashboard({ dash }: any) {
  const b = dash?.budget || {};
  const close = dash?.monthlyClose || {};
  return (
    <div className="grid md:grid-cols-3 gap-4">
      <div className="card md:col-span-2 bg-gradient-to-br from-slate-950 to-emerald-900">
        <p className="text-emerald-200">Resultado de {dash?.month?.label}</p>
        <h2 className="text-4xl font-black mt-2">
          {money(b.used)} / {money(b.monthly)}
        </h2>
        <div className="mt-4 h-3 bg-white/20 rounded-full overflow-hidden">
          <div
            className={
              b.percent > 100 ? "h-full bg-rose-400" : "h-full bg-emerald-300"
            }
            style={{ width: `${Math.min(b.percent || 0, 100)}%` }}
          />
        </div>
        <div className="grid grid-cols-3 gap-3 mt-5 text-sm">
          <span>
            <b>{money(b.income)}</b>
            <br />
            renda
          </span>
          <span>
            <b>{money(b.remaining)}</b>
            <br />
            saldo
          </span>
          <span>
            <b>{close.status}</b>
            <br />
            fechamento
          </span>
        </div>
      </div>
      <div className="card">
        <h3 className="font-black text-xl">Consultoria mensal</h3>
        {dash?.consultant?.plan?.map((p: string, i: number) => (
          <p key={i} className="text-sm text-slate-600 mt-2">
            • {p}
          </p>
        ))}
        {dash?.consultant?.alerts?.map((a: string, i: number) => (
          <p key={i} className="alert mt-2">
            {a}
          </p>
        ))}
      </div>
      <div className="card md:col-span-3">
        <h3 className="font-black mb-3">Tetos por categoria</h3>
        <div className="grid md:grid-cols-3 gap-3">
          {dash?.categoryBudgets
            ?.filter((c: any) => c.enabled && c.monthlyLimit > 0)
            .map((c: any) => (
              <div key={c.id} className="rounded-2xl bg-slate-50 p-3">
                <div className="flex justify-between">
                  <b>{c.name}</b>
                  <span>{money(c.used)}</span>
                </div>
                <Bar used={c.used} limit={c.monthlyLimit} />
                <small>
                  Teto: {money(c.monthlyLimit)} • Restante: {money(c.remaining)}
                </small>
              </div>
            ))}
        </div>
      </div>
      <div className="card md:col-span-2">
        <h3 className="font-black mb-3">Fechamento e correção de rota</h3>
        <p className="text-slate-600">
          Status: <b>{close.status}</b>
        </p>
        <p className="text-slate-600">
          Potencial de sobra após gastos e cofre:{" "}
          <b>{money(close.savingsPotential)}</b>
        </p>
        <p className="text-sm mt-3">
          Ajuste categorias acima do teto, negocie vencimentos com desconto à
          vista e mantenha aportes do cofre no início do mês.
        </p>
      </div>
      <div className="card">
        <h3 className="font-black mb-3">Cofre</h3>
        <p className="text-3xl font-black">
          {money(dash?.vault?.currentAmount)}
        </p>
        <p className="text-slate-500">
          Meta: {money(dash?.vault?.targetAmount)}
        </p>
      </div>
      <div className="card md:col-span-3">
        <h3 className="font-black mb-3">Últimos gastos do mês</h3>
        <div className="grid md:grid-cols-2 gap-2">
          {dash?.recentExpenses?.map((e: any) => (
            <div
              key={e.id}
              className="rounded-2xl bg-slate-50 p-3 flex justify-between"
            >
              <span>
                {e.description}
                <br />
                <small>
                  {e.category.name} •{" "}
                  {new Date(e.inputtedAt || e.date).toLocaleString("pt-BR")} •{" "}
                  {e.user?.name}
                </small>
              </span>
              <b>{money(e.amount)}</b>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function SettingsPage({ token, dash, categories, reload }: any) {
  const [income, setIncome] = useState(0),
    [budget, setBudget] = useState(0),
    [rows, setRows] = useState<any[]>([]),
    [newCat, setNewCat] = useState({ name: "", monthlyLimit: "" });
  useEffect(() => {
    setIncome(dash?.family?.monthlyIncome || 0);
    setBudget(dash?.family?.monthlyBudget || 0);
    setRows(dash?.categoryBudgets || []);
  }, [dash]);
  async function save() {
    await fetch(`${API}/settings`, {
      method: "PATCH",
      headers: jsonHeaders(token),
      body: JSON.stringify({
        monthlyIncome: income,
        monthlyBudget: budget,
        categoryBudgets: rows,
      }),
    });
    reload();
  }
  async function addCat() {
    if (!newCat.name) return;
    await fetch(`${API}/categories`, {
      method: "POST",
      headers: jsonHeaders(token),
      body: JSON.stringify({
        name: newCat.name,
        monthlyLimit: nv(newCat.monthlyLimit),
      }),
    });
    setNewCat({ name: "", monthlyLimit: "" });
    reload();
  }
  return (
    <div className="grid gap-4">
      <div className="card">
        <h2 className="text-2xl font-black">Parametrização mensal</h2>
        <div className="grid md:grid-cols-3 gap-3 mt-4">
          <Field label="Ganhos mensais familiares">
            <input
              className="input"
              type="number"
              value={income}
              onChange={(e) => setIncome(nv(e.target.value))}
            />
          </Field>
          <Field label="Teto total de gastos">
            <input
              className="input"
              type="number"
              value={budget}
              onChange={(e) => setBudget(nv(e.target.value))}
            />
          </Field>
          <button
            className="btn bg-emerald-600 text-white self-end"
            onClick={save}
          >
            <Save size={16} />
            Salvar
          </button>
        </div>
      </div>
      <div className="card">
        <h3 className="font-black">Criar categoria personalizada</h3>
        <div className="grid md:grid-cols-3 gap-3 mt-3">
          <Field label="Nome">
            <input
              className="input"
              placeholder="Financiamento, acordo judicial..."
              value={newCat.name}
              onChange={(e) => setNewCat({ ...newCat, name: e.target.value })}
            />
          </Field>
          <Field label="Teto mensal">
            <input
              className="input"
              value={newCat.monthlyLimit}
              onChange={(e) =>
                setNewCat({ ...newCat, monthlyLimit: e.target.value })
              }
            />
          </Field>
          <button
            onClick={addCat}
            className="btn bg-slate-900 text-white self-end"
          >
            <Plus size={16} />
            Adicionar
          </button>
        </div>
      </div>
      <div className="card">
        <h3 className="font-black mb-3">Tetos por categoria</h3>
        <div className="grid md:grid-cols-2 gap-2">
          {rows.map((r: any, i: number) => (
            <div
              key={r.id || r.categoryId}
              className="grid grid-cols-[1fr_110px_70px] gap-2 items-end bg-slate-50 p-3 rounded-2xl"
            >
              <b>{r.name}</b>
              <Field label="Teto">
                <input
                  className="input"
                  value={r.monthlyLimit}
                  onChange={(e) => {
                    const cp = [...rows];
                    cp[i] = { ...r, monthlyLimit: nv(e.target.value) };
                    setRows(cp);
                  }}
                />
              </Field>
              <label className="text-xs">
                <input
                  type="checkbox"
                  checked={r.enabled}
                  onChange={(e) => {
                    const cp = [...rows];
                    cp[i] = { ...r, enabled: e.target.checked };
                    setRows(cp);
                  }}
                />{" "}
                ativo
              </label>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function Expenses({ token, expenses, categories, reload }: any) {
  const [form, setForm] = useState({
    description: "",
    amount: "",
    category: "Mercado",
    date: "",
  });
  async function save() {
    if (!form.description.trim()) return alert("Informe a descrição do gasto");
    if (!form.amount) return alert("Informe o valor do gasto");
    await fetch(`${API}/expenses`, {
      method: "POST",
      headers: jsonHeaders(token),
      body: JSON.stringify(form),
    });
    setForm({ description: "", amount: "", category: "Mercado", date: "" });
    reload();
  }
  async function patch(e: any, body: any) {
    await fetch(`${API}/expenses/${e.id}`, {
      method: "PATCH",
      headers: jsonHeaders(token),
      body: JSON.stringify({ ...e, ...body }),
    });
    reload();
  }
  async function del(id: string) {
    if (!confirm("Excluir este gasto?")) return;
    await fetch(`${API}/expenses/${id}`, {
      method: "DELETE",
      headers: authHeaders(token),
    });
    reload();
  }
  return (
    <div className="grid gap-4">
      <div className="card">
        <h2 className="text-2xl font-black">Adicionar gasto manual</h2>
        <p className="text-slate-500 mt-1">
          Mantido como antes: você pode lançar gastos manualmente e eles entram
          no mês selecionado.
        </p>
        <div className="grid md:grid-cols-5 gap-3 mt-4 items-end">
          <Field label="Descrição do gasto">
            <input
              className="input"
              placeholder="Ex.: Padaria, gasolina, escola"
              value={form.description}
              onChange={(e) =>
                setForm({ ...form, description: e.target.value })
              }
            />
          </Field>
          <Field label="Valor total do gasto">
            <input
              className="input"
              placeholder="Ex.: 129.90"
              value={form.amount}
              onChange={(e) => setForm({ ...form, amount: e.target.value })}
            />
          </Field>
          <Field label="Categoria do gasto">
            <select
              className="input"
              value={form.category}
              onChange={(e) => setForm({ ...form, category: e.target.value })}
            >
              {categories.map((c: any) => (
                <option key={c.id}>{c.name}</option>
              ))}
            </select>
          </Field>
          <Field label="Data/hora">
            <input
              className="input"
              type="datetime-local"
              value={form.date}
              onChange={(e) => setForm({ ...form, date: e.target.value })}
            />
          </Field>
          <button onClick={save} className="btn bg-emerald-600 text-white">
            <Plus size={18} />
            Salvar gasto
          </button>
        </div>
      </div>
      <div className="card">
        <h2 className="text-2xl font-black">Gastos do mês</h2>
        <p className="text-slate-500">
          Lista de tudo o que já foi gasto, com edição e exclusão.
        </p>
        <div className="grid gap-3 mt-4">
          {expenses?.map((e: any) => (
            <div key={e.id} className="rounded-2xl bg-slate-50 p-3 border">
              <div className="grid md:grid-cols-5 gap-2 items-end">
                <Field label="Descrição">
                  <input
                    className="input"
                    defaultValue={e.description}
                    onBlur={(x) => patch(e, { description: x.target.value })}
                  />
                </Field>
                <Field label="Valor">
                  <input
                    className="input"
                    type="number"
                    defaultValue={e.amount}
                    onBlur={(x) => patch(e, { amount: x.target.value })}
                  />
                </Field>
                <Field label="Categoria">
                  <select
                    className="input"
                    defaultValue={e.categoryId}
                    onChange={(x) => patch(e, { categoryId: x.target.value })}
                  >
                    {categories.map((c: any) => (
                      <option key={c.id} value={c.id}>
                        {c.name}
                      </option>
                    ))}
                  </select>
                </Field>
                <Field label="Data">
                  <input
                    className="input"
                    type="datetime-local"
                    defaultValue={String(e.date).slice(0, 16)}
                    onBlur={(x) => patch(e, { date: x.target.value })}
                  />
                </Field>
                <button
                  className="btn bg-rose-50 text-rose-700"
                  onClick={() => del(e.id)}
                >
                  <Trash2 size={16} />
                  Excluir
                </button>
              </div>
              <small className="text-slate-500">
                Inputado por {e.user?.name} em{" "}
                {new Date(e.inputtedAt || e.date).toLocaleString("pt-BR")} •{" "}
                {e.source}
              </small>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function OCR({ token, categories, receipts, reload }: any) {
  const [cat, setCat] = useState("Mercado"),
    [loading, setLoading] = useState(false);
  async function send(file: any) {
    setLoading(true);
    const fd = new FormData();
    fd.append("file", file);
    fd.append("category", cat);
    await fetch(`${API}/ocr/receipt`, {
      method: "POST",
      headers: authHeaders(token),
      body: fd,
    });
    await reload();
    setLoading(false);
  }
  async function patchReceipt(r: any, items: any[]) {
    await fetch(`${API}/receipts/${r.id}`, {
      method: "PATCH",
      headers: jsonHeaders(token),
      body: JSON.stringify({
        description: r.description,
        categoryId: r.categoryId,
        items,
      }),
    });
    reload();
  }
  async function delItem(id: string) {
    await fetch(`${API}/receipt-items/${id}`, {
      method: "DELETE",
      headers: authHeaders(token),
    });
    reload();
  }
  return (
    <div className="grid gap-4">
      <div className="card">
        <h2 className="text-2xl font-black">OCR de cupom limpo</h2>
        <p className="text-slate-500">
          O OCR foi ajustado para cupom térmico/matricial, letras pequenas e leitura baseada no cabeçalho das colunas de itens. Revise os itens extraídos antes de salvar as correções.
        </p>
        <UploadGuidance type="receipt" />
        <div className="grid md:grid-cols-2 gap-3 mt-3">
          <Field label="Categoria do cupom">
            <select
              className="input"
              value={cat}
              onChange={(e) => setCat(e.target.value)}
            >
              {categories.map((c: any) => (
                <option key={c.id}>{c.name}</option>
              ))}
            </select>
          </Field>
          <Field label="Foto do cupom">
            <input
              className="input"
              type="file"
              accept="image/*"
              capture="environment"
              onChange={(e) => e.target.files?.[0] && send(e.target.files[0])}
            />
          </Field>
        </div>
        {loading && (
          <p className="alert mt-3">
            <ScanLine size={16} />
            Extraindo itens...
          </p>
        )}
      </div>
      {receipts?.map((r: any) => (
        <ReceiptEditor
          key={r.id}
          r={r}
          categories={categories}
          patchReceipt={patchReceipt}
          delItem={delItem}
        />
      ))}
    </div>
  );
}
function ReceiptEditor({ r, categories, patchReceipt, delItem }: any) {
  const [items, setItems] = useState(r.items || []);
  return (
    <div className="card">
      <div className="flex justify-between gap-3">
        <div>
          <h3 className="font-black">{r.description}</h3>
          <p className="text-sm text-slate-500">
            {r.category?.name} • Total recalculado: {money(r.amount)}
          </p>
        </div>
        <button
          className="btn bg-emerald-600 text-white"
          onClick={() => patchReceipt(r, items)}
        >
          Salvar correções
        </button>
      </div>
      <div className="overflow-auto mt-3">
        <table className="w-full text-sm">
          <thead>
            <tr>
              <th>Item</th>
              <th>Qtd</th>
              <th>Unit.</th>
              <th>Total</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {items.map((it: any, i: number) => (
              <tr key={it.id} className="border-t">
                <td>
                  <input
                    className="input"
                    value={it.name}
                    onChange={(e) => {
                      const cp = [...items];
                      cp[i] = { ...it, name: e.target.value };
                      setItems(cp);
                    }}
                  />
                </td>
                <td>
                  <input
                    className="input"
                    value={it.quantity}
                    onChange={(e) => {
                      const q = nv(e.target.value);
                      const cp = [...items];
                      cp[i] = {
                        ...it,
                        quantity: q,
                        total: q * nv(it.unitPrice),
                      };
                      setItems(cp);
                    }}
                  />
                </td>
                <td>
                  <input
                    className="input"
                    value={it.unitPrice}
                    onChange={(e) => {
                      const u = nv(e.target.value);
                      const cp = [...items];
                      cp[i] = {
                        ...it,
                        unitPrice: u,
                        total: nv(it.quantity) * u,
                      };
                      setItems(cp);
                    }}
                  />
                </td>
                <td>{money(it.total)}</td>
                <td>
                  <button
                    className="btn bg-rose-50 text-rose-700"
                    onClick={() => delItem(it.id)}
                  >
                    Excluir
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function Bills({ token, bills, reload }: any) {
  const [form, setForm] = useState({
    title: "",
    amount: "",
    dueDate: "",
    remindAt: "",
    notification: "EMAIL_SMS",
    description: "",
    barcode: "",
  });
  const [loading, setLoading] = useState(false);
  async function save() {
    await fetch(`${API}/bill-reminders`, {
      method: "POST",
      headers: jsonHeaders(token),
      body: JSON.stringify(form),
    });
    setForm({
      title: "",
      amount: "",
      dueDate: "",
      remindAt: "",
      notification: "EMAIL_SMS",
      description: "",
      barcode: "",
    });
    reload();
  }
  async function ocr(file: any) {
    setLoading(true);
    const fd = new FormData();
    fd.append("file", file);
    fd.append("notification", form.notification);
    await fetch(`${API}/bill-reminders/ocr`, {
      method: "POST",
      headers: authHeaders(token),
      body: fd,
    });
    await reload();
    setLoading(false);
  }
  async function patch(b: any, body: any) {
    await fetch(`${API}/bill-reminders/${b.id}`, {
      method: "PATCH",
      headers: jsonHeaders(token),
      body: JSON.stringify({ ...b, ...body }),
    });
    reload();
  }
  async function del(id: string) {
    if (!confirm("Excluir esta conta agendada?")) return;
    await fetch(`${API}/bill-reminders/${id}`, {
      method: "DELETE",
      headers: authHeaders(token),
    });
    reload();
  }
  return (
    <div className="grid lg:grid-cols-[380px_1fr] gap-4">
      <div className="card">
        <h2 className="text-2xl font-black">Agendar conta</h2>
        <div className="grid gap-3 mt-3">
          <Field label="Nome">
            <input
              className="input"
              value={form.title}
              onChange={(e) => setForm({ ...form, title: e.target.value })}
            />
          </Field>
          <Field label="Valor">
            <input
              className="input"
              value={form.amount}
              onChange={(e) => setForm({ ...form, amount: e.target.value })}
            />
          </Field>
          <Field label="Código de barras / linha digitável">
            <input
              className="input"
              value={form.barcode}
              onChange={(e) => setForm({ ...form, barcode: e.target.value })}
            />
          </Field>
          <Field label="Vencimento">
            <input
              className="input"
              type="datetime-local"
              value={form.dueDate}
              onChange={(e) => setForm({ ...form, dueDate: e.target.value })}
            />
          </Field>
          <Field label="Alerta">
            <input
              className="input"
              type="datetime-local"
              value={form.remindAt}
              onChange={(e) => setForm({ ...form, remindAt: e.target.value })}
            />
          </Field>
          <button className="btn bg-emerald-600 text-white" onClick={save}>
            Salvar conta
          </button>
          <UploadGuidance type="bill" />
          <Field label="Foto da conta para OCR e arquivo">
            <input
              className="input"
              type="file"
              accept="image/*"
              capture="environment"
              onChange={(e) => e.target.files?.[0] && ocr(e.target.files[0])}
            />
          </Field>
          {loading && (
            <p className="alert">
              <ScanLine size={16} />
              Lendo e salvando imagem...
            </p>
          )}
        </div>
      </div>
      <div className="card">
        <h3 className="font-black text-xl">Contas agendadas</h3>
        <div className="grid gap-3 mt-4">
          {bills?.map((b: any) => (
            <div key={b.id} className="rounded-2xl bg-slate-50 p-3">
              <div className="grid md:grid-cols-4 gap-2 items-end">
                <Field label="Conta">
                  <input
                    className="input"
                    defaultValue={b.title}
                    onBlur={(e) => patch(b, { title: e.target.value })}
                  />
                </Field>
                <Field label="Valor">
                  <input
                    className="input"
                    defaultValue={b.amount}
                    onBlur={(e) => patch(b, { amount: e.target.value })}
                  />
                </Field>
                <Field label="Código de barras">
                  <input
                    className="input"
                    defaultValue={b.barcode || ""}
                    onBlur={(e) => patch(b, { barcode: e.target.value })}
                  />
                </Field>
                <Field label="Vencimento">
                  <input
                    className="input"
                    type="datetime-local"
                    defaultValue={String(b.dueDate).slice(0, 16)}
                    onBlur={(e) => patch(b, { dueDate: e.target.value })}
                  />
                </Field>
              </div>
              {b.imageBase64 && (
                <details className="mt-2">
                  <summary className="cursor-pointer text-sm text-emerald-700 flex gap-1">
                    <ImageIcon size={16} />
                    Ver imagem salva
                  </summary>
                  <img
                    className="mt-2 max-h-96 rounded-xl"
                    src={`data:${b.imageMime};base64,${b.imageBase64}`}
                  />
                </details>
              )}
              <div className="mt-3 flex flex-wrap items-center justify-between gap-2">
                <small className="text-slate-500">
                  Criada por {b.createdBy?.name} em{" "}
                  {new Date(b.createdAt).toLocaleString("pt-BR")}
                </small>
                <button className="btn bg-rose-50 text-rose-700" onClick={() => del(b.id)}>
                  <Trash2 size={16} />
                  Excluir conta
                </button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function Shopping({ token, shopping, reload }: any) {
  const [name, setName] = useState("Compra de mercado");
  const [sid, setSid] = useState("");
  const [item, setItem] = useState({ product: "", quantity: 1, price: "" });
  const [loading, setLoading] = useState(false);
  const current = shopping?.find((s: any) => s.id === sid) || shopping?.[0];
  useEffect(() => {
    if (shopping?.[0] && !sid) setSid(shopping[0].id);
  }, [shopping]);
  async function start() {
    const r = await fetch(`${API}/shopping-sessions`, {
      method: "POST",
      headers: jsonHeaders(token),
      body: JSON.stringify({ name }),
    });
    const d = await r.json();
    setSid(d.id);
    reload();
  }
  async function add() {
    let active = current?.id || sid;
    if (!active) {
      const r = await fetch(`${API}/shopping-sessions`, {
        method: "POST",
        headers: jsonHeaders(token),
        body: JSON.stringify({ name }),
      });
      const d = await r.json();
      active = d.id;
      setSid(active);
    }
    await fetch(`${API}/shopping-sessions/${active}/items`, {
      method: "POST",
      headers: jsonHeaders(token),
      body: JSON.stringify(item),
    });
    setItem({ product: "", quantity: 1, price: "" });
    reload();
  }
  async function ocr(file: any) {
    let active = current?.id || sid;
    if (!active) {
      const r = await fetch(`${API}/shopping-sessions`, {
        method: "POST",
        headers: jsonHeaders(token),
        body: JSON.stringify({ name }),
      });
      const d = await r.json();
      active = d.id;
      setSid(active);
    }
    setLoading(true);
    const fd = new FormData();
    fd.append("file", file);
    await fetch(`${API}/shopping-sessions/${active}/ocr-price`, {
      method: "POST",
      headers: authHeaders(token),
      body: fd,
    });
    await reload();
    setLoading(false);
  }
  async function patchItem(it: any, body: any) {
    await fetch(`${API}/shopping-items/${it.id}`, {
      method: "PATCH",
      headers: jsonHeaders(token),
      body: JSON.stringify({ ...it, ...body }),
    });
    reload();
  }
  async function delItem(id: string) {
    await fetch(`${API}/shopping-items/${id}`, {
      method: "DELETE",
      headers: authHeaders(token),
    });
    reload();
  }
  return (
    <div className="grid lg:grid-cols-[380px_1fr] gap-4">
      <div className="grid gap-4">
        <div className="card">
          <h2 className="text-2xl font-black">Sessão de mercado</h2>
          <Field label="Nome da sessão">
            <input
              className="input"
              value={name}
              onChange={(e) => setName(e.target.value)}
            />
          </Field>
          <button
            className="btn bg-emerald-600 text-white mt-2"
            onClick={start}
          >
            <ShoppingCart size={18} />
            Abrir sessão
          </button>
          <Field label="Sessões salvas">
            <select
              className="input"
              value={current?.id || ""}
              onChange={(e) => setSid(e.target.value)}
            >
              {shopping?.map((s: any) => (
                <option key={s.id} value={s.id}>
                  {s.name} - {money(s.total)}
                </option>
              ))}
            </select>
          </Field>
          <UploadGuidance type="label" />
          <Field label="Foto da etiqueta de preço">
            <input
              className="input"
              type="file"
              accept="image/*"
              capture="environment"
              onChange={(e) => e.target.files?.[0] && ocr(e.target.files[0])}
            />
          </Field>
          {loading && (
            <p className="alert">
              <ScanLine size={16} />
              Lendo etiqueta de preço...
            </p>
          )}
        </div>
        <div className="card">
          <h3 className="font-black">Adicionar item manualmente</h3>
          <div className="grid gap-2 mt-3">
            <Field label="Produto">
              <input
                className="input"
                value={item.product}
                onChange={(e) => setItem({ ...item, product: e.target.value })}
              />
            </Field>
            <Field label="Quantidade">
              <input
                className="input"
                type="number"
                value={item.quantity}
                onChange={(e) =>
                  setItem({ ...item, quantity: nv(e.target.value) })
                }
              />
            </Field>
            <Field label="Preço unitário">
              <input
                className="input"
                value={item.price}
                onChange={(e) => setItem({ ...item, price: e.target.value })}
              />
            </Field>
            <button className="btn bg-slate-900 text-white" onClick={add}>
              <Plus size={18} />
              Adicionar à compra
            </button>
          </div>
        </div>
      </div>
      <div className="card">
        <h3 className="font-black text-xl">
          {current?.name || "Nenhuma sessão"}
        </h3>
        <p className="text-4xl font-black text-emerald-700 my-3">
          {money(current?.total)}
        </p>
        <div className="grid gap-2">
          {current?.items?.map((it: any) => (
            <div key={it.id} className="rounded-xl bg-slate-50 p-3">
              <div className="grid md:grid-cols-5 gap-2 items-end">
                <Field label="Produto">
                  <input
                    className="input"
                    defaultValue={it.product}
                    onBlur={(e) => patchItem(it, { product: e.target.value })}
                  />
                </Field>
                <Field label="Quantidade">
                  <input
                    className="input"
                    type="number"
                    defaultValue={it.quantity}
                    onBlur={(e) =>
                      patchItem(it, { quantity: nv(e.target.value) })
                    }
                  />
                </Field>
                <Field label="Preço">
                  <input
                    className="input"
                    type="number"
                    defaultValue={it.price}
                    onBlur={(e) => patchItem(it, { price: nv(e.target.value) })}
                  />
                </Field>
                <div>
                  <span className="label">Total</span>
                  <b>{money(it.total)}</b>
                </div>
                <button
                  className="btn bg-rose-50 text-rose-700"
                  onClick={() => delItem(it.id)}
                >
                  <Trash2 size={16} />
                  Excluir
                </button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function Vault({ token, dash, reload }: any) {
  const [amount, setAmount] = useState(""),
    [note, setNote] = useState(""),
    [target, setTarget] = useState(0),
    [monthly, setMonthly] = useState(0);
  useEffect(() => {
    setTarget(dash?.vault?.targetAmount || 0);
    setMonthly(dash?.vault?.monthlyDeposit || 0);
  }, [dash]);
  async function tx(type: string) {
    await fetch(`${API}/vault/${type}`, {
      method: "POST",
      headers: jsonHeaders(token),
      body: JSON.stringify({ amount, note }),
    });
    setAmount("");
    setNote("");
    reload();
  }
  async function save() {
    await fetch(`${API}/vault`, {
      method: "PATCH",
      headers: jsonHeaders(token),
      body: JSON.stringify({
        targetAmount: target,
        monthlyDeposit: monthly,
        riskProfile: dash?.vault?.riskProfile || "MISTO",
      }),
    });
    reload();
  }
  return (
    <div className="grid lg:grid-cols-[380px_1fr] gap-4">
      <div className="card">
        <h2 className="text-2xl font-black">Cofre</h2>
        <p className="text-4xl font-black text-emerald-700">
          {money(dash?.vault?.currentAmount)}
        </p>
        <div className="grid gap-3 mt-4">
          <Field label="Meta do cofre">
            <input
              className="input"
              value={target}
              onChange={(e) => setTarget(nv(e.target.value))}
            />
          </Field>
          <Field label="Aporte planejado mensal">
            <input
              className="input"
              value={monthly}
              onChange={(e) => setMonthly(nv(e.target.value))}
            />
          </Field>
          <button className="btn bg-slate-900 text-white" onClick={save}>
            Atualizar meta
          </button>
          <Field label="Valor do aporte/retirada">
            <input
              className="input"
              value={amount}
              onChange={(e) => setAmount(e.target.value)}
            />
          </Field>
          <Field label="Observação">
            <input
              className="input"
              value={note}
              onChange={(e) => setNote(e.target.value)}
            />
          </Field>
          <div className="flex gap-2">
            <button
              className="btn bg-emerald-600 text-white"
              onClick={() => tx("deposit")}
            >
              Aportar
            </button>
            <button
              className="btn bg-rose-50 text-rose-700"
              onClick={() => tx("withdraw")}
            >
              Retirar
            </button>
          </div>
        </div>
      </div>
      <div className="grid gap-4">
        <div className="card">
          <h3 className="font-black">Consultoria do cofre</h3>
          {dash?.consultant?.plan?.map((p: string, i: number) => (
            <p key={i} className="text-sm mt-2">
              • {p}
            </p>
          ))}
          <p className="text-sm mt-3 text-slate-600">
            Para adiantar metas: buscar descontos em contas pagas à vista,
            reduzir categorias estouradas e direcionar a diferença imediatamente
            para o cofre.
          </p>
        </div>
        <div className="card">
          <h3 className="font-black">Composição e movimentações</h3>
          {dash?.vault?.transactions?.map((t: any) => (
            <p key={t.id} className="border-b py-2 flex justify-between">
              <span>
                {t.type} • {t.note}
                <br />
                <small>{new Date(t.createdAt).toLocaleString("pt-BR")}</small>
              </span>
              <b
                className={t.amount < 0 ? "text-rose-600" : "text-emerald-700"}
              >
                {money(t.amount)}
              </b>
            </p>
          ))}
        </div>
      </div>
    </div>
  );
}

function Investments({ token, dash }: any) {
  const [months, setMonths] = useState(12),
    [data, setData] = useState<any>(null);
  async function calc(m = months) {
    setMonths(m);
    const r = await fetch(
      `${API}/investments?months=${m}&monthlyDeposit=${dash?.vault?.monthlyDeposit || 500}&currentAmount=${dash?.vault?.currentAmount || 0}`,
      { headers: authHeaders(token) },
    );
    setData(await r.json());
  }
  useEffect(() => {
    if (token) calc(months);
  }, [token, dash]);
  const opts = [1, 12, 24, 36, 48, 60, 84];
  return (
    <div className="grid gap-4">
      <div className="card">
        <h2 className="text-2xl font-black">
          Investimentos por prazo e cenário
        </h2>
        <p className="text-slate-500">
          Simulações educacionais com cenários de baixo, médio, misto e alto
          risco.
        </p>
        <div className="flex flex-wrap gap-2 mt-4">
          {opts.map((m) => (
            <button
              key={m}
              onClick={() => calc(m)}
              className={`btn ${months === m ? "bg-emerald-600 text-white" : "bg-slate-100"}`}
            >
              {m === 1 ? "1 mês" : `${m / 12} anos`}
            </button>
          ))}
        </div>
      </div>
      <div className="grid md:grid-cols-2 gap-4">
        {data?.scenarios?.map((s: any) => (
          <div key={s.name} className="card">
            <h3 className="font-black">{s.name}</h3>
            <p className="text-sm text-slate-500">
              Risco: {s.risk} • Liquidez: {s.liquidity}
            </p>
            <p className="text-3xl font-black mt-3">
              {money(s.estimatedAmount)}
            </p>
            <p className="text-emerald-700">
              Ganho estimado: {money(s.estimatedGain)}
            </p>
            <p className="text-sm mt-3">{s.note}</p>
          </div>
        ))}
      </div>
      <div className="card">
        <h3 className="font-black">Fontes usadas na lógica</h3>
        {data?.references?.map((r: string, i: number) => (
          <p key={i} className="text-sm">
            • {r}
          </p>
        ))}
        <small className="text-slate-500">{data?.disclaimer}</small>
      </div>
    </div>
  );
}


function MonthlyReport({ token, month }: any) {
  const [report, setReport] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  async function generate() {
    setLoading(true);
    const r = await fetch(`${API}/monthly-report?month=${month}`, { headers: authHeaders(token) });
    setReport(await r.json());
    setLoading(false);
  }
  useEffect(() => { if (token) generate(); }, [token, month]);
  const s = report?.executiveSummary || {};
  return (
    <div className="grid gap-4">
      <div className="card bg-gradient-to-br from-slate-950 to-emerald-900 text-white">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <p className="text-emerald-200">Relatório financeiro mensal</p>
            <h2 className="text-3xl font-black">{report?.month?.label || month}</h2>
            <p className="text-sm text-white/70">Página web acionada por botão, com análise do mês até o momento.</p>
          </div>
          <button className="btn bg-white text-slate-900" onClick={generate}>
            <FileText size={18} />
            {loading ? "Gerando..." : "Gerar relatório completo"}
          </button>
        </div>
      </div>
      {report && (
        <>
          <div className="grid md:grid-cols-4 gap-4">
            <Kpi title="Renda familiar" value={money(s.income)} />
            <Kpi title="Gasto até agora" value={money(s.used)} />
            <Kpi title="Saldo orçamento" value={money(s.remainingBudget)} tone={s.remainingBudget < 0 ? "bad" : "good"} />
            <Kpi title="Caixa livre pós-cofre" value={money(s.freeCash)} tone={s.freeCash < 0 ? "bad" : "good"} />
          </div>
          <div className="card">
            <h3 className="font-black text-xl">Diagnóstico executivo</h3>
            <p className="mt-2 text-slate-600">Status do mês: <b>{s.status}</b>. Cofre atual: <b>{money(s.vaultCurrent)}</b> de meta <b>{money(s.vaultTarget)}</b>.</p>
            <div className="grid md:grid-cols-2 gap-3 mt-4">
              {(report.recommendations || []).map((x: string, i: number) => (
                <p key={i} className="rounded-2xl bg-emerald-50 text-emerald-900 p-3 text-sm">• {x}</p>
              ))}
            </div>
          </div>
          <div className="grid md:grid-cols-2 gap-4">
            <div className="card">
              <h3 className="font-black text-xl">Categorias críticas</h3>
              {(report.overLimit || []).length === 0 && (report.nearLimit || []).length === 0 && <p className="text-slate-500 mt-2">Nenhuma categoria crítica no momento.</p>}
              {[...(report.overLimit || []), ...(report.nearLimit || [])].map((c: any) => (
                <div key={c.id} className="rounded-2xl bg-slate-50 p-3 mt-2">
                  <div className="flex justify-between"><b>{c.name}</b><span>{money(c.used)} / {money(c.monthlyLimit)}</span></div>
                  <Bar used={c.used} limit={c.monthlyLimit} />
                </div>
              ))}
            </div>
            <div className="card">
              <h3 className="font-black text-xl">Maiores gastos</h3>
              {(report.topSpending || []).map((c: any) => (
                <div key={c.id} className="flex justify-between border-b py-2">
                  <span>{c.name}</span><b>{money(c.used)}</b>
                </div>
              ))}
            </div>
          </div>
          <div className="card">
            <h3 className="font-black text-xl">Plano de ação para corrigir rota</h3>
            <div className="overflow-auto mt-3">
              <table className="w-full text-sm">
                <thead><tr><th>Prioridade</th><th>Ação</th><th>Impacto esperado</th><th>Responsável</th></tr></thead>
                <tbody>
                  {(report.actionPlan || []).map((a: any, i: number) => (
                    <tr key={i} className="border-t"><td className="py-2"><b>{a.priority}</b></td><td>{a.action}</td><td>{a.expectedImpact}</td><td>{a.owner}</td></tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
          <div className="card">
            <h3 className="font-black text-xl">Cenários de investimento vinculados ao cofre</h3>
            <div className="grid md:grid-cols-3 gap-3 mt-3">
              {(report.investmentScenarios || []).slice(0,6).map((i: any) => (
                <div key={i.name} className="rounded-2xl bg-slate-50 p-3">
                  <b>{i.name}</b>
                  <p className="text-xs text-slate-500">Risco {i.risk} • {i.liquidity}</p>
                  <p className="text-xl font-black mt-2">{money(i.estimatedAmount)}</p>
                  <p className="text-sm text-emerald-700">Ganho estimado {money(i.estimatedGain)}</p>
                </div>
              ))}
            </div>
          </div>
          <div className="card">
            <h3 className="font-black text-xl">Últimos lançamentos usados na análise</h3>
            {(report.recentExpenses || []).map((e: any) => (
              <div key={e.id} className="flex justify-between border-b py-2 text-sm"><span>{e.description}<br/><small>{e.category?.name} • {new Date(e.date).toLocaleString("pt-BR")}</small></span><b>{money(e.amount)}</b></div>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function Kpi({ title, value, tone }: any) {
  const cls = tone === "bad" ? "text-rose-700" : tone === "good" ? "text-emerald-700" : "text-slate-900";
  return <div className="card"><p className="text-sm text-slate-500">{title}</p><p className={`text-2xl font-black ${cls}`}>{value}</p></div>;
}

function Family({ token, members, reload }: any) {
  const [m, setM] = useState({
    name: "",
    email: "",
    phone: "",
    role: "ADULTO",
    notifyEmail: true,
    notifySms: false,
    password: "123456",
  });
  async function add() {
    await fetch(`${API}/members`, {
      method: "POST",
      headers: jsonHeaders(token),
      body: JSON.stringify(m),
    });
    setM({
      name: "",
      email: "",
      phone: "",
      role: "ADULTO",
      notifyEmail: true,
      notifySms: false,
      password: "123456",
    });
    reload();
  }
  return (
    <div className="card">
      <h2 className="text-2xl font-black">Família</h2>
      <div className="grid md:grid-cols-4 gap-2 mt-3">
        <Field label="Nome">
          <input
            className="input"
            value={m.name}
            onChange={(e) => setM({ ...m, name: e.target.value })}
          />
        </Field>
        <Field label="E-mail">
          <input
            className="input"
            value={m.email}
            onChange={(e) => setM({ ...m, email: e.target.value })}
          />
        </Field>
        <Field label="Celular">
          <input
            className="input"
            value={m.phone}
            onChange={(e) => setM({ ...m, phone: e.target.value })}
          />
        </Field>
        <button
          className="btn bg-emerald-600 text-white self-end"
          onClick={add}
        >
          Adicionar
        </button>
      </div>
      <div className="grid gap-2 mt-4">
        {members?.map((u: any) => (
          <div
            key={u.id}
            className="rounded-xl bg-slate-50 p-3 flex justify-between"
          >
            <span>
              {u.name}
              <br />
              <small>
                {u.email} • {u.phone}
              </small>
            </span>
            <span>{u.role}</span>
          </div>
        ))}
      </div>
    </div>
  );
}
function AuditLogs({ audit }: any) {
  return (
    <div className="card">
      <h2 className="text-2xl font-black">Logs</h2>
      <div className="overflow-auto">
        <table className="w-full text-xs">
          <tbody>
            {audit?.map((a: any) => (
              <tr key={a.id} className="border-t">
                <td className="py-2">
                  {new Date(a.createdAt).toLocaleString("pt-BR")}
                </td>
                <td>
                  {a.userName}
                  <br />
                  {a.userEmail}
                </td>
                <td>
                  <b>{a.method}</b> {a.path}
                </td>
                <td>{a.statusCode}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
