"use client";

import { useEffect, useRef, useState, useCallback } from "react";
import {
  RefreshCw, Calendar, Building2, Coins, Search,
  Save, CheckCircle, AlertCircle, X, Plus, TrendingUp,
} from "lucide-react";

interface CurrencyOption {
  id: string;
  label: string;
}

interface CurrencyCard {
  code: string;
  currencyId: string;
  amount: string;
  isNew: boolean;
}

interface ParsedBalance {
  bankName: string;
  lastUpdated: string;
  cards: CurrencyCard[];
  allCurrencies: CurrencyOption[];
}

function parseBalanceHtml(html: string, existingCards?: CurrencyCard[]): ParsedBalance {
  if (typeof window === "undefined") {
    return { bankName: "", lastUpdated: "", cards: [], allCurrencies: [] };
  }
  const parser = new DOMParser();
  const doc = parser.parseFromString(html, "text/html");

  const bankName = doc.querySelector("h6 b")?.textContent?.trim() ?? "";
  const lastUpdated = doc.querySelector(".date")?.textContent?.trim() ?? "";

  const cards: CurrencyCard[] = [];
  doc.querySelectorAll(".lisiti-itm").forEach((row) => {
    const code = row.querySelector(".the-code")?.textContent?.trim() ?? "";
    const input = row.querySelector("input") as HTMLInputElement | null;
    const currencyId = input?.getAttribute("data-id") ?? "";
    const valueStr = input?.value ?? "0";
    if (code) cards.push({ code, currencyId, amount: String(parseFloat(valueStr) || 0), isNew: false });
  });

  if (existingCards) {
    existingCards
      .filter((c) => c.isNew && !cards.find((a) => a.code === c.code))
      .forEach((c) => cards.push({ ...c }));
  }

  const allCurrencies: CurrencyOption[] = [];
  doc.querySelectorAll("select[name='currency_id'] option").forEach((opt) => {
    const el = opt as HTMLOptionElement;
    allCurrencies.push({ id: el.value, label: el.text.trim() });
  });

  return { bankName, lastUpdated, cards, allCurrencies };
}

function formatAmount(value: string): string {
  const n = parseFloat(value);
  return isFinite(n)
    ? n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
    : value;
}

interface BankBalanceDetailProps {
  bankId: string;
  bankLabel: string;
}

