import { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Plus, Search, RefreshCw, Send, AlertCircle, Loader2,
  FileText, ChevronLeft, ChevronRight, X,
  Receipt, Eye, Printer,
} from 'lucide-react';
import { useFinanceStore, Invoice } from '../../store/finance';
import { Drawer } from '../../components/ui/Drawer';

const PAGE_SIZE = 25;

const currency = (n: number) =>
  new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(Number.isFinite(n) ? n : 0);

const statusBadge = (status: string) => {
  const s = status.toLowerCase();
  if (s === 'paid') return 'bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-900/20 dark:text-emerald-300';
  if (s === 'partial' || s === 'issued') return 'bg-blue-50 text-blue-700 border-blue-200 dark:bg-blue-900/20 dark:text-blue-300';
  if (s === 'draft') return 'bg-muted text-text-muted border-border';
  if (s === 'overdue' || s === 'cancelled') return 'bg-rose-50 text-rose-700 border-rose-200 dark:bg-rose-900/20 dark:text-rose-300';
  return 'bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-900/20 dark:text-amber-300';
};

export default function Invoices() {
  const navigate = useNavigate();
  const {
    invoices, loading, error, fetchInvoices, fetchInvoice, sendInvoice,
  } = useFinanceStore();

  const [status, setStatus] = useState('');
  const [period, setPeriod] = useState('');
  const [search, setSearch] = useState('');
  const [page, setPage] = useState(0);
  const [detail, setDetail] = useState<Invoice | null>(null);
  const [busy, setBusy] = useState<string | null>(null);

  useEffect(() => {
    fetchInvoices({
      status: status || undefined,
      period_label: period || undefined,
      search: search.trim() || undefined,
    });
  }, [status, period, search, fetchInvoices]);

  const totalPages = Math.max(1, Math.ceil(invoices.length / PAGE_SIZE));
  const pageRows = invoices.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE);

  const periods = useMemo(() => {
    const set = new Set<string>();
    invoices.forEach((i) => i.period_label && set.add(i.period_label));
    return Array.from(set).sort();
  }, [invoices]);

  const totalsByStatus = useMemo(() => {
    const out: Record<string, { count: number; total: number }> = {};
    invoices.forEach((i) => {
      const s = i.status || 'unknown';
      out[s] = out[s] || { count: 0, total: 0 };
      out[s].count++;
      out[s].total += Number(i.total) || 0;
    });
    return out;
  }, [invoices]);

  const openDetail = async (uid: string) => {
    setBusy(uid);
    const inv = await fetchInvoice(uid);
    if (inv) setDetail(inv);
    setBusy(null);
  };

  const onSend = async (uid: string) => {
    setBusy(uid);
    const ok = await sendInvoice(uid);
    setBusy(null);
    if (ok) {
      await fetchInvoices();
      const inv = await fetchInvoice(uid);
      if (inv) setDetail(inv);
    }
  };

  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">Invoices</h1>
          <p className="text-text-muted mt-1 text-lg">
            Formal invoices issued to students and guardians.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => fetchInvoices()}
            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={() => navigate('/finance/invoices/new')}
            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 Invoice
          </button>
        </div>
      </div>

      {/* Summary chips */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
        {['draft', 'issued', 'paid', 'overdue'].map((s) => (
          <div key={s} className="bg-card border border-border rounded-2xl p-4 shadow-sm">
            <p className="text-[0.6rem] uppercase font-black tracking-widest text-text-muted">{s}</p>
            <p className="text-2xl font-black mt-1">{totalsByStatus[s]?.count || 0}</p>
            <p className="text-[0.65rem] text-text-muted mt-1">{currency(totalsByStatus[s]?.total || 0)}</p>
          </div>
        ))}
      </div>

      {/* Filters */}
      <div className="bg-card rounded-2xl border border-border p-5 shadow-sm">
        <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
          <div className="relative sm:col-span-2">
            <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-text-muted" />
            <input
              type="text"
              placeholder="Search invoice #, student name…"
              value={search}
              onChange={(e) => { setSearch(e.target.value); setPage(0); }}
              className="w-full pl-9 pr-3 py-2.5 bg-muted/30 border border-border rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-primary/30"
            />
          </div>
          <select
            value={status}
            onChange={(e) => { setStatus(e.target.value); setPage(0); }}
            className="px-3 py-2.5 bg-muted/30 border border-border rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-primary/30"
          >
            <option value="">All statuses</option>
            {['draft', 'issued', 'paid', 'partial', 'overdue', 'cancelled'].map((s) => (
              <option key={s} value={s}>{s}</option>
            ))}
          </select>
        </div>
        <div className="flex flex-wrap items-center gap-2 mt-3">
          {periods.map((p) => (
            <button
              key={p}
              onClick={() => setPeriod(period === p ? '' : p)}
              className={`px-2.5 py-1 rounded-full text-[0.65rem] font-bold border transition-all ${
                period === p ? 'bg-primary text-white border-primary' : 'bg-muted text-text-muted border-border'
              }`}
            >
              {p}
            </button>
          ))}
          {period && (
            <button onClick={() => setPeriod('')} className="text-xs text-primary hover:underline">Clear period</button>
          )}
        </div>
      </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">
          <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">Invoice</th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Student</th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Period</th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest text-right">Total</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">
              {pageRows.length > 0 ? (
                pageRows.map((i) => (
                  <tr key={i.uid} className="hover:bg-muted/40 transition-colors">
                    <td className="px-6 py-4">
                      <div className="flex items-center gap-2">
                        <div className="p-1.5 rounded-md bg-primary/10 text-primary">
                          <Receipt size={14} />
                        </div>
                        <div>
                          <p className="text-[0.85rem] font-mono font-bold text-text">{i.invoice_number}</p>
                          <p className="text-[0.65rem] text-text-muted">{i.fee_name || i.fee_type || '—'}</p>
                        </div>
                      </div>
                    </td>
                    <td className="px-6 py-4">
                      <p className="text-[0.85rem] font-semibold text-text">{i.first_name} {i.last_name}</p>
                      <p className="text-[0.65rem] text-text-muted">{i.email}</p>
                    </td>
                    <td className="px-6 py-4 text-[0.85rem] text-text-secondary">{i.period_label || '—'}</td>
                    <td className="px-6 py-4 text-right text-[0.85rem] font-bold text-text whitespace-nowrap">{currency(Number(i.total))}</td>
                    <td className="px-6 py-4">
                      <span className={`text-[0.6rem] font-black uppercase tracking-tight px-2 py-1 rounded-full border ${statusBadge(i.status)}`}>{i.status}</span>
                    </td>
                    <td className="px-6 py-4 text-right whitespace-nowrap">
                      <button
                        onClick={() => openDetail(i.uid)}
                        disabled={busy === i.uid}
                        className="p-2 rounded-lg hover:bg-primary hover:text-white text-text-muted transition-all disabled:opacity-40"
                        title="View invoice"
                        aria-label="View invoice"
                      >
                        {busy === i.uid ? <Loader2 size={16} className="animate-spin" /> : <Eye size={16} />}
                      </button>
                    </td>
                  </tr>
                ))
              ) : (
                <tr><td colSpan={6} className="px-6 py-10 text-center text-text-muted text-sm">No invoices match the current filters.</td></tr>
              )}
            </tbody>
          </table>
        </div>
        <div className="px-6 py-4 border-t border-border bg-muted/30 flex items-center justify-between">
          <span className="text-[0.7rem] font-bold text-text-muted">Page {page + 1} of {totalPages}</span>
          <div className="inline-flex items-center gap-2">
            <button disabled={page === 0} onClick={() => setPage((p) => Math.max(0, p - 1))} className="flex items-center gap-1 px-3 py-1.5 rounded-lg border border-border bg-card text-xs font-bold disabled:opacity-40 hover:bg-muted transition-all">
              <ChevronLeft size={14} /> Prev
            </button>
            <button disabled={page + 1 >= totalPages} onClick={() => setPage((p) => p + 1)} className="flex items-center gap-1 px-3 py-1.5 rounded-lg border border-border bg-card text-xs font-bold disabled:opacity-40 hover:bg-muted transition-all">
              Next <ChevronRight size={14} />
            </button>
          </div>
        </div>
      </div>

      {detail && (
        <InvoiceDetail
          invoice={detail}
          busy={busy === detail.uid}
          onClose={() => setDetail(null)}
          onSend={() => onSend(detail.uid)}
        />
      )}
    </div>
  );
}

