import { useMemo, useState } from 'react';
import { CheckCircle2, ChevronDown, Pause, Play, X, Zap } from 'lucide-react';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { formatUSDWhole, asDollars, type Dollars } from '@/lib/money';

interface CurrentDebt {
  bill_id: number;
  name: string;
  starting_balance?: Dollars;
  current_balance?: Dollars | null;
  progress_pct?: number;
  projected_payoff_month?: number;
}

interface SnapshotDebt {
  bill_id: number;
  projected_payoff_date?: string | null;
  projected_payoff_month?: number;
}

export interface ActivePlan {
  name: string;
  status: string;
  started_at?: string | null;
  months_elapsed?: number;
  current_debts?: CurrentDebt[];
  plan_snapshot?: { debts?: SnapshotDebt[]; interest_saved?: Dollars };
}

interface ConfirmState {
  title: string;
  description: string;
  onConfirm?: () => void;
}

function fmt(v: Dollars | null | undefined): string {
  return formatUSDWhole(v);
}

function dateLabel(iso: string | null | undefined): string {
  if (!iso) return '—';
  return new Date(iso).toLocaleDateString(undefined, { month: 'short', year: 'numeric' });
}

function months(n: number | null | undefined): string {
  if (!n || n <= 0) return 'just started';
  const y = Math.floor(n / 12);
  const m = n % 12;
  if (y === 0) return `${m} mo`;
  if (m === 0) return `${y} yr`;
  return `${y} yr ${m} mo`;
}

// ─── On-track indicator ───────────────────────────────────────────────────────

interface OnTrackDebt {
  projected_payoff_month?: number;
  current_balance?: Dollars | null;
  starting_balance?: Dollars;
}

function computeOnTrack(debt: OnTrackDebt, monthsElapsed: number): string | null {
  if (!debt.projected_payoff_month || debt.current_balance == null) return null;
  const startBal = debt.starting_balance ?? asDollars(0);
  if (startBal <= 0) return null;

  const remaining = debt.projected_payoff_month - monthsElapsed;
  if (remaining <= 0) return debt.current_balance <= 0 ? 'done' : 'behind';

  const progressExpected = monthsElapsed / debt.projected_payoff_month;
  const progressActual = startBal > 0
    ? 1 - (debt.current_balance / startBal)
    : 0;

  const diff = progressActual - progressExpected;
  if (diff > 0.05) return 'ahead';
  if (diff < -0.05) return 'behind';
  return 'on_track';
}

function OnTrackPill({ status }: { status: string | null }) {
  if (!status) return null;
  const map = {
    ahead:    { label: '↑ Ahead',    cls: 'bg-teal-500/12 text-teal-600 dark:text-teal-400' },
    on_track: { label: '→ On track', cls: 'bg-muted/60 text-muted-foreground' },
    behind:   { label: '↓ Behind',   cls: 'bg-amber-500/12 text-amber-600 dark:text-amber-400' },
    done:     { label: '✓ Paid off', cls: 'bg-emerald-500/12 text-emerald-600 dark:text-emerald-400' },
  };
  const { label, cls } = map[status as keyof typeof map] ?? map.on_track;
  return (
    <span className={cn('rounded-full px-2 py-0.5 text-[10px] font-semibold', cls)}>
      {label}
    </span>
  );
}

// ─── Per-debt progress row ────────────────────────────────────────────────────

function DebtProgressRow({ debt, snapshotDebt, monthsElapsed }: { debt: CurrentDebt; snapshotDebt?: SnapshotDebt; monthsElapsed: number }) {
  const startBal  = debt.starting_balance ?? asDollars(0);
  const curBal    = debt.current_balance ?? startBal;
  const pct       = debt.progress_pct ?? 0;
  const trackStatus = computeOnTrack({ ...debt, ...snapshotDebt }, monthsElapsed);

  return (
    <div className="flex items-center gap-3 px-4 py-2.5 text-sm">
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-2 mb-1">
          <span className="font-medium truncate">{debt.name}</span>
          <OnTrackPill status={trackStatus} />
        </div>
        <div className="flex items-center gap-2">
          <div className="flex-1 h-2 rounded-full bg-muted/50 overflow-hidden">
            <div
              className="h-full rounded-full bg-emerald-500 transition-all duration-500"
              style={{ width: `${pct}%` }}
            />
          </div>
          <span className="text-[11px] font-mono text-muted-foreground tabular-nums w-8 text-right">{pct}%</span>
        </div>
      </div>
      <div className="shrink-0 text-right">
        {debt.current_balance !== null ? (
          <>
            <p className="text-xs font-mono font-semibold tabular-nums">{fmt(curBal)}</p>
            {startBal > 0 && <p className="text-[10px] text-muted-foreground">{fmt(startBal)} start</p>}
          </>
        ) : (
          <p className="text-xs text-muted-foreground italic">removed</p>
        )}
      </div>
      {snapshotDebt?.projected_payoff_date && (
        <div className="shrink-0 text-right hidden sm:block">
          <p className="text-[10px] text-muted-foreground">proj.</p>
          <p className="text-xs font-mono">{snapshotDebt.projected_payoff_date.slice(0, 7)}</p>
        </div>
      )}
    </div>
  );
}