export const BankBalanceDetail = ({ bankId, bankLabel }: BankBalanceDetailProps) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [parsed, setParsed] = useState<ParsedBalance | null>(null);
  const [cards, setCards] = useState<CurrencyCard[]>([]);
  const [saving, setSaving] = useState(false);
  const [saveStatus, setSaveStatus] = useState<"idle" | "success" | "error">("idle");
  const [saveMessage, setSaveMessage] = useState("");
  const [query, setQuery] = useState("");
  const [showDropdown, setShowDropdown] = useState(false);
  const searchRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    function handleOutside(e: MouseEvent) {
      if (searchRef.current && !searchRef.current.contains(e.target as Node)) {
        setShowDropdown(false);
      }
    }
    document.addEventListener("mousedown", handleOutside);
    return () => document.removeEventListener("mousedown", handleOutside);
  }, []);

  const fetchBalance = useCallback(async (existingCards?: CurrencyCard[]) => {
    const res = await fetch("/api/cash-balance/find-balance", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      credentials: "include",
      cache: "no-store",
      body: JSON.stringify({ bankid: Number(bankId) }),
    });
    if (!res.ok) throw new Error(`Request failed (${res.status})`);
    const json = await res.json();
    const html: string = json?.html ?? "";
    if (!html) throw new Error("No balance data returned");
    return parseBalanceHtml(html, existingCards);
  }, [bankId]);

  useEffect(() => {
    if (!bankId) return;
    let cancelled = false;
    setLoading(true);
    setError(null);
    setParsed(null);
    setCards([]);
    setQuery("");
    setSaveStatus("idle");

    fetchBalance()
      .then((p) => { if (!cancelled) { setParsed(p); setCards(p.cards); } })
      .catch((err) => { if (!cancelled) setError(err instanceof Error ? err.message : "Failed to load balance"); })
      .finally(() => { if (!cancelled) setLoading(false); });

    return () => { cancelled = true; };
  }, [bankId, fetchBalance]);

  const handleSaveAll = async () => {
    if (!cards.length) return;
    setSaving(true);
    setSaveStatus("idle");
    try {
      // Build payload matching the HTML form structure:
      // { b_id, currency: { [bankId]: { [currencyId]: amount } } }
      const currencyMap: Record<string, number> = {};
      cards.forEach((card) => {
        if (card.currencyId) {
          currencyMap[card.currencyId] = parseFloat(card.amount) || 0;
        }
      });

      const payload = {
        b_id: Number(bankId),
        currency: {
          [bankId]: currencyMap,
        },
      };

      const res = await fetch("/api/cash-balance/save-balance", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify(payload),
      });
      if (!res.ok) throw new Error(`Save failed (${res.status})`);

      setSaveStatus("success");
      setSaveMessage("All balances saved successfully!");
      const p = await fetchBalance(cards);
      setParsed(p);
      setCards(p.cards);
    } catch (err) {
      setSaveStatus("error");
      setSaveMessage(err instanceof Error ? err.message : "Failed to save");
    } finally {
      setSaving(false);
    }
  };

  const handleAddCurrency = (opt: CurrencyOption) => {
    setShowDropdown(false);
    setQuery("");
    if (cards.find((c) => c.code === opt.label)) return;
    setCards((prev) => [...prev, { code: opt.label, currencyId: opt.id, amount: "", isNew: true }]);
    setSaveStatus("idle");
  };

  if (loading) {
    return (
      <div className="rounded-2xl border border-slate-200/60 bg-white shadow-sm">
        {/* Skeleton header */}
        <div className="bg-gradient-to-r from-[#428B4D]/8 to-emerald-50/30 px-8 py-6 border-b border-slate-100">
          <div className="flex items-center gap-3">
            <div className="h-10 w-10 rounded-xl bg-slate-200 animate-pulse" />
            <div className="space-y-2">
              <div className="h-4 w-40 rounded bg-slate-200 animate-pulse" />
              <div className="h-3 w-24 rounded bg-slate-100 animate-pulse" />
            </div>
          </div>
        </div>
        <div className="p-8">
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
            {[1, 2, 3].map((i) => (
              <div key={i} className="rounded-xl border border-slate-100 bg-slate-50 p-4 space-y-3">
                <div className="h-3 w-12 rounded bg-slate-200 animate-pulse" />
                <div className="h-8 w-full rounded-lg bg-slate-100 animate-pulse" />
                <div className="h-3 w-20 rounded bg-slate-100 animate-pulse" />
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="rounded-2xl border border-red-100 bg-red-50/60 px-6 py-5 flex items-start gap-3">
        <AlertCircle className="h-5 w-5 text-red-500 mt-0.5 shrink-0" />
        <div>
          <p className="text-sm font-semibold text-red-700">Failed to load balance</p>
          <p className="text-xs text-red-500 mt-0.5">{error}</p>
        </div>
      </div>
    );
  }

  if (!parsed) return null;

  const existingCodes = new Set(cards.filter((c) => !c.isNew).map((c) => c.code));
  const filteredDropdown = parsed.allCurrencies.filter(
    (c) =>
      !existingCodes.has(c.label) &&
      !cards.find((card) => card.isNew && card.code === c.label) &&
      (query.trim() ? c.label.toLowerCase().includes(query.trim().toLowerCase()) : true)
  );

  const totalCurrencies = cards.length;
  const newCount = cards.filter((c) => c.isNew).length;

  return (
    <div className="rounded-2xl border border-slate-200/60 bg-white shadow-sm">

      {/* ── Header ────────────────────────────────────────────────── */}
      <div className="relative overflow-hidden rounded-t-2xl bg-gradient-to-br from-[#428B4D]/10 via-emerald-50/40 to-white border-b border-slate-100 px-8 py-6">
        {/* Decorative blob */}
        <div className="pointer-events-none absolute -right-8 -top-8 h-32 w-32 rounded-full bg-[#428B4D] opacity-[0.06] blur-3xl" />

        <div className="relative flex flex-wrap items-start justify-between gap-4">
          <div className="flex items-center gap-4">
            <div className="flex h-11 w-11 items-center justify-center rounded-xl bg-[#428B4D]/12 ring-1 ring-[#428B4D]/15 shadow-sm">
              <Building2 className="h-5 w-5 text-[#428B4D]" />
            </div>
            <div>
              <h2 className="text-base font-bold text-slate-800 tracking-tight">
                {parsed.bankName || bankLabel}
              </h2>
              <div className="mt-1 flex items-center gap-3">
                {parsed.lastUpdated && (
                  <span className="flex items-center gap-1 text-xs text-slate-400">
                    <Calendar className="h-3 w-3" />
                    Updated {parsed.lastUpdated}
                  </span>
                )}
              </div>
            </div>
          </div>

          {/* Stats chips */}
          <div className="flex items-center gap-2">
            <div className="flex items-center gap-1.5 rounded-full border border-[#428B4D]/15 bg-[#428B4D]/8 px-3 py-1">
              <Coins className="h-3.5 w-3.5 text-[#428B4D]" />
              <span className="text-xs font-semibold text-[#428B4D]">
                {totalCurrencies} {totalCurrencies === 1 ? "currency" : "currencies"}
              </span>
            </div>
            {newCount > 0 && (
              <div className="flex items-center gap-1.5 rounded-full border border-amber-200 bg-amber-50 px-3 py-1">
                <TrendingUp className="h-3.5 w-3.5 text-amber-600" />
                <span className="text-xs font-semibold text-amber-700">{newCount} new</span>
              </div>
            )}
          </div>
        </div>
      </div>

      {/* ── Body ──────────────────────────────────────────────────── */}
      <div className="p-6 space-y-5">

        {/* Section header */}
        <div className="flex items-center gap-2">
          <div className="h-px flex-1 bg-slate-100" />
          <span className="text-[10px] font-bold uppercase tracking-[0.12em] text-slate-400 px-2">
            Balances
          </span>
          <div className="h-px flex-1 bg-slate-100" />
        </div>

        {/* Currency card grid */}
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">

          {cards.map((card) => (
            <div
              key={card.code}
              className={`
                group relative flex flex-col gap-3 rounded-xl border p-4 transition-all duration-200
                ${card.isNew
                  ? "border-amber-200/60 bg-amber-50/30 shadow-sm shadow-amber-100"
                  : "border-slate-200/60 bg-slate-50/60 shadow-sm hover:border-[#428B4D]/25 hover:bg-white hover:shadow-md"
                }
              `}
            >
              {/* Remove (new only) */}
              {card.isNew && (
                <button
                  onClick={() => { setCards((prev) => prev.filter((c) => c.code !== card.code)); setSaveStatus("idle"); }}
                  className="absolute right-3 top-3 rounded-full p-0.5 text-slate-300 opacity-0 transition-all group-hover:opacity-100 hover:bg-slate-200 hover:text-slate-600"
                  title="Remove"
                >
                  <X className="h-3.5 w-3.5" />
                </button>
              )}

              {/* Currency code badge */}
              <div className="flex items-center justify-between">
                <span className={`
                  inline-flex items-center rounded-lg px-2.5 py-1 text-xs font-bold tracking-widest uppercase
                  ${card.isNew
                    ? "bg-amber-100 text-amber-700"
                    : "bg-[#428B4D]/10 text-[#428B4D]"
                  }
                `}>
                  {card.code}
                </span>
                {card.isNew && (
                  <span className="text-[9px] font-bold uppercase tracking-wider text-amber-500">New</span>
                )}
              </div>

              {/* Amount input */}
              <div className="space-y-1.5">
                <input
                  type="number"
                  value={card.amount}
                  onChange={(e) => {
                    setSaveStatus("idle");
                    setCards((prev) => prev.map((c) => c.code === card.code ? { ...c, amount: e.target.value } : c));
                  }}
                  placeholder="0.00"
                  className="w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm font-semibold text-slate-800 tabular-nums placeholder:text-slate-300 focus:border-[#428B4D] focus:outline-none focus:ring-2 focus:ring-[#428B4D]/12 transition-colors"
                />
                {card.amount && isFinite(parseFloat(card.amount)) && (
                  <p className="text-[11px] text-slate-400 tabular-nums px-0.5">
                    {formatAmount(card.amount)}
                  </p>
                )}
              </div>
            </div>
          ))}

          {/* ── Add Currency card ───────────────────────────────── */}
          {parsed.allCurrencies.length > 0 && (
            <div
              ref={searchRef}
              className="relative flex flex-col justify-center gap-3 rounded-xl border border-dashed border-slate-300 bg-white/60 p-4 min-h-[120px] hover:border-[#428B4D]/40 hover:bg-[#428B4D]/3 transition-colors"
            >
              <div className="flex items-center gap-2">
                <div className="flex h-6 w-6 items-center justify-center rounded-full bg-slate-100">
                  <Plus className="h-3.5 w-3.5 text-slate-400" />
                </div>
                <span className="text-xs font-semibold text-slate-400">Add Currency</span>
              </div>

              <div className="relative">
                <input
                  type="text"
                  value={query}
                  onChange={(e) => { setQuery(e.target.value); setShowDropdown(true); }}
                  onFocus={() => setShowDropdown(true)}
                  placeholder="Search (e.g. USD)…"
                  className="w-full rounded-lg border border-slate-200 bg-white px-3 py-2 pr-8 text-xs text-slate-900 placeholder:text-slate-300 focus:border-[#428B4D] focus:outline-none focus:ring-2 focus:ring-[#428B4D]/12 transition-colors"
                />
                <Search className="pointer-events-none absolute right-2.5 top-2.5 h-3 w-3 text-slate-400" />
              </div>

              {showDropdown && filteredDropdown.length > 0 && (
                <ul className="absolute left-0 right-0 top-full mt-1 max-h-48 overflow-auto rounded-xl border border-slate-200 bg-white shadow-xl text-sm z-50 divide-y divide-slate-50">
                  {filteredDropdown.map((opt) => (
                    <li
                      key={opt.id}
                      onMouseDown={(e) => e.preventDefault()}
                      onClick={() => handleAddCurrency(opt)}
                      className="cursor-pointer px-3 py-2.5 text-slate-800 hover:bg-[#428B4D]/8 hover:text-[#428B4D] transition-colors first:rounded-t-xl last:rounded-b-xl text-xs font-medium"
                    >
                      {opt.label}
                    </li>
                  ))}
                </ul>
              )}
              {showDropdown && query.trim() && filteredDropdown.length === 0 && (
                <p className="text-xs text-slate-400">No match found.</p>
              )}
            </div>
          )}
        </div>

        {/* ── Save All footer ──────────────────────────────────────── */}
        {cards.length > 0 && (
          <div className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-slate-100 bg-slate-50/60 px-5 py-3">
            <div className="min-h-[20px]">
              {saveStatus === "success" && (
                <div className="flex items-center gap-2 text-sm text-emerald-700">
                  <CheckCircle className="h-4 w-4" />
                  <span className="font-medium">{saveMessage}</span>
                </div>
              )}
              {saveStatus === "error" && (
                <div className="flex items-center gap-2 text-sm text-red-600">
                  <AlertCircle className="h-4 w-4" />
                  <span className="font-medium">{saveMessage}</span>
                </div>
              )}
            </div>

            <button
              onClick={handleSaveAll}
              disabled={saving || cards.every((c) => !c.amount)}
              className="flex items-center gap-2 rounded-xl px-6 py-2.5 text-sm font-semibold text-white shadow-sm transition-all hover:shadow-md hover:brightness-105 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:shadow-none"
              style={{ backgroundColor: "#428B4D" }}
            >
              {saving ? <RefreshCw className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
              {saving ? "Saving…" : "Save All Balances"}
            </button>
          </div>
        )}
      </div>
    </div>
  );
};
