import { useEffect, useMemo, useState } from 'react';
import {
  Plus, RefreshCw, AlertCircle, Loader2, X,
  ChevronRight, ChevronDown, Pencil, Trash2, ChevronLeft,
  Building2, PiggyBank, Landmark, TrendingUp, Wallet, ArrowDownToLine, ArrowUpFromLine,
} from 'lucide-react';
import { useFinanceStore, ChartAccount } from '../../store/finance';
import { Modal, ModalBody } from '../../components/ui/Modal';

const TYPE_ICONS: Record<string, typeof Building2> = {
  asset: ArrowDownToLine,
  liability: ArrowUpFromLine,
  equity: Building2,
  revenue: TrendingUp,
  expense: Wallet,
};
const TYPE_LABEL: Record<string, string> = {
  asset: 'Asset',
  liability: 'Liability',
  equity: 'Equity',
  revenue: 'Revenue',
  expense: 'Expense',
};

const TYPE_BADGE: Record<string, string> = {
  asset: 'bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-900/20 dark:text-emerald-300',
  liability: 'bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-900/20 dark:text-amber-300',
  equity: 'bg-indigo-50 text-indigo-700 border-indigo-200 dark:bg-indigo-900/20 dark:text-indigo-300',
  revenue: 'bg-blue-50 text-blue-700 border-blue-200 dark:bg-blue-900/20 dark:text-blue-300',
  expense: 'bg-rose-50 text-rose-700 border-rose-200 dark:bg-rose-900/20 dark:text-rose-300',
};

interface TreeNode extends ChartAccount {
  children: TreeNode[];
}

function toTree(rows: ChartAccount[]): TreeNode[] {
  const byId = new Map<number, TreeNode>();
  rows.forEach((r) => byId.set(r.id, { ...r, children: [] }));
  const roots: TreeNode[] = [];
  rows.forEach((r) => {
    const node = byId.get(r.id)!;
    if (r.parent_id && byId.has(r.parent_id)) byId.get(r.parent_id)!.children.push(node);
    else roots.push(node);
  });
  return roots;
}

