import { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Plus, RefreshCw, Search, AlertCircle, Loader2, X,
  Wallet, Hash, Calendar, ChevronLeft, ChevronRight,
  Eye, Play, Trash2, Wallet2, BookText,
} from 'lucide-react';
import { useFinanceStore, FeePlan } from '../../store/finance';
import { Modal, ModalBody } from '../../components/ui/Modal';
import { useFinanceEngineStore } from '../../store/finance-engine';

const PAGE_SIZE = 25;

const statusBadge = (status: string) =>
  status === 'paid' ? 'bg-emerald-50 text-emerald-700 border-emerald-200'
: status === 'approved'    ? 'bg-blue-50 text-blue-700 border-blue-200'
: status === 'calculated' ? 'bg-indigo-50 text-indigo-700 border-indigo-200'
: status === 'cancelled'  ? 'bg-rose-50 text-rose-700 border-rose-200'
: status === 'draft'      ? 'bg-amber-50 text-amber-700 border-amber-200'
: 'bg-muted text-text-muted border-border';

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

export default function FeePlans() {
  const navigate = useNavigate();
  const {
    plans, currentPlan, loading, error,
    fetchPlans, fetchPlan, deletePlan, fetchFeeGroups,
  } = useFinanceStore();
  const {
    lastApply, busy: engineBusy, error: engineError,
    applyFeePlan, revokeFeePlan,
  } = useFinanceEngineStore();

  const [search, setSearch] = useState('');
  const [feeGroup, setFeeGroup] = useState('');
  const [academicYear, setAcademicYear] = useState('');
  const [page, setPage] = useState(0);
  const [applyModal, setApplyModal] = useState<FeePlan | null>(null);
  const [confirmRevoke, setConfirmRevoke] = useState<FeePlan | null>(null);
  const [banner, setBanner] = useState<{ kind: 'ok' | 'err'; msg: string } | null>(null);

  useEffect(() => {
    fetchPlans({ fee_group_id: feeGroup ? Number(feeGroup) : undefined, academic_year: academicYear || undefined });
    fetchFeeGroups();
  }, [feeGroup, academicYear, fetchPlans, fetchFeeGroups]);

  const filtered = useMemo(() => {
    if (!search.trim()) return plans;
    const needle = search.toLowerCase();
    return plans.filter((p) =>
      (p.name || '').toLowerCase().includes(needle) ||
      (p.fee_name || '').toLowerCase().includes(needle),
    );
  }, [plans, search]);

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

  const openDetail = async (uid: string) => {
    await fetchPlan(uid);
  };

  const onRevoke = async (p: FeePlan) => {
    const r = await revokeFeePlan(p.uid);
    if (r) {
      setBanner({ kind: 'ok', msg: `Revoked plan; ${r.removed} fee line(s) removed.` });
      await fetchPlans();
    } else {
      setBanner({ kind: 'err', msg: 'Failed to revoke plan.' });
    }
    setConfirmRevoke(null);
  };

  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">Fee Plans</h1>
          <p className="text-text-muted mt-1 text-lg">
            Installment templates — apply to a student, group, or class to materialize fee lines.
          </p>
        </div>
        <button
          onClick={() => navigate('/finance/plans/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 Plan
        </button>
      </div>

      {banner && (
        <div className={`rounded-2xl border p-4 flex items-center gap-3 text-sm ${
          banner.kind === 'ok' ? 'bg-emerald-50 border-emerald-200 text-emerald-700' : 'bg-red-50 border-red-200 text-red-700'
        }`}>
          {banner.kind === 'ok' ? <Wallet size={18} /> : <AlertCircle size={18} />}
          <span className="flex-1">{banner.msg}</span>
          <button onClick={() => setBanner(null)} className="text-xs font-bold underline">Dismiss</button>
        </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 plan, fee group…"
              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={academicYear} onChange={(e) => { setAcademicYear(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 academic years</option>
            {Array.from(new Set(plans.map((p) => p.academic_year).filter(Boolean))).map((y) => (
              <option key={String(y)} value={String(y)}>{String(y)}</option>
            ))}
          </select>
        </div>
        <p className="text-[0.65rem] mt-3 text-text-muted">{loading ? 'Loading…' : `${filtered.length} plan${filtered.length === 1 ? '' : 's'}`}</p>
      </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">Plan</th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Fee group</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 text-right">Installments</th>
                <th className="px-6 py-4 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Year</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((p) => (
                  <tr key={p.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"><Wallet2 size={14} /></div>
                        <p className="text-[0.85rem] font-semibold text-text">{p.name}</p>
                      </div>
                    </td>
                    <td className="px-6 py-4 text-[0.85rem] text-text-secondary">{p.fee_name || '—'}</td>
                    <td className="px-6 py-4 text-right text-[0.85rem] font-bold text-text whitespace-nowrap">{currency(Number(p.total_amount))}</td>
                    <td className="px-6 py-4 text-right text-[0.85rem] text-text-secondary whitespace-nowrap">{p.installments_count}</td>
                    <td className="px-6 py-4 text-[0.85rem] text-text-muted">{p.academic_year || '—'}</td>
                    <td className="px-6 py-4 text-right whitespace-nowrap">
                      <div className="inline-flex items-center gap-1">
                        <button
                          onClick={() => setApplyModal(p)}
                          className="p-2 rounded-lg hover:bg-emerald-500 hover:text-white text-emerald-600 transition-all"
                          title="Apply plan to a class / student / group"
                          aria-label="Apply plan"
                        >
                          <Play size={16} />
                        </button>
                        <button
                          onClick={() => openDetail(p.uid)}
                          className="p-2 rounded-lg hover:bg-primary hover:text-white text-text-muted transition-all"
                          title="View installments"
                          aria-label="View installments"
                        >
                          <Eye size={16} />
                        </button>
                        <button
                          onClick={() => setConfirmRevoke(p)}
                          className="p-2 rounded-lg hover:bg-red-500 hover:text-white text-text-muted transition-all"
                          title="Revoke plan lines (unpaid only)"
                          aria-label="Revoke plan"
                        >
                          <Trash2 size={16} />
                        </button>
                      </div>
                    </td>
                  </tr>
                ))
              ) : (
                <tr><td colSpan={6} className="px-6 py-10 text-center text-text-muted text-sm">No plans yet — create one to materialize installment fees.</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>

      {currentPlan && (
        <div className="bg-card border border-border rounded-2xl p-6 shadow-sm">
          <div className="flex items-center justify-between mb-3">
            <h3 className="text-[0.65rem] font-black uppercase tracking-[2px] text-primary">Plan installments — {currentPlan.name}</h3>
            <button onClick={() => openDetail('')} className="text-xs font-bold text-text-muted hover:text-text"><X size={14} /></button>
          </div>
          <table className="w-full text-left">
            <thead className="bg-muted/50">
              <tr>
                <th className="px-4 py-2 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">#</th>
                <th className="px-4 py-2 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Label</th>
                <th className="px-4 py-2 text-[0.6rem] uppercase text-text-muted font-black tracking-widest text-right">Amount</th>
                <th className="px-4 py-2 text-[0.6rem] uppercase text-text-muted font-black tracking-widest">Due date</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-border">
              {(currentPlan.installments || []).map((it) => (
                <tr key={it.id}>
                  <td className="px-4 py-2 text-[0.85rem] text-text-muted">{it.sequence}</td>
                  <td className="px-4 py-2 text-[0.85rem] font-semibold text-text">{it.label}</td>
                  <td className="px-4 py-2 text-right text-[0.85rem] font-mono font-bold">{currency(Number(it.amount))}</td>
                  <td className="px-4 py-2 text-[0.85rem] font-mono text-text-secondary whitespace-nowrap"><Calendar size={12} className="inline mr-1" />{it.due_date || '—'}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {applyModal && (
        <ApplyPlanModal
          plan={applyModal}
          busy={engineBusy}
          onClose={() => setApplyModal(null)}
          onApply={async (body) => {
            const r = await applyFeePlan(applyModal.uid, body);
            if (r) {
              setBanner({ kind: 'ok', msg: `Applied to ${r.recipients} recipient(s); created ${r.created} fee line(s), skipped ${r.skipped}.` });
              setApplyModal(null);
            } else {
              setBanner({ kind: 'err', msg: 'Failed to apply plan.' });
            }
          }}
        />
      )}

      {confirmRevoke && (
        <Modal
          open={true}
          onClose={() => setConfirmRevoke(null)}
          title="Revoke plan?"
          icon={Trash2}
          maxWidth="max-w-sm"
          footer={
            <>
              <button onClick={() => setConfirmRevoke(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={() => onRevoke(confirmRevoke)} disabled={engineBusy} 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">
                {engineBusy ? <Loader2 size={14} className="animate-spin" /> : <Trash2 size={14} />}
                <span>Revoke</span>
              </button>
            </>
          }
        >
          <ModalBody>
            <p className="text-sm text-text-muted">
              Soft-delete every fee line generated by <strong>{confirmRevoke.name}</strong> that has <em>not</em> received payment. Paid lines are kept intact.
            </p>
          </ModalBody>
        </Modal>
      )}
    </div>
  );
}

function ApplyPlanModal({
  plan, busy, onClose, onApply,
}: {
  plan: FeePlan;
  busy: boolean;
  onClose: () => void;
  onApply: (body: any) => Promise<unknown>;
}) {
  const [scope, setScope] = useState<'student' | 'group' | 'class'>('class');
  const [scopeUid, setScopeUid] = useState('');
  const [classId, setClassId] = useState('');
  const [academicYear, setAcademicYear] = useState(plan.academic_year || '');

  const submit = (e: React.FormEvent) => {
    e.preventDefault();
    const body: any = { scope, academic_year: academicYear || undefined };
    if (scope === 'student' || scope === 'group') {
      if (!scopeUid.trim()) return;
      body.scope_uid = scopeUid.trim();
    } else if (scope === 'class') {
      if (!classId.trim()) return;
      body.scope_uid = classId.trim();
    }
    onApply(body);
  };

  return (
    <Modal
      open={true}
      onClose={onClose}
      title={`Apply ${plan.name}`}
      icon={Play}
      maxWidth="max-w-md"
      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="feeplan-apply-form" disabled={busy} className="flex items-center gap-2 px-4 py-2 rounded-xl bg-emerald-500 text-white text-sm font-bold hover:bg-emerald-600 disabled:opacity-40 transition-all">
            {busy ? <Loader2 size={14} className="animate-spin" /> : <Play size={14} />}
            <span>Apply plan</span>
          </button>
        </>
      }
    >
      <ModalBody>
        <form id="feeplan-apply-form" onSubmit={submit}>
          <p className="text-sm text-text-muted mb-3">
            This will generate <strong>{plan.installments_count}</strong> fee line{plan.installments_count === 1 ? '' : 's'} × recipient(s) on the student_fees table.
          </p>
          <label className="block">
            <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Apply to</span>
            <select value={scope} onChange={(e) => setScope(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">
              <option value="class">Class (enter class ID)</option>
              <option value="group">Student group (enter group UID)</option>
              <option value="student">Single student (enter student UID)</option>
            </select>
          </label>
          {scope === 'class' && (
            <label className="block mt-3">
              <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Class ID</span>
              <input type="number" min={1} value={classId} onChange={(e) => setClassId(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" />
            </label>
          )}
          {(scope === 'student' || scope === 'group') && (
            <label className="block mt-3">
              <span className="text-xs font-bold uppercase tracking-wider text-text-muted">{scope === 'student' ? 'Student UID' : 'Student group UID'}</span>
              <input value={scopeUid} onChange={(e) => setScopeUid(e.target.value)} 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 mt-3">
            <span className="text-xs font-bold uppercase tracking-wider text-text-muted">Academic year (optional)</span>
            <input value={academicYear} onChange={(e) => setAcademicYear(e.target.value)} placeholder="2027" 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>
        </form>
      </ModalBody>
    </Modal>
  );
}