// ─── PlanStatusBanner ─────────────────────────────────────────────────────────

interface PlanStatusBannerProps {
  plan?: ActivePlan | null;
  onPause?: () => void;
  onResume?: () => void;
  onComplete?: () => void;
  onAbandon?: () => void;
  onNewPlan?: () => void;
}

export default function PlanStatusBanner({ plan, onPause, onResume, onComplete, onAbandon, onNewPlan }: PlanStatusBannerProps) {
  const [open, setOpen] = useState(true);
  const [confirmDialog, setConfirmDialog] = useState<ConfirmState | null>(null);

  const snapshot    = plan?.plan_snapshot ?? {};
  const snapshotMap = useMemo(() => {
    const m: Record<number, SnapshotDebt> = {};
    (snapshot.debts ?? []).forEach(d => { m[d.bill_id] = d; });
    return m;
  }, [snapshot.debts]);

  const currentDebts = plan?.current_debts ?? [];
  const monthsElapsed = plan?.months_elapsed ?? 0;

  const totalStart = currentDebts.reduce((s, d) => s + (d.starting_balance ?? 0), 0);
  const totalCur   = currentDebts.reduce((s, d) => s + (d.current_balance ?? d.starting_balance ?? 0), 0);
  const totalPaid  = Math.max(0, totalStart - totalCur);
  const overallPct = totalStart > 0 ? Math.min(100, Math.round(totalPaid / totalStart * 100)) : 0;

  const isActive = plan?.status === 'active';
  const isPaused = plan?.status === 'paused';

  function confirm(_action: string, title: string, description: string, onConfirm?: () => void) {
    setConfirmDialog({ title, description, onConfirm });
  }

  if (!plan) return null;

  return (
    <>
      <Collapsible open={open} onOpenChange={setOpen}>
        <div className="mb-4 rounded-xl border border-emerald-400/25 bg-emerald-500/[0.05] dark:bg-emerald-400/[0.04] shadow-sm overflow-hidden">

          {/* Header row. The name/progress area and the chevron are the collapsible
              toggles; the action buttons are siblings (not nested inside a trigger
              button) so they don't trip axe nested-interactive (a11y QA-B14-02). */}
          <div className="flex items-center gap-3 px-4 py-3">

            {/* Status dot + name + progress — toggle */}
            <CollapsibleTrigger asChild>
              <button type="button" className="flex min-w-0 flex-1 items-center gap-3 text-left">
                <div className="flex items-center gap-2 min-w-0 flex-1">
                  {isActive ? (
                    <span className="relative flex h-2.5 w-2.5 shrink-0">
                      <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75" />
                      <span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500" />
                    </span>
                  ) : (
                    <Pause className="h-3 w-3 text-amber-500 shrink-0" />
                  )}
                  <span className="text-sm font-semibold truncate">{plan.name}</span>
                  <span className={cn(
                    'hidden sm:inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide',
                    isActive ? 'bg-emerald-500/15 text-emerald-600 dark:text-emerald-400' : 'bg-amber-500/15 text-amber-600 dark:text-amber-400',
                  )}>
                    {isActive ? 'Active' : 'Paused'}
                  </span>
                  <span className="text-[11px] text-muted-foreground shrink-0">
                    Started {dateLabel(plan.started_at)} · {months(monthsElapsed)} in
                  </span>
                </div>

                {/* Overall progress bar */}
                <div className="hidden md:flex items-center gap-2 w-36 shrink-0">
                  <div className="flex-1 h-1.5 rounded-full bg-muted/40 overflow-hidden">
                    <div className="h-full rounded-full bg-emerald-500 transition-all duration-500" style={{ width: `${overallPct}%` }} />
                  </div>
                  <span className="text-xs font-mono text-muted-foreground">{overallPct}%</span>
                </div>
              </button>
            </CollapsibleTrigger>

            {/* Actions — siblings of the triggers, not nested inside them */}
            <div className="flex items-center gap-1 shrink-0">
              {isActive && (
                <>
                  <Button size="sm" variant="ghost" className="h-7 px-2 text-xs gap-1" onClick={onPause}>
                    <Pause className="h-3 w-3" /> Pause
                  </Button>
                  <Button size="sm" variant="outline" className="h-7 px-2 text-xs gap-1 border-emerald-400/40 text-emerald-600 hover:bg-emerald-500/10 dark:text-emerald-400" onClick={() => confirm('complete', 'Mark plan as complete?', 'This will record your plan as successfully completed.', onComplete)}>
                    <CheckCircle2 className="h-3 w-3" /> Complete
                  </Button>
                </>
              )}
              {isPaused && (
                <>
                  <Button size="sm" variant="outline" className="h-7 px-2 text-xs gap-1 border-emerald-400/40 text-emerald-600 hover:bg-emerald-500/10 dark:text-emerald-400" onClick={onResume}>
                    <Play className="h-3 w-3" /> Resume
                  </Button>
                  <Button size="sm" variant="ghost" className="h-7 px-2 text-xs gap-1 text-destructive hover:bg-destructive/10" onClick={() => confirm('abandon', 'Abandon this plan?', 'This plan will be moved to history. Your debt data stays unchanged.', onAbandon)}>
                    <X className="h-3 w-3" /> Abandon
                  </Button>
                </>
              )}
              <Button size="sm" variant="ghost" className="h-7 px-2 text-xs gap-1 text-muted-foreground" onClick={() => confirm('new', 'Start a new plan?', 'Your current plan will be abandoned and moved to history. Your debt data stays unchanged.', onNewPlan)}>
                <Zap className="h-3 w-3" /> New Plan
              </Button>
            </div>

            {/* Chevron — also a toggle */}
            <CollapsibleTrigger asChild>
              <button type="button" aria-label="Toggle plan details" className="shrink-0 rounded text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
                <ChevronDown className={cn('h-4 w-4 transition-transform', open && 'rotate-180')} />
              </button>
            </CollapsibleTrigger>

          </div>

          {/* Collapsible body — per-debt rows */}
          <CollapsibleContent>
            <div className="border-t border-emerald-400/15 divide-y divide-border/30">
              {currentDebts.length === 0 ? (
                <p className="px-4 py-3 text-sm text-muted-foreground">No debt data in this plan.</p>
              ) : (
                currentDebts.map(debt => (
                  <DebtProgressRow
                    key={debt.bill_id}
                    debt={debt}
                    snapshotDebt={snapshotMap[debt.bill_id]}
                    monthsElapsed={monthsElapsed}
                  />
                ))
              )}

              {/* Summary row */}
              {totalStart > 0 && (
                <div className="px-4 py-2.5 flex items-center justify-between bg-muted/20">
                  <span className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                    Total progress
                  </span>
                  <div className="flex items-center gap-4">
                    <span className="text-xs text-muted-foreground">
                      {fmt(asDollars(totalPaid))} paid of {fmt(asDollars(totalStart))}
                    </span>
                    {(snapshot.interest_saved ?? 0) > 0 && (
                      <span className="text-xs text-emerald-600 dark:text-emerald-400 font-medium">
                        {fmt(snapshot.interest_saved)} interest saved vs minimum
                      </span>
                    )}
                  </div>
                </div>
              )}
            </div>
          </CollapsibleContent>

        </div>
      </Collapsible>

      {/* Confirmation dialog */}
      <AlertDialog open={!!confirmDialog} onOpenChange={open => { if (!open) setConfirmDialog(null); }}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{confirmDialog?.title}</AlertDialogTitle>
            <AlertDialogDescription>{confirmDialog?.description}</AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={() => setConfirmDialog(null)}>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={() => { confirmDialog?.onConfirm?.(); setConfirmDialog(null); }}>
              Confirm
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}
