"use client";

// Form "Thêm khoản thu/chi" + lịch tự động — bám sát mockup "Option 1: Đơn giản – Nhanh nhất".
// Lưu ý kiến trúc: mỗi lần lưu chỉ ghi 1 dòng MonthlyEntry (period = tháng của ngày đến hạn),
// cycle/dueDate/endDate chỉ là METADATA để tính lịch xem trước (nextOccurrences) — không tự sinh
// thêm bản ghi cho các kỳ tương lai, nên không có rủi ro trùng dữ liệu khi sửa/lưu lại.
import { useCallback, useEffect, useState } from "react";
import { categoriesFor, type Scope } from "@/lib/categories";
import { CYCLE_OPTIONS, type Cycle, cycleLabel, formatVND, nextOccurrences, periodKey } from "@/lib/finance";
import { CurrencyInput } from "@/components/CurrencyInput";
import { ICONS } from "@/lib/icons";

interface EntryRow {
  id: string;
  scope: string;
  period: string;
  category: string;
  label: string;
  amount: number;
  realized: boolean;
  cycle: string;
  dueDate: string | null;
  endDate: string | null;
}

interface FormState {
  id: string | null;
  flow: "INFLOW" | "OUTFLOW";
  category: string;
  label: string;
  amount: string;
  cycle: Cycle;
  dueDate: string;
  endDate: string;
  note: string;
  realized: boolean;
  realizedTouched: boolean;
}

function todayISO() {
  return new Date().toISOString().slice(0, 10);
}

// Cảnh báo khi người dùng gõ nhầm số tiền vào ô TÊN khoản con (ô này không tự format dấu
// chấm vì là text tự do) — tránh lặp lại lỗi "nhập số bị mất dấu chấm phân cách".
function looksLikeAmount(label: string): boolean {
  return /^\d{4,}$/.test(label.trim());
}

// Mặc định thông minh: ngày đến hạn <= hôm nay -> coi là ĐÃ THỰC HIỆN (tiền đã vào/ra thật),
// ngày trong tương lai -> DỰ KIẾN (chưa thu/chưa chi) cho tới khi người dùng tự xác nhận.
// Đây là điểm gốc gây lỗi Dashboard/Agent trước đây: form luôn gửi realized=true bất kể ngày,
// nên "dự kiến" và "đã thực nhận/đã chi" bị trộn lẫn trong mọi phép tính dòng tiền.
function defaultRealized(dueDate: string): boolean {
  if (!dueDate) return true;
  return dueDate <= todayISO();
}

function emptyForm(category: string, flow: "INFLOW" | "OUTFLOW"): FormState {
  const dueDate = todayISO();
  return { id: null, flow, category, label: "", amount: "", cycle: "MONTHLY", dueDate, endDate: "", note: "", realized: defaultRealized(dueDate), realizedTouched: false };
}