function InvoiceDetail({
  invoice, busy, onClose, onSend,
}: {
  invoice: Invoice;
  busy: boolean;
  onClose: () => void;
  onSend: () => void;
}) {
  return (
    <Drawer
      open={true}
      onClose={onClose}
      title={`Invoice ${invoice.invoice_number}`}
      icon={FileText}
      maxWidth="max-w-2xl"
      footer={
        <>
          <button
            onClick={() => window.print()}
            className="flex items-center gap-2 px-4 py-2.5 rounded-xl border border-border text-text text-sm font-bold hover:bg-muted transition-all"
          >
            <Printer size={14} /> Print
          </button>
          {invoice.status === 'draft' && (
            <button
              onClick={onSend}
              disabled={busy}
              className="flex items-center gap-2 px-4 py-2.5 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" /> : <Send size={14} />}
              <span>Mark as sent</span>
            </button>
          )}
        </>
      }
    >
      <div className="px-6 py-5 space-y-6">
          <div className="grid grid-cols-2 gap-3">
            <DetailBlock label="Student" value={`${invoice.first_name || ''} ${invoice.last_name || ''}`} sub={invoice.email} />
            <DetailBlock label="Period" value={invoice.period_label || '—'} sub={invoice.fee_name || invoice.fee_type || '—'} />
          </div>

          <div className="bg-muted/30 rounded-2xl border border-border p-4 space-y-2">
            <LineItem label="Subtotal" amount={Number(invoice.subtotal) || 0} />
            <LineItem label="Discount" amount={-(Number(invoice.discount_amount) || 0)} tone="rose" />
            <LineItem label="Total" amount={Number(invoice.total) || 0} bold />
            <LineItem label="Paid" amount={Number(invoice.paid_amount) || 0} tone="emerald" />
            <LineItem label="Outstanding" amount={(Number(invoice.total) || 0) - (Number(invoice.paid_amount) || 0)} tone={invoice.paid_amount >= invoice.total ? 'emerald' : 'rose'} bold />
          </div>

          {invoice.lines && invoice.lines.length > 0 && (
            <div>
              <p className="text-[0.6rem] uppercase font-black tracking-widest text-text-muted mb-1.5 px-1">Linked fee lines</p>
              <div className="rounded-xl border border-border divide-y divide-border bg-card">
                {invoice.lines.map((l) => (
                  <div key={l.id} className="px-4 py-2.5 text-sm flex items-center justify-between">
                    <div>
                      <p className="font-semibold text-text">{l.fee_name || 'Fee line'}</p>
                      <p className="text-[0.65rem] text-text-muted">{l.due_date || 'no due date'} · status {l.status}</p>
                    </div>
                    <p className="font-mono font-bold">{currency(Number(l.amount))}</p>
                  </div>
                ))}
              </div>
            </div>
          )}

          {invoice.notes && (
            <div className="bg-muted/30 rounded-2xl border border-border p-4">
              <p className="text-[0.6rem] uppercase font-black tracking-widest text-text-muted mb-1">Notes</p>
              <p className="text-sm whitespace-pre-wrap text-text-secondary">{invoice.notes}</p>
            </div>
          )}

          <div className="flex items-center gap-2">
            <button
              onClick={() => window.print()}
              className="flex items-center gap-2 px-4 py-2.5 rounded-xl border border-border text-text text-sm font-bold hover:bg-muted transition-all"
            >
              <Printer size={14} /> Print
            </button>
            {invoice.status === 'draft' && (
              <button
                onClick={onSend}
                disabled={busy}
                className="flex items-center gap-2 px-4 py-2.5 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" /> : <Send size={14} />}
                <span>Mark as sent</span>
              </button>
            )}
          </div>
        </div>
    </Drawer>
  );
}

function DetailBlock({ label, value, sub }: { label: string; value: string; sub?: string }) {
  return (
    <div className="rounded-xl border border-border bg-muted/30 p-3">
      <p className="text-[0.6rem] uppercase font-black tracking-widest text-text-muted">{label}</p>
      <p className="text-sm font-bold text-text mt-0.5 break-words">{value || '—'}</p>
      {sub && <p className="text-[0.65rem] text-text-muted mt-0.5 break-words">{sub}</p>}
    </div>
  );
}

function LineItem({ label, amount, tone, bold }: { label: string; amount: number; tone?: 'rose' | 'emerald'; bold?: boolean }) {
  const valueCls =
    tone === 'rose' ? 'text-rose-500' : tone === 'emerald' ? 'text-emerald-600' : 'text-text';
  return (
    <div className="flex items-center justify-between text-sm">
      <span className="text-text-secondary">{label}</span>
      <span className={`font-mono ${bold ? 'font-black text-base' : 'font-semibold'} ${valueCls}`}>{currency(amount)}</span>
    </div>
  );
}
