import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Plus, Search, Pencil, Trash2, AlertCircle, ChevronLeft, ChevronRight,
  CheckCircle2, XCircle, Loader2, Receipt, Filter, Tag, Calendar, RotateCcw,
} from 'lucide-react';
import {
  useFinanceStore,
  EXPENSE_CATEGORIES,
  EXPENSE_STATUSES,
  ExpenseFilters,
  Expense,
} from '../../store/finance';
import { Modal, ModalBody } from '../../components/ui/Modal';
import CreateExpenseModal from '../../components/CreateExpenseModal';

const PAGE_SIZE = 25;

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

export default function Expenses() {
  const navigate = useNavigate();
  const {
    expenses,
    expensesTotal,
    expenseSummary,
    loading,
    error,
    fetchExpenses,
    fetchCategories,
    deleteExpense,
    approveExpense,
    rejectExpense,
    fetchExpenseSummary,
  } = useFinanceStore();

  const [status, setStatus] = useState('');
  const [category, setCategory] = useState('');
  const [dateFrom, setDateFrom] = useState('');
  const [dateTo, setDateTo] = useState('');
  const [page, setPage] = useState(0);
  const [confirmDelete, setConfirmDelete] = useState<number | null>(null);
  const [search, setSearch] = useState('');
  const [showCreateModal, setShowCreateModal] = useState(false);

  // F5 — approve/reject state machine
  const [rejecting, setRejecting] = useState<Expense | null>(null);
  const [rejectReason, setRejectReason] = useState('');
  const [actionPending, setActionPending] = useState<number | null>(null);
  const [actionError, setActionError] = useState<string | null>(null);
  const [actionOk, setActionOk] = useState<string | null>(null);

  useEffect(() => {
    fetchCategories();
    fetchExpenseSummary();
  }, [fetchCategories, fetchExpenseSummary]);

  useEffect(() => {
    const filters: ExpenseFilters = {
      status: status || undefined,
      category: category || undefined,
      date_from: dateFrom || undefined,
      date_to: dateTo || undefined,
      limit: PAGE_SIZE,
      offset: page * PAGE_SIZE,
    };
    fetchExpenses(filters);
  }, [status, category, dateFrom, dateTo, page, fetchExpenses]);

  const totalPages = Math.max(1, Math.ceil(expensesTotal / PAGE_SIZE));
  const filtered = search.trim()
    ? expenses.filter(
        (e) =>
          (e.description || '').toLowerCase().includes(search.toLowerCase()) ||
          (e.vendor || '').toLowerCase().includes(search.toLowerCase()) ||
          (e.invoice_number || '').toLowerCase().includes(search.toLowerCase()),
      )
    : expenses;

  const onDelete = async (id: number) => {
    const ok = await deleteExpense(id);
    if (ok) setConfirmDelete(null);
  };

  const onApprove = async (id: number) => {
    setActionPending(id);
    setActionError(null);
    setActionOk(null);
    try {
      await approveExpense(id);
      setActionOk(`Expense #${id} approved.`);
      await fetchExpenseSummary();
    } catch (err: any) {
      setActionError(err?.message || 'Failed to approve expense.');
    } finally {
      setActionPending(null);
    }
  };

  const onConfirmReject = async () => {
    if (!rejecting) return;
    const trimmed = rejectReason.trim();
    if (!trimmed) {
      setActionError('A rejection reason is required.');
      return;
    }
    const id = rejecting.id;
    setActionPending(id);
    setActionError(null);
    setActionOk(null);
    try {
      await rejectExpense(id, trimmed);
      setActionOk(`Expense #${id} rejected.`);
      setRejecting(null);
      setRejectReason('');
      await fetchExpenseSummary();
    } catch (err: any) {
      setActionError(err?.message || 'Failed to reject expense.');
    } finally {
      setActionPending(null);
    }
  };

  return (
    <div className="space-y-6 animate-in fade-in duration-300 pb-10">
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 pb-2 border-b border-border/60">
        <div>
          <div className="flex items-center gap-2">
            <Receipt className="text-primary" size={26} />
            <h1 className="text-2xl sm:text-3xl font-black text-text tracking-tight uppercase">Expenses</h1>
          </div>
          <p className="text-text-muted mt-1 text-xs sm:text-sm font-medium">
            Track and audit operational spend across the school.
          </p>
        </div>
        <button
          onClick={() => setShowCreateModal(true)}
          className="inline-flex items-center justify-center gap-2 bg-primary hover:bg-primary/90 text-white px-6 py-3 rounded-2xl font-black uppercase tracking-wider text-xs transition-all shadow-lg shadow-primary/20 hover:shadow-primary/30 active:scale-95 shrink-0 cursor-pointer"
        >
          <Plus size={18} strokeWidth={2.5} />
          <span>New Expense</span>
        </button>
      </div>

      {/* Search & Filters Card */}
      <div className="bg-card rounded-[2rem] border border-border p-6 shadow-sm space-y-5 min-w-0 max-w-full">
        {/* Search Input & Total Summary Pill */}
        <div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
          <div className="relative flex-1 min-w-0">
            <Search size={18} className="absolute left-4 top-1/2 -translate-y-1/2 text-text-muted" />
            <input
              type="text"
              placeholder="Search description, vendor, or invoice #"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="w-full pl-11 pr-10 py-3 bg-muted/40 border border-border rounded-2xl text-sm font-semibold focus:outline-none focus:ring-2 focus:ring-primary/40 focus:bg-card transition-all text-text"
            />
            {search && (
              <button
                type="button"
                onClick={() => setSearch('')}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-text-muted hover:text-text p-1 transition-colors"
                aria-label="Clear search text"
              >
                <XCircle size={16} />
              </button>
            )}
          </div>

          <div className="flex items-center gap-2 shrink-0">
            <span className="px-4 py-2 bg-primary/10 border border-primary/20 text-primary rounded-2xl text-xs font-black uppercase tracking-wider shadow-2xs">
              {loading ? 'Loading…' : `${expensesTotal} Total Expense${expensesTotal === 1 ? '' : 's'}`}
            </span>
            {filtered.length !== expenses.length && (
              <span className="text-xs text-text-muted font-bold">
                ({filtered.length} matching search)
              </span>
            )}
          </div>
        </div>

        {/* Filter Controls Grid */}
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4 border-t border-border/60">
          {/* Status Select */}
          <div className="space-y-1.5 min-w-0">
            <label className="text-[0.65rem] font-black uppercase tracking-wider text-text-muted px-1 flex items-center gap-1.5">
              <Filter size={12} className="text-primary shrink-0" />
              <span>Status</span>
            </label>
            <select
              value={status}
              onChange={(e) => { setStatus(e.target.value); setPage(0); }}
              className="w-full px-3.5 py-2.5 bg-muted/40 border border-border rounded-xl text-sm font-semibold focus:outline-none focus:ring-2 focus:ring-primary/40 text-text cursor-pointer"
            >
              <option value="">All statuses</option>
              {EXPENSE_STATUSES.map((s) => (
                <option key={s.value} value={s.value}>{s.label}</option>
              ))}
            </select>
          </div>

          {/* Category Select */}
          <div className="space-y-1.5 min-w-0">
            <label className="text-[0.65rem] font-black uppercase tracking-wider text-text-muted px-1 flex items-center gap-1.5">
              <Tag size={12} className="text-primary shrink-0" />
              <span>Category</span>
            </label>
            <select
              value={category}
              onChange={(e) => { setCategory(e.target.value); setPage(0); }}
              className="w-full px-3.5 py-2.5 bg-muted/40 border border-border rounded-xl text-sm font-semibold focus:outline-none focus:ring-2 focus:ring-primary/40 text-text cursor-pointer"
            >
              <option value="">All categories</option>
              {EXPENSE_CATEGORIES.map((c) => (
                <option key={c.value} value={c.value}>{c.label}</option>
              ))}
            </select>
          </div>

          {/* Date From */}
          <div className="space-y-1.5 min-w-0">
            <label className="text-[0.65rem] font-black uppercase tracking-wider text-text-muted px-1 flex items-center gap-1.5">
              <Calendar size={12} className="text-primary shrink-0" />
              <span>From Date</span>
            </label>
            <input
              type="date"
              value={dateFrom}
              onChange={(e) => { setDateFrom(e.target.value); setPage(0); }}
              className="w-full px-3.5 py-2.5 bg-muted/40 border border-border rounded-xl text-sm font-semibold focus:outline-none focus:ring-2 focus:ring-primary/40 text-text"
              aria-label="From date"
            />
          </div>

          {/* Date To */}
          <div className="space-y-1.5 min-w-0">
            <label className="text-[0.65rem] font-black uppercase tracking-wider text-text-muted px-1 flex items-center gap-1.5">
              <Calendar size={12} className="text-primary shrink-0" />
              <span>To Date</span>
            </label>
            <input
              type="date"
              value={dateTo}
              onChange={(e) => { setDateTo(e.target.value); setPage(0); }}
              className="w-full px-3.5 py-2.5 bg-muted/40 border border-border rounded-xl text-sm font-semibold focus:outline-none focus:ring-2 focus:ring-primary/40 text-text"
              aria-label="To date"
            />
          </div>
        </div>

        {/* Clear Filters Row */}
        {(status || category || dateFrom || dateTo || search) && (
          <div className="pt-3 border-t border-border/60 flex justify-end">
            <button
              onClick={() => {
                setStatus(''); setCategory(''); setDateFrom(''); setDateTo(''); setSearch(''); setPage(0);
              }}
              className="inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-rose-50 dark:bg-rose-950/30 text-rose-600 dark:text-rose-400 font-black uppercase tracking-wider text-[0.65rem] hover:bg-rose-100 dark:hover:bg-rose-900/50 transition-all border border-rose-200 dark:border-rose-800 cursor-pointer active:scale-95"
            >
              <RotateCcw size={14} />
              <span>Clear filters</span>
            </button>
          </div>
        )}
      </div>

      {/* Sprint 1b — B10: approval queue summary tiles */}
      {expenseSummary && (
        <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
          <div className="bg-card rounded-2xl border border-border p-4 shadow-sm">
            <p className="text-[0.6rem] uppercase font-black tracking-widest text-text-muted">
              Pending approval
            </p>
            <p className="text-2xl font-black mt-1 text-text">
              {expenseSummary.pending_count}
            </p>
            <p className="text-[0.65rem] mt-1 text-text-muted">
              {currency(expenseSummary.pending_amount)} queued
            </p>
          </div>
          <div className="bg-card rounded-2xl border border-border p-4 shadow-sm">
            <p className="text-[0.6rem] uppercase font-black tracking-widest text-text-muted">
              Approved this month
            </p>
            <p className="text-2xl font-black mt-1 text-emerald-600">
              {expenseSummary.approved_this_month.count}
            </p>
            <p className="text-[0.65rem] mt-1 text-text-muted">
              {currency(expenseSummary.approved_this_month.total)} released
            </p>
          </div>
          <div className="bg-card rounded-2xl border border-border p-4 shadow-sm">
            <p className="text-[0.6rem] uppercase font-black tracking-widest text-text-muted">
              Rejected this month
            </p>
            <p className="text-2xl font-black mt-1 text-rose-600">
              {expenseSummary.rejected_this_month.count}
            </p>
            <p className="text-[0.65rem] mt-1 text-text-muted">
              {currency(expenseSummary.rejected_this_month.total)} blocked
            </p>
          </div>
        </div>
      )}

      {/* Inline banners — no alert() — for approve/reject outcomes */}
      {actionOk && (
        <div className="bg-emerald-50 dark:bg-emerald-950/30 border border-emerald-200 dark:border-emerald-900 rounded-2xl p-4 flex items-center gap-3 text-emerald-700 dark:text-emerald-300">
          <CheckCircle2 size={18} />
          <span className="text-sm">{actionOk}</span>
        </div>
      )}
      {actionError && (
        <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">{actionError}</span>
          <button
            onClick={() => setActionError(null)}
            className="ml-auto text-xs font-bold underline"
          >
            Dismiss
          </button>
        </div>
      )}

      {/* Error */}
      {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>
      )}

      {/* Table */}
      <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">
                  Date
                </th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">
                  Category
                </th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">
                  Description
                </th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">
                  Vendor
                </th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest text-right">
                  Amount
                </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">
              {filtered.length > 0 ? (
                filtered.map((e) => (
                  <tr key={e.id} className="hover:bg-muted/40 transition-colors">
                    <td className="px-6 py-4 text-[0.75rem] font-mono text-text-muted whitespace-nowrap">
                      {(e.expense_date || '').slice(0, 10)}
                    </td>
                    <td className="px-6 py-4">
                      <span className="text-[0.7rem] font-bold uppercase tracking-tight px-2 py-1 rounded-md bg-muted text-text">
                        {(EXPENSE_CATEGORIES.find((c) => c.value === e.category) || { label: e.category }).label}
                      </span>
                    </td>
                    <td className="px-6 py-4 text-[0.85rem] font-medium text-text-secondary max-w-xs truncate">
                      {e.description}
                    </td>
                    <td className="px-6 py-4 text-[0.85rem] text-text-muted">
                      {e.vendor || '—'}
                    </td>
                    <td className="px-6 py-4 text-right text-[0.85rem] font-bold text-text whitespace-nowrap">
                      {currency(Number(e.amount))}
                    </td>
                    <td className="px-6 py-4">
                      <span className={`text-[0.6rem] font-black uppercase tracking-widest px-2.5 py-1 rounded-full border ${
                        e.status === 'approved' ? 'bg-emerald-500/10 text-emerald-500 border-emerald-500/20'
                        : e.status === 'paid' ? 'bg-blue-500/10 text-blue-500 border-blue-500/20'
                        : e.status === 'rejected' ? 'bg-rose-500/10 text-rose-500 border-rose-500/20'
                        : 'bg-amber-500/10 text-amber-500 border-amber-500/20'
                      }`}>
                        {e.status}
                      </span>
                    </td>
                    <td className="px-6 py-4 text-right whitespace-nowrap">
                      <div className="inline-flex items-center gap-1">
                        {e.status === 'pending' && (
                          <>
                            <button
                              onClick={() => onApprove(e.id)}
                              disabled={actionPending === e.id}
                              className="p-2 rounded-lg hover:bg-emerald-500 hover:text-white text-emerald-600 transition-all disabled:opacity-40"
                              title="Approve expense"
                              aria-label="Approve expense"
                            >
                              {actionPending === e.id ? (
                                <Loader2 size={16} className="animate-spin" />
                              ) : (
                                <CheckCircle2 size={16} />
                              )}
                            </button>
                            <button
                              onClick={() => {
                                setRejecting(e);
                                setRejectReason('');
                                setActionError(null);
                                setActionOk(null);
                              }}
                              className="p-2 rounded-lg hover:bg-rose-500 hover:text-white text-rose-500 transition-all"
                              title="Reject expense"
                              aria-label="Reject expense"
                            >
                              <XCircle size={16} />
                            </button>
                          </>
                        )}
                        <button
                          onClick={() => navigate(`/finance/expenses/${e.id}/edit`)}
                          className="p-2 rounded-lg hover:bg-primary hover:text-white text-text-muted transition-all"
                          title="Edit expense"
                          aria-label="Edit expense"
                        >
                          <Pencil size={16} />
                        </button>
                        <button
                          onClick={() => setConfirmDelete(e.id)}
                          className="p-2 rounded-lg hover:bg-red-500 hover:text-white text-text-muted transition-all"
                          title="Delete expense"
                          aria-label="Delete expense"
                        >
                          <Trash2 size={16} />
                        </button>
                      </div>
                    </td>
                  </tr>
                ))
              ) : (
                <tr>
                  <td colSpan={7} className="px-6 py-10 text-center text-text-muted text-sm">
                    {loading ? 'Loading expenses…' : 'No expenses match the current filters.'}
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>

        {/* Pagination */}
        <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>

      {/* Delete confirm */}
      {confirmDelete !== null && (
        <Modal
          open={true}
          onClose={() => setConfirmDelete(null)}
          title="Delete expense?"
          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={() => onDelete(confirmDelete)} className="px-4 py-2 rounded-xl bg-red-500 text-white text-sm font-bold hover:bg-red-600 transition-all">Delete</button>
            </>
          }
        >
          <ModalBody>
            <p className="text-sm text-text-muted">
              This will soft-delete expense #{confirmDelete}. It can be restored from the sync logs.
            </p>
          </ModalBody>
        </Modal>
      )}

      {/* Sprint 1b — F5 reject-reason modal */}
      {rejecting && (
        <Modal
          open={true}
          onClose={() => {
            setRejecting(null);
            setRejectReason('');
          }}
          title="Reject expense?"
          icon={XCircle}
          maxWidth="max-w-md"
          footer={
            <>
              <button onClick={() => { setRejecting(null); setRejectReason(''); }} disabled={actionPending === rejecting.id} 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={onConfirmReject} disabled={actionPending === rejecting.id || !rejectReason.trim()} className="flex items-center gap-2 px-4 py-2 rounded-xl bg-rose-500 text-white text-sm font-bold hover:bg-rose-600 disabled:opacity-40 transition-all">
                {actionPending === rejecting.id ? (<Loader2 size={14} className="animate-spin" />) : (<Receipt size={14} />)}
                <span>Reject expense</span>
              </button>
            </>
          }
        >
          <ModalBody>
            <p className="text-sm text-text-muted mb-3">
              Rejecting <strong>#{rejecting.id}</strong> · {currency(Number(rejecting.amount))} ·
              {' '}
              <span className="font-mono text-xs">{rejecting.description}</span>
            </p>
            <label className="block text-xs font-bold uppercase tracking-wider text-text-muted mb-1">
              Reason (required)
            </label>
            <textarea
              value={rejectReason}
              onChange={(e) => setRejectReason(e.target.value)}
              rows={3}
              maxLength={500}
              placeholder="Why is this being rejected?"
              className="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"
            />
            <p className="text-[0.65rem] text-text-muted mt-1">
              {rejectReason.trim().length}/500 characters
            </p>
          </ModalBody>
        </Modal>
      )}

      {/* Create Expense Modal */}
      <CreateExpenseModal
        isOpen={showCreateModal}
        onClose={() => setShowCreateModal(false)}
      />
    </div>
  );
}