export function EntryForm({ scope }: { scope: Scope }) {
  const cats = categoriesFor(scope).filter((c) => !c.internal);
  const inflowCats = cats.filter((c) => c.flow === "INFLOW");
  const outflowCats = cats.filter((c) => c.flow === "OUTFLOW");

  const [form, setForm] = useState<FormState>(emptyForm(outflowCats[0]?.key ?? "", "OUTFLOW"));
  const [advanced, setAdvanced] = useState(false);
  const [entries, setEntries] = useState<EntryRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [tab, setTab] = useState<"ALL" | "INFLOW" | "OUTFLOW">("ALL");
  const [visibleCount, setVisibleCount] = useState(10);

  const load = useCallback(async () => {
    setLoading(true);
    const res = await fetch(`/api/entries?scope=${scope}`);
    const json = await res.json();
    setEntries(json.entries);
    setLoading(false);
  }, [scope]);

  useEffect(() => {
    load();
    setForm(emptyForm(outflowCats[0]?.key ?? "", "OUTFLOW"));
    setVisibleCount(10);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [scope]);

  function flowCats(flow: "INFLOW" | "OUTFLOW") {
    return flow === "INFLOW" ? inflowCats : outflowCats;
  }

  function setFlow(flow: "INFLOW" | "OUTFLOW") {
    const list = flowCats(flow);
    setForm((f) => ({ ...f, flow, category: list[0]?.key ?? "" }));
  }

  async function save(keepOpen: boolean) {
    if (!form.category || !form.amount || !form.dueDate) {
      setMessage("Thiếu danh mục, số tiền hoặc ngày đến hạn.");
      return;
    }
    setSaving(true);
    setMessage(null);
    try {
      const period = periodKey(new Date(form.dueDate));
      const payload = {
        scope,
        period,
        category: form.category,
        label: form.label.trim(),
        amount: Number(form.amount),
        realized: form.realized,
        cycle: form.cycle,
        dueDate: new Date(form.dueDate).toISOString(),
        endDate: form.endDate ? new Date(form.endDate).toISOString() : undefined,
        note: form.note || undefined,
      };
      const res = form.id
        ? await fetch(`/api/entries/${form.id}`, {
            method: "PATCH",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(payload),
          })
        : await fetch("/api/entries", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(payload),
          });
      if (!res.ok) {
        const err = await res.json().catch(() => null);
        setMessage(err?.error && typeof err.error === "string" ? err.error : "Không lưu được khoản này.");
        return;
      }
      setMessage("Đã lưu khoản.");
      await load();
      setForm(keepOpen ? emptyForm(form.category, form.flow) : emptyForm(outflowCats[0]?.key ?? "", "OUTFLOW"));
    } finally {
      setSaving(false);
    }
  }

  function editRow(e: EntryRow) {
    const cat = cats.find((c) => c.key === e.category);
    setForm({
      id: e.id,
      flow: cat?.flow ?? "OUTFLOW",
      category: e.category,
      label: e.label,
      amount: String(e.amount),
      cycle: (e.cycle as Cycle) ?? "ONCE",
      dueDate: e.dueDate ? e.dueDate.slice(0, 10) : todayISO(),
      endDate: e.endDate ? e.endDate.slice(0, 10) : "",
      note: "",
      realized: e.realized,
      realizedTouched: true,
    });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function duplicateRow(e: EntryRow) {
    const cat = cats.find((c) => c.key === e.category);
    setForm({
      id: null,
      flow: cat?.flow ?? "OUTFLOW",
      category: e.category,
      label: e.label ? `${e.label} (bản sao)` : "",
      amount: String(e.amount),
      cycle: (e.cycle as Cycle) ?? "ONCE",
      dueDate: todayISO(),
      endDate: e.endDate ? e.endDate.slice(0, 10) : "",
      note: "",
      realized: defaultRealized(todayISO()),
      realizedTouched: false,
    });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  async function removeRow(id: string) {
    await fetch(`/api/entries/${id}`, { method: "DELETE" });
    load();
  }

  const selectedCat = cats.find((c) => c.key === form.category);
  const previewOccurrences =
    form.dueDate && form.amount
      ? nextOccurrences({
          dueDate: new Date(form.dueDate),
          cycle: form.cycle,
          endDate: form.endDate ? new Date(form.endDate) : null,
          count: 4,
        })
      : [];

  const filtered = entries
    .filter((e) => {
      if (tab === "ALL") return true;
      const cat = cats.find((c) => c.key === e.category);
      return cat?.flow === tab;
    })
    .filter((e) => {
      if (!search.trim()) return true;
      const q = search.trim().toLowerCase();
      const cat = cats.find((c) => c.key === e.category);
      return e.label.toLowerCase().includes(q) || (cat?.label ?? "").toLowerCase().includes(q);
    })
    .sort((a, b) => (b.dueDate ?? b.period).localeCompare(a.dueDate ?? a.period));

  const countAll = entries.length;
  const countInflow = entries.filter((e) => cats.find((c) => c.key === e.category)?.flow === "INFLOW").length;
  const countOutflow = entries.filter((e) => cats.find((c) => c.key === e.category)?.flow === "OUTFLOW").length;

  return (
    <div className="grid grid-cols-1 gap-6 lg:grid-cols-12">
      <div className="card p-5 lg:col-span-7">
        <div className="mb-4 flex items-center gap-2 font-bold text-slate-800">
          <ICONS.nhapSo size={18} strokeWidth={1.75} className="text-slate-400" /> Thêm khoản thu / chi
        </div>

        <div className="mb-4 grid grid-cols-2 gap-2">
          <button
            onClick={() => setFlow("INFLOW")}
            className={`flex items-center justify-center gap-1.5 rounded-lg border py-2 text-sm font-semibold ${
              form.flow === "INFLOW" ? "border-teal-500 bg-teal-50 text-teal-700" : "border-slate-200 text-slate-500"
            }`}
          >
            <ICONS.inflow size={16} strokeWidth={1.75} /> Thu nhập (Tiền vào)
          </button>
          <button
            onClick={() => setFlow("OUTFLOW")}
            className={`flex items-center justify-center gap-1.5 rounded-lg border py-2 text-sm font-semibold ${
              form.flow === "OUTFLOW" ? "border-rose-400 bg-rose-50 text-rose-600" : "border-slate-200 text-slate-500"
            }`}
          >
            <ICONS.outflow size={16} strokeWidth={1.75} /> Chi phí (Tiền ra)
          </button>
        </div>

        <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
          <label className="text-xs text-slate-500">
            Danh mục
            <select
              value={form.category}
              onChange={(e) => setForm({ ...form, category: e.target.value })}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700"
            >
              {flowCats(form.flow).map((c) => (
                <option key={c.key} value={c.key}>
                  {c.label}
                </option>
              ))}
            </select>
          </label>
          <label className="text-xs text-slate-500">
            Khoản con (tuỳ chọn, chỉ là TÊN — không nhập số tiền ở đây)
            <input
              value={form.label}
              onChange={(e) => setForm({ ...form, label: e.target.value })}
              placeholder={`VD: ${selectedCat?.label ?? "tên khoản"}`}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700"
            />
            {looksLikeAmount(form.label) && (
              <span className="mt-1 flex items-center gap-1 text-[11px] font-medium text-amber-600">
                <ICONS.alert size={12} strokeWidth={2} /> Đây là ô TÊN khoản con — số tiền xin nhập ở ô &quot;Số tiền (VND)&quot; bên dưới.
              </span>
            )}
          </label>

          <label className="text-xs text-slate-500">
            Số tiền (VND)
            <CurrencyInput
              value={form.amount}
              onChange={(v) => setForm({ ...form, amount: v })}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700"
            />
          </label>
          <label className="text-xs text-slate-500">
            Chu kỳ
            <select
              value={form.cycle}
              onChange={(e) => setForm({ ...form, cycle: e.target.value as Cycle })}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700"
            >
              {CYCLE_OPTIONS.map((c) => (
                <option key={c.value} value={c.value}>
                  {c.label}
                </option>
              ))}
            </select>
          </label>

          <label className="text-xs text-slate-500">
            Ngày nhận / đến hạn
            <input
              type="date"
              value={form.dueDate}
              onChange={(e) => {
                const dueDate = e.target.value;
                setForm((f) => ({ ...f, dueDate, realized: f.realizedTouched ? f.realized : defaultRealized(dueDate) }));
              }}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700"
            />
          </label>
          <label className="text-xs text-slate-500">
            Ngày kết thúc (tuỳ chọn)
            <input
              type="date"
              value={form.endDate}
              onChange={(e) => setForm({ ...form, endDate: e.target.value })}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700"
            />
          </label>
        </div>

        <div className="mt-3 grid grid-cols-2 gap-2">
          <button
            type="button"
            onClick={() => setForm((f) => ({ ...f, realized: true, realizedTouched: true }))}
            className={`flex items-center justify-center gap-1.5 rounded-lg border py-2 text-xs font-semibold ${
              form.realized ? "border-teal-500 bg-teal-50 text-teal-700" : "border-slate-200 text-slate-500"
            }`}
          >
            Đã thực hiện (tiền đã vào/ra thật)
          </button>
          <button
            type="button"
            onClick={() => setForm((f) => ({ ...f, realized: false, realizedTouched: true }))}
            className={`flex items-center justify-center gap-1.5 rounded-lg border py-2 text-xs font-semibold ${
              !form.realized ? "border-amber-400 bg-amber-50 text-amber-700" : "border-slate-200 text-slate-500"
            }`}
          >
            Dự kiến (chưa thu/chưa chi)
          </button>
        </div>

        <button onClick={() => setAdvanced((a) => !a)} className="mt-3 flex items-center gap-1 text-xs font-medium text-teal-600">
          <ICONS.chevronDown size={14} strokeWidth={1.75} className={`transition ${advanced ? "rotate-180" : ""}`} />
          Tùy chọn nâng cao
        </button>
        {advanced && (
          <label className="mt-2 block text-xs text-slate-500">
            Ghi chú (tuỳ chọn)
            <input
              value={form.note}
              onChange={(e) => setForm({ ...form, note: e.target.value })}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700"
            />
          </label>
        )}

        <div className="mt-4 flex flex-wrap items-center gap-3">
          <button
            onClick={() => save(false)}
            disabled={saving}
            className="rounded-lg bg-teal-500 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-teal-600 disabled:opacity-50"
          >
            {saving ? "Đang lưu..." : form.id ? "Lưu thay đổi" : "Lưu khoản"}
          </button>
          {!form.id && (
            <button
              onClick={() => save(true)}
              disabled={saving}
              className="rounded-lg border border-slate-200 px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50 disabled:opacity-50"
            >
              Lưu và thêm khoản khác
            </button>
          )}
          {form.id && (
            <button
              onClick={() => setForm(emptyForm(outflowCats[0]?.key ?? "", "OUTFLOW"))}
              className="rounded-lg border border-slate-200 px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50"
            >
              Hủy sửa
            </button>
          )}
          {message && <span className="text-xs text-teal-600">{message}</span>}
        </div>
      </div>

      <div className="card p-5 lg:col-span-5">
        <div className="mb-3 flex items-center gap-2 font-bold text-slate-800">
          <ICONS.calendar size={18} strokeWidth={1.75} className="text-slate-400" /> Tóm tắt khoản đã nhập
        </div>
        <dl className="flex flex-col gap-2 text-sm">
          <Row label="Danh mục" value={selectedCat?.label ?? "—"} />
          <Row label="Khoản con" value={form.label || "—"} />
          <Row label="Số tiền mỗi kỳ" value={form.amount ? formatVND(Number(form.amount)) : "—"} strong />
          <Row label="Chu kỳ" value={cycleLabel(form.cycle)} />
          <Row label="Ngày nhận / đến hạn" value={form.dueDate ? new Date(form.dueDate).toLocaleDateString("vi-VN") : "—"} />
          <Row label="Ngày kết thúc" value={form.endDate ? new Date(form.endDate).toLocaleDateString("vi-VN") : "Không giới hạn"} />
          <Row label="Trạng thái" value={form.realized ? "Đã thực hiện" : "Dự kiến"} />
        </dl>

        {previewOccurrences.length > 1 && (
          <div className="mt-4 rounded-lg bg-teal-50 p-3">
            <div className="mb-2 text-xs font-semibold text-teal-700">Các lần thu/chi tiếp theo (dự kiến)</div>
            <div className="flex flex-col gap-1.5 text-xs">
              {previewOccurrences.map((d, i) => (
                <div key={i} className="flex items-center justify-between">
                  <span className="text-slate-600">{d.toLocaleDateString("vi-VN")}</span>
                  <span className="font-semibold text-slate-700">{formatVND(Number(form.amount))}</span>
                </div>
              ))}
              {form.cycle !== "ONCE" && <div className="text-slate-400">…</div>}
            </div>
          </div>
        )}
      </div>

      <div className="card overflow-hidden lg:col-span-12">
        <div className="flex flex-wrap items-center justify-between gap-3 border-b border-slate-100 p-4">
          <div className="flex items-center gap-2 font-bold text-slate-800">
            <ICONS.nhapSo size={18} strokeWidth={1.75} className="text-slate-400" /> Danh sách khoản đã nhập
          </div>
          <div className="flex items-center gap-2">
            <div className="inline-flex rounded-lg bg-slate-100 p-1 text-xs">
              {[
                ["ALL", `Tất cả (${countAll})`],
                ["INFLOW", `Thu nhập (${countInflow})`],
                ["OUTFLOW", `Chi phí (${countOutflow})`],
              ].map(([k, l]) => (
                <button
                  key={k}
                  onClick={() => setTab(k as typeof tab)}
                  className={`rounded-md px-3 py-1.5 font-semibold ${tab === k ? "bg-white text-teal-600 shadow-sm" : "text-slate-500"}`}
                >
                  {l}
                </button>
              ))}
            </div>
            <div className="relative">
              <ICONS.search size={14} strokeWidth={1.75} className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-slate-300" />
              <input
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="Tìm kiếm khoản..."
                className="rounded-lg border border-slate-200 py-1.5 pl-8 pr-3 text-xs text-slate-600"
              />
            </div>
          </div>
        </div>
        <table className="w-full text-sm">
          <thead className="bg-slate-50 text-xs uppercase text-slate-400">
            <tr>
              <th className="px-4 py-3 text-left">Danh mục</th>
              <th className="px-4 py-3 text-left">Khoản con</th>
              <th className="px-4 py-3 text-left">Số tiền</th>
              <th className="px-4 py-3 text-left">Chu kỳ</th>
              <th className="px-4 py-3 text-left">Ngày đến hạn</th>
              <th className="px-4 py-3 text-left">Ngày kết thúc</th>
              <th className="px-4 py-3 text-left">Trạng thái</th>
              <th className="px-4 py-3 text-right">Hành động</th>
            </tr>
          </thead>
          <tbody>
            {!loading &&
              filtered.slice(0, visibleCount).map((e) => {
                const cat = cats.find((c) => c.key === e.category);
                return (
                  <tr key={e.id} className="border-t border-slate-50">
                    <td className="px-4 py-3 text-slate-700">{cat?.label ?? e.category}</td>
                    <td className="px-4 py-3 text-slate-400">{e.label || "—"}</td>
                    <td className="px-4 py-3 font-semibold">{formatVND(e.amount)}</td>
                    <td className="px-4 py-3 text-slate-500">{cycleLabel(e.cycle)}</td>
                    <td className="px-4 py-3 text-slate-500">{e.dueDate ? new Date(e.dueDate).toLocaleDateString("vi-VN") : "—"}</td>
                    <td className="px-4 py-3 text-slate-500">{e.endDate ? new Date(e.endDate).toLocaleDateString("vi-VN") : "Không giới hạn"}</td>
                    <td className="px-4 py-3">
                      <span
                        className={`rounded-full px-2 py-0.5 text-xs font-medium ${
                          e.realized ? "bg-teal-50 text-teal-600" : "bg-amber-50 text-amber-600"
                        }`}
                      >
                        {e.realized ? "Đã thực hiện" : "Dự kiến"}
                      </span>
                    </td>
                    <td className="px-4 py-3">
                      <div className="flex items-center justify-end gap-1">
                        <button onClick={() => editRow(e)} title="Sửa" className="rounded p-1.5 text-slate-400 hover:bg-slate-100 hover:text-teal-600">
                          <ICONS.edit size={14} strokeWidth={1.75} />
                        </button>
                        <button onClick={() => duplicateRow(e)} title="Sao chép" className="rounded p-1.5 text-slate-400 hover:bg-slate-100 hover:text-teal-600">
                          <ICONS.copy size={14} strokeWidth={1.75} />
                        </button>
                        <button onClick={() => removeRow(e.id)} title="Xóa" className="rounded p-1.5 text-slate-400 hover:bg-rose-50 hover:text-rose-500">
                          <ICONS.delete size={14} strokeWidth={1.75} />
                        </button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            {!loading && filtered.length === 0 && (
              <tr>
                <td colSpan={8} className="px-4 py-6 text-center text-sm text-slate-400">
                  Chưa có khoản nào khớp.
                </td>
              </tr>
            )}
          </tbody>
        </table>
        {filtered.length > visibleCount && (
          <div className="border-t border-slate-100 p-3 text-center">
            <button onClick={() => setVisibleCount((n) => n + 10)} className="text-xs font-medium text-teal-600 hover:underline">
              Xem thêm ({filtered.length - visibleCount})
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

function Row({ label, value, strong }: { label: string; value: string; strong?: boolean }) {
  return (
    <div className="flex items-center justify-between">
      <dt className="text-slate-400">{label}</dt>
      <dd className={strong ? "text-base font-bold text-slate-800" : "font-medium text-slate-600"}>{value}</dd>
    </div>
  );
}