export default function ChartOfAccounts() {
  const {
    chartAccounts,
    loading,
    error,
    fetchChartAccounts,
    createChartAccount,
    updateChartAccount,
    deleteChartAccount,
  } = useFinanceStore();

  const [typeFilter, setTypeFilter] = useState<string>('');
  const [editor, setEditor] = useState<{ row?: ChartAccount; creating?: boolean } | null>(null);
  const [confirmDelete, setConfirmDelete] = useState<ChartAccount | null>(null);
  const [busy, setBusy] = useState(false);
  const [collapsed, setCollapsed] = useState<Set<number>>(new Set());

  useEffect(() => {
    fetchChartAccounts();
  }, [fetchChartAccounts]);

  const tree = useMemo(() => toTree(chartAccounts), [chartAccounts]);

  const filteredTree = useMemo(() => {
    if (!typeFilter) return tree;
    const matches = (n: TreeNode): boolean => {
      if (n.type === typeFilter) return true;
      return n.children.some(matches);
    };
    const filterNodes = (nodes: TreeNode[]): TreeNode[] =>
      nodes.flatMap((n) => {
        if (matches(n)) return [{ ...n, children: filterNodes(n.children) }];
        return [];
      });
    return filterNodes(tree);
  }, [tree, typeFilter]);

  const toggle = (id: number) => {
    setCollapsed((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  const save = async (data: Partial<ChartAccount>) => {
    setBusy(true);
    if (editor?.row && !editor.creating) {
      const r = await updateChartAccount(editor.row.uid, data);
      setBusy(false);
      if (r) setEditor(null);
    } else {
      const r = await createChartAccount(data);
      setBusy(false);
      if (r) setEditor(null);
    }
  };

  const totalsByType = useMemo(() => {
    const out: Record<string, number> = { asset: 0, liability: 0, equity: 0, revenue: 0, expense: 0 };
    chartAccounts.forEach((r) => { if (r.is_active) out[r.type] = (out[r.type] || 0) + 1; });
    return out;
  }, [chartAccounts]);

  return (
    <div className="space-y-6 animate-in fade-in duration-300 pb-10">
      <div className="flex flex-col md:flex-row md:items-end justify-between gap-4">
        <div>
          <h1 className="text-3xl font-extrabold text-text tracking-tight">Chart of Accounts</h1>
          <p className="text-text-muted mt-1 text-lg">Chart of accounts — categories for revenue, expenses, assets, liabilities.</p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => fetchChartAccounts()}
            className="flex items-center gap-2 px-4 py-2 rounded-xl border border-border text-text text-sm font-bold hover:bg-muted transition-all"
          >
            <RefreshCw size={16} /> Refresh
          </button>
          <button
            onClick={() => setEditor({ creating: true })}
            className="flex items-center gap-2 bg-primary hover:bg-primary-dark text-white px-5 py-2.5 rounded-xl font-semibold transition-all shadow-lg shadow-blue-900/10 active:scale-[0.98]"
          >
            <Plus size={18} /> New Account
          </button>
        </div>
      </div>

      {/* Type filter chips */}
      <div className="flex flex-wrap gap-2">
        <button
          onClick={() => setTypeFilter('')}
          className={`px-3 py-1.5 rounded-xl text-xs font-bold border transition-all ${
            !typeFilter ? 'bg-primary text-white border-primary' : 'bg-card text-text-muted border-border hover:bg-muted'
          }`}
        >
          All ({chartAccounts.length})
        </button>
        {Object.keys(TYPE_LABEL).map((t) => (
          <button
            key={t}
            onClick={() => setTypeFilter(t)}
            className={`px-3 py-1.5 rounded-xl text-xs font-bold border transition-all ${
              typeFilter === t ? 'bg-primary text-white border-primary' : 'bg-card text-text-muted border-border hover:bg-muted'
            }`}
          >
            {TYPE_LABEL[t]} ({totalsByType[t] || 0})
          </button>
        ))}
      </div>

      {error && (
        <div className="bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-900 rounded-2xl p-4 flex items-center gap-3 text-red-700 dark:text-red-300">
          <AlertCircle size={18} />
          <span className="text-sm">{error}</span>
        </div>
      )}

      <div className="bg-card rounded-2xl border border-border overflow-hidden shadow-sm">
        <div className="overflow-x-auto">
          {loading ? (
            <div className="p-10 text-center text-text-muted text-sm">Loading…</div>
          ) : filteredTree.length === 0 ? (
            <div className="p-10 text-center text-text-muted text-sm">No accounts yet — add one to seed the chart of accounts.</div>
          ) : (
            <table className="w-full text-left">
              <thead className="bg-muted/80 border-b border-border">
                <tr>
                  <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Code / Name</th>
                  <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Type</th>
                  <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Status</th>
                  <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest text-right">Actions</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-border">
                {filteredTree.map((node) => (
                  <TreeRow
                    key={node.id}
                    node={node}
                    depth={0}
                    collapsed={collapsed}
                    onToggle={toggle}
                    onEdit={(r) => setEditor({ row: r, creating: false })}
                    onDelete={(r) => setConfirmDelete(r)}
                  />
                ))}
              </tbody>
            </table>
          )}
        </div>
      </div>

      {editor && (
        <ChartEditor
          initial={editor.row}
          isCreating={!!editor.creating}
          allAccounts={chartAccounts}
          busy={busy}
          onSave={save}
          onClose={() => setEditor(null)}
        />
      )}

      {confirmDelete && (
        <Modal
          open={true}
          onClose={() => setConfirmDelete(null)}
          title="Delete chart account?"
          icon={Trash2}
          maxWidth="max-w-sm"
          footer={
            <>
              <button onClick={() => setConfirmDelete(null)} className="px-4 py-2 rounded-xl border border-border text-text text-sm font-bold hover:bg-muted transition-all">Cancel</button>
              <button
                onClick={async () => {
                  setBusy(true);
                  const ok = await deleteChartAccount(confirmDelete.uid);
                  setBusy(false);
                  if (ok) { setConfirmDelete(null); fetchChartAccounts(); }
                }}
                disabled={busy}
                className="flex items-center gap-2 px-4 py-2 rounded-xl bg-red-500 text-white text-sm font-bold hover:bg-red-600 disabled:opacity-40 transition-all"
              >
                {busy && <Loader2 size={14} className="animate-spin" />}
                <span>Delete</span>
              </button>
            </>
          }
        >
          <ModalBody>
            <p className="text-sm text-text-muted">Delete <strong>{confirmDelete.code} — {confirmDelete.name}</strong>? Will be blocked if children or bank accounts still reference it.</p>
          </ModalBody>
        </Modal>
      )}
    </div>
  );
}

function TreeRow({
  node, depth, collapsed, onToggle, onEdit, onDelete,
}: {
  node: TreeNode;
  depth: number;
  collapsed: Set<number>;
  onToggle: (id: number) => void;
  onEdit: (r: ChartAccount) => void;
  onDelete: (r: ChartAccount) => void;
}) {
  const isCollapsed = collapsed.has(node.id);
  const Icon = TYPE_ICONS[node.type] || Landmark;
  const hasChildren = node.children.length > 0;
  return (
    <>
      <tr className="hover:bg-muted/40 transition-colors">
        <td className="px-6 py-4">
          <div className="flex items-center gap-2" style={{ paddingLeft: depth * 24 }}>
            {hasChildren ? (
              <button onClick={() => onToggle(node.id)} className="p-1 rounded-md hover:bg-muted text-text-muted">
                {isCollapsed ? <ChevronRight size={14} /> : <ChevronDown size={14} />}
              </button>
            ) : (
              <span className="w-6" />
            )}
            <div className="w-2 h-6 rounded-sm" style={{ background: node.color || '#94a3b8' }} />
            <div className="font-mono text-[0.7rem] text-text-muted">{node.code}</div>
            <div className="text-[0.85rem] font-semibold text-text">{node.name}</div>
          </div>
        </td>
        <td className="px-6 py-4">
          <span className={`text-[0.6rem] font-black uppercase tracking-tight px-2 py-1 rounded-full border inline-flex items-center gap-1 ${TYPE_BADGE[node.type] || 'bg-muted text-text-muted'}`}>
            <Icon size={12} /> {TYPE_LABEL[node.type] || node.type}
          </span>
        </td>
        <td className="px-6 py-4">
          <span className={`text-[0.6rem] font-black uppercase tracking-tight px-2 py-1 rounded-full border ${
            node.is_active ? 'bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-900/20 dark:text-emerald-300'
                            : 'bg-muted text-text-muted border-border'
          }`}>{node.is_active ? 'Active' : 'Disabled'}</span>
        </td>
        <td className="px-6 py-4 text-right whitespace-nowrap">
          <div className="inline-flex items-center gap-1">
            <button onClick={() => onEdit(node as ChartAccount)} className="p-2 rounded-lg hover:bg-primary hover:text-white text-text-muted transition-all" title="Edit" aria-label="Edit">
              <Pencil size={16} />
            </button>
            <button onClick={() => onDelete(node as ChartAccount)} className="p-2 rounded-lg hover:bg-red-500 hover:text-white text-text-muted transition-all" title="Delete" aria-label="Delete">
              <Trash2 size={16} />
            </button>
          </div>
        </td>
      </tr>
      {hasChildren && !isCollapsed && node.children.map((c) => (
        <TreeRow
          key={c.id}
          node={c}
          depth={depth + 1}
          collapsed={collapsed}
          onToggle={onToggle}
          onEdit={onEdit}
          onDelete={onDelete}
        />
      ))}
    </>
  );
}

function ChartEditor({
  initial, isCreating, allAccounts, busy, onSave, onClose,
}: {
  initial?: ChartAccount;
  isCreating: boolean;
  allAccounts: ChartAccount[];
  busy: boolean;
  onSave: (data: Partial<ChartAccount>) => Promise<unknown>;
  onClose: () => void;
}) {
  const [code, setCode] = useState(initial?.code || '');
  const [name, setName] = useState(initial?.name || '');
  const [type, setType] = useState<ChartAccount['type']>(initial?.type || 'expense');
  const [parentUid, setParentUid] = useState(initial?.parent_id ? (allAccounts.find((a) => a.id === initial.parent_id)?.uid || '') : '');
  const [color, setColor] = useState(initial?.color || '#10b981');
  const [active, setActive] = useState(initial ? !!initial.is_active : true);

  const submit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!code.trim() || !name.trim()) return;
    await onSave({
      code: code.trim(), name: name.trim(), type,
      parent_uid: parentUid || null,
      color: color.trim() || null,
      is_active: active ? 1 : 0,
    } as any);
  };

  const parentOptions = allAccounts.filter((a) => !isCreating || a.type === type || !a.parent_id);

  return (
    <Modal
      open={true}
      onClose={onClose}
      title={isCreating ? 'New chart account' : `Edit ${initial?.code}`}
      icon={Landmark}
      maxWidth="max-w-lg"
      footer={
        <>
          <button type="button" onClick={onClose} className="px-4 py-2 rounded-xl border border-border text-text text-sm font-bold hover:bg-muted transition-all">Cancel</button>
          <button type="submit" form="chart-form" disabled={busy || !code.trim() || !name.trim()} className="flex items-center gap-2 px-4 py-2 rounded-xl bg-primary text-white text-sm font-bold hover:bg-primary-dark disabled:opacity-40 transition-all">
            {busy && <Loader2 size={14} className="animate-spin" />}
            <span>{isCreating ? 'Create' : 'Save'}</span>
          </button>
        </>
      }
    >
      <ModalBody>
        <form id="chart-form" onSubmit={submit} className="space-y-3">
          <div className="grid grid-cols-2 gap-3">
            <label className="block">
              <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Code *</span>
              <input value={code} onChange={(e) => setCode(e.target.value)} required className="mt-1 w-full px-3 py-2 bg-muted/30 border border-border rounded-xl text-sm font-mono focus:outline-none focus:ring-2 focus:ring-primary/30" />
            </label>
            <label className="block">
              <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Type *</span>
              <select value={type} onChange={(e) => setType(e.target.value as any)} className="mt-1 w-full px-3 py-2 bg-muted/30 border border-border rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-primary/30">
                {Object.keys(TYPE_LABEL).map((t) => <option key={t} value={t}>{TYPE_LABEL[t]}</option>)}
              </select>
            </label>
          </div>
          <label className="block">
            <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Name *</span>
            <input value={name} onChange={(e) => setName(e.target.value)} required className="mt-1 w-full px-3 py-2 bg-muted/30 border border-border rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-primary/30" />
          </label>
          <div className="grid grid-cols-2 gap-3">
            <label className="block">
              <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Parent</span>
              <select value={parentUid} onChange={(e) => setParentUid(e.target.value)} className="mt-1 w-full px-3 py-2 bg-muted/30 border border-border rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-primary/30">
                <option value="">— top-level —</option>
                {parentOptions.map((p) => (
                  <option key={p.uid} value={p.uid}>{p.code} · {p.name}</option>
                ))}
              </select>
            </label>
            <label className="block">
              <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Color</span>
              <input type="color" value={color} onChange={(e) => setColor(e.target.value)} className="mt-1 w-full h-10 px-1 py-1 bg-muted/30 border border-border rounded-xl text-sm" />
            </label>
          </div>
          <label className="flex items-center gap-2 text-sm">
            <input type="checkbox" checked={active} onChange={(e) => setActive(e.target.checked)} className="accent-primary" />
            <span>Active</span>
          </label>
        </form>
      </ModalBody>
    </Modal>
  );
}
