"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { categoriesFor, type Scope } from "@/lib/categories";
import { formatVND, periodKey } from "@/lib/finance";
import { CurrencyInput } from "@/components/CurrencyInput";
import { ICONS } from "@/lib/icons";

interface Row {
  id?: string;
  label: string;
  amount: string;
}

type RowsByCategory = Record<string, Row[]>;

function emptyRow(): Row {
  return { label: "", amount: "" };
}

function parseAmount(raw: string): number {
  return Number(raw.replace(/[^\d.-]/g, ""));
}

function currentPeriod(): string {
  return periodKey(new Date());
}

// Mặc định thông minh cho khoản MỚI thêm ở widget này: kỳ đang chọn đã qua/là hiện tại ->
// coi là Đã thực hiện (số thực); kỳ trong tương lai -> Dự kiến, không tự tính là đã thanh toán.
// Khoản đã có sẵn (đang hiển thị trong lưới) giữ nguyên trạng thái cũ, không đổi khi chỉ sửa số tiền.
function defaultRealized(period: string): boolean {
  return period <= currentPeriod();
}

export function QuickInputForm({ scope, period, onSaved }: { scope: Scope; period: string; onSaved: () => void }) {
  const [expanded, setExpanded] = useState(false);
  const [rows, setRows] = useState<RowsByCategory>({});
  const [removedIds, setRemovedIds] = useState<string[]>([]);
  const [balance, setBalance] = useState("");
  const [saving, setSaving] = useState(false);
  const [loading, setLoading] = useState(true);
  const [message, setMessage] = useState<string | null>(null);
  // Trạng thái + ngày áp dụng cho các khoản MỚI thêm trong lượt lưu này (khoản đã có sẵn trong
  // lưới giữ nguyên trạng thái cũ — chỉ trang Nhập số mới sửa trạng thái khoản đã lưu).
  const [newRealized, setNewRealized] = useState(() => defaultRealized(period));
  const [newRealizedTouched, setNewRealizedTouched] = useState(false);
  const [newDueDate, setNewDueDate] = useState("");
  const fileRef = useRef<HTMLInputElement>(null);

  const cats = categoriesFor(scope).filter((c) => !c.internal);
  const visible = expanded ? cats : cats.filter((c) => c.quickInput || (rows[c.key]?.some((r) => r.id)));

  const load = useCallback(async () => {
    setLoading(true);
    const res = await fetch(`/api/entries?scope=${scope}&period=${period}`);
    const json = await res.json();
    const grouped: RowsByCategory = {};
    for (const cat of cats) grouped[cat.key] = [];
    for (const e of json.entries as { id: string; category: string; label: string; amount: number; realized: boolean }[]) {
      if (!e.realized) continue;
      if (!grouped[e.category]) grouped[e.category] = [];
      grouped[e.category].push({ id: e.id, label: e.label, amount: String(e.amount) });
    }
    for (const key of Object.keys(grouped)) {
      if (grouped[key].length === 0) grouped[key] = [emptyRow()];
    }
    setRows(grouped);
    setRemovedIds([]);
    setLoading(false);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [scope, period]);

  useEffect(() => {
    load();
    setNewRealizedTouched(false);
    setNewRealized(defaultRealized(period));
    setNewDueDate("");
  }, [load, period]);

  function updateRow(catKey: string, idx: number, field: "label" | "amount", value: string) {
    setRows((prev) => {
      const list = [...(prev[catKey] ?? [])];
      list[idx] = { ...list[idx], [field]: value };
      return { ...prev, [catKey]: list };
    });
  }

  function addRow(catKey: string) {
    setRows((prev) => ({ ...prev, [catKey]: [...(prev[catKey] ?? []), emptyRow()] }));
  }

  function removeRow(catKey: string, idx: number) {
    setRows((prev) => {
      const list = [...(prev[catKey] ?? [])];
      const [removed] = list.splice(idx, 1);
      if (removed?.id) setRemovedIds((ids) => [...ids, removed.id!]);
      if (list.length === 0) list.push(emptyRow());
      return { ...prev, [catKey]: list };
    });
  }

  function categoryTotal(catKey: string): number {
    return (rows[catKey] ?? []).reduce((s, r) => {
      const n = parseAmount(r.amount);
      return s + (Number.isFinite(n) ? n : 0);
    }, 0);
  }

  async function save() {
    setSaving(true);
    setMessage(null);
    try {
      for (const id of removedIds) {
        await fetch(`/api/entries/${id}`, { method: "DELETE" });
      }
      for (const cat of cats) {
        for (const row of rows[cat.key] ?? []) {
          const amount = parseAmount(row.amount);
          if (!row.amount || !Number.isFinite(amount)) continue;
          if (row.id) {
            // Khoản đã có sẵn trong lưới (chỉ nạp khi realized=true) — chỉ cập nhật số tiền/tên,
            // KHÔNG đổi trạng thái đã lưu để tránh ghi trùng do đổi khoá upsert (scope/period/category/label/realized).
            await fetch(`/api/entries/${row.id}`, {
              method: "PATCH",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({ amount, label: row.label.trim() }),
            });
          } else {
            await fetch("/api/entries", {
              method: "POST",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({
                scope,
                period,
                category: cat.key,
                label: row.label.trim(),
                amount,
                realized: newRealized,
                dueDate: newDueDate ? new Date(newDueDate).toISOString() : undefined,
              }),
            });
          }
        }
      }
      if (balance !== "") {
        const amount = parseAmount(balance);
        if (Number.isFinite(amount)) {
          await fetch("/api/balance", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ scope, asOfDate: new Date().toISOString(), amount }),
          });
        }
      }
      setMessage("Đã cập nhật số liệu.");
      await load();
      onSaved();
    } finally {
      setSaving(false);
    }
  }

  async function handleCsv(file: File) {
    const text = await file.text();
    const lines = text.split(/\r?\n/).filter(Boolean);
    setRows((prev) => {
      const next: RowsByCategory = { ...prev };
      for (const line of lines) {
        const parts = line.split(",").map((p) => p.trim());
        if (parts.length < 2) continue;
        const [rawKey, a, b] = parts;
        const label = parts.length >= 3 ? a : "";
        const rawAmount = parts.length >= 3 ? b : a;
        const cat = cats.find((c) => c.key === rawKey.toUpperCase() || c.label.toLowerCase() === rawKey.toLowerCase());
        if (!cat || !rawAmount) continue;
        const list = next[cat.key] ? [...next[cat.key]] : [];
        const existingIdx = list.findIndex((r) => r.label === label);
        if (existingIdx >= 0) list[existingIdx] = { ...list[existingIdx], amount: rawAmount };
        else list.push({ label, amount: rawAmount });
        next[cat.key] = list.filter((r) => r.label !== "" || r.amount !== "");
      }
      return next;
    });
    setMessage(`Đã nạp dữ liệu từ ${file.name}, kiểm tra lại rồi bấm Cập nhật số liệu.`);
  }

  return (
    <div className="card p-5">
      <div className="mb-1 flex items-center justify-between">
        <div className="flex items-center gap-2 font-bold text-slate-800">
          <ICONS.zap size={18} strokeWidth={1.75} className="text-slate-400" /> Nhập số nhanh
        </div>
        <button onClick={() => setExpanded((e) => !e)} className="text-xs font-medium text-teal-600 hover:underline">
          {expanded ? "Thu gọn" : "Mở rộng danh mục"}
        </button>
      </div>
      <p className="mb-2 text-xs text-slate-400">
        Nhập số trực tiếp, hoặc bấm &ldquo;+ Thêm khoản&rdquo; để chia nhỏ từng hàng mục thành nhiều khoản con tự đặt tên.
      </p>
      <div className="mb-4 flex flex-wrap items-center gap-2 rounded-lg bg-slate-50 p-2.5">
        <span className="text-[11px] font-medium text-slate-500">Khoản mới thêm ở đây là:</span>
        <div className="flex overflow-hidden rounded-lg border border-slate-200">
          <button
            type="button"
            onClick={() => {
              setNewRealized(true);
              setNewRealizedTouched(true);
            }}
            className={`px-2.5 py-1 text-[11px] font-semibold ${newRealized ? "bg-teal-500 text-white" : "bg-white text-slate-500"}`}
          >
            Đã thực hiện
          </button>
          <button
            type="button"
            onClick={() => {
              setNewRealized(false);
              setNewRealizedTouched(true);
            }}
            className={`px-2.5 py-1 text-[11px] font-semibold ${!newRealized ? "bg-amber-500 text-white" : "bg-white text-slate-500"}`}
          >
            Dự kiến
          </button>
        </div>
        <label className="flex items-center gap-1.5 text-[11px] text-slate-500">
          Ngày thực hiện/đến hạn (tuỳ chọn)
          <input
            type="date"
            value={newDueDate}
            onChange={(e) => {
              const v = e.target.value;
              setNewDueDate(v);
              if (!newRealizedTouched) setNewRealized(defaultRealized(v ? v.slice(0, 7) : period));
            }}
            className="rounded-md border border-slate-200 px-1.5 py-1 text-[11px] text-slate-600"
          />
        </label>
      </div>
      {loading ? (
        <div className="py-6 text-center text-sm text-slate-400">Đang tải...</div>
      ) : (
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
          {visible.map((cat) => {
            const list = rows[cat.key] ?? [emptyRow()];
            const total = categoryTotal(cat.key);
            return (
              <div key={cat.key} className="rounded-xl border border-slate-100 p-3">
                <div className="mb-2 flex items-center justify-between">
                  <span className="text-xs font-semibold text-slate-600">{cat.label}</span>
                  {total > 0 && <span className="text-xs font-semibold text-teal-600">{formatVND(total)}</span>}
                </div>
                <div className="flex flex-col gap-1.5">
                  {list.map((row, idx) => (
                    <div key={row.id ?? `new-${idx}`} className="flex items-center gap-1.5">
                      <input
                        type="text"
                        placeholder={idx === 0 && list.length === 1 ? "Tên khoản (tuỳ chọn)" : "VD: Tiền nhà"}
                        value={row.label}
                        onChange={(e) => updateRow(cat.key, idx, "label", e.target.value)}
                        className="w-1/2 rounded-lg border border-slate-200 px-2.5 py-1.5 text-xs text-slate-700 focus:border-teal-400 focus:outline-none"
                      />
                      <CurrencyInput
                        value={row.amount}
                        onChange={(v) => updateRow(cat.key, idx, "amount", v)}
                        className="flex-1 rounded-lg border border-slate-200 px-2.5 py-1.5 text-xs text-slate-700 focus:border-teal-400 focus:outline-none"
                      />
                      <button
                        onClick={() => removeRow(cat.key, idx)}
                        className="shrink-0 rounded px-1.5 py-1 text-xs text-slate-300 hover:bg-rose-50 hover:text-rose-500"
                        title="Xoá khoản này"
                      >
                        <ICONS.close size={13} strokeWidth={1.75} />
                      </button>
                    </div>
                  ))}
                </div>
                <button onClick={() => addRow(cat.key)} className="mt-1.5 text-[11px] font-medium text-teal-600 hover:underline">
                  + Thêm khoản
                </button>
              </div>
            );
          })}
          <label className="text-xs text-slate-500">
            Số dư hiện tại
            <CurrencyInput
              value={balance}
              onChange={setBalance}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm text-slate-700 focus:border-teal-400 focus:outline-none"
            />
          </label>
        </div>
      )}
      <div className="mt-4 flex flex-wrap items-center gap-3">
        <button
          onClick={save}
          disabled={saving || loading}
          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..." : "+ Cập nhật số liệu"}
        </button>
        <button
          onClick={() => fileRef.current?.click()}
          className="flex items-center gap-1.5 rounded-lg border border-slate-200 px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50"
        >
          <ICONS.refresh size={15} strokeWidth={1.75} /> Nhập nhanh từ Excel/CSV
        </button>
        <input
          ref={fileRef}
          type="file"
          accept=".csv"
          className="hidden"
          onChange={(e) => e.target.files?.[0] && handleCsv(e.target.files[0])}
        />
        {message && <span className="text-xs text-teal-600">{message}</span>}
      </div>
    </div>
  );
}
