import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import {
  Banknote,
  CalendarDays,
  ChevronLeft,
  ChevronRight,
  CircleDollarSign,
  PiggyBank,
  RefreshCw,
  Target,
  TrendingDown,
  Trophy,
  WalletCards,
} from 'lucide-react';
import { toast } from 'sonner';
import { api } from '@/api';
import { cn, fmt, fmtDate, todayStr } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';

const MONTHS = [
  'January', 'February', 'March', 'April', 'May', 'June',
  'July', 'August', 'September', 'October', 'November', 'December',
];
const WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

function currentMonth() {
  const now = new Date();
  return { year: now.getFullYear(), month: now.getMonth() + 1 };
}

function shiftMonth(year, month, delta) {
  const next = new Date(year, month - 1 + delta, 1);
  return { year: next.getFullYear(), month: next.getMonth() + 1 };
}

function displayStatus(status) {
  if (status === 'due_soon') return 'Due';
  if (status === 'late') return 'Late';
  return status ? status.charAt(0).toUpperCase() + status.slice(1) : 'Due';
}

function statusTone(status) {
  if (status === 'paid' || status === 'autodraft') return 'bg-emerald-500/15 text-emerald-500 border-emerald-500/25';
  if (status === 'skipped') return 'bg-muted text-muted-foreground border-border';
  if (status === 'late' || status === 'missed') return 'bg-destructive/15 text-destructive border-destructive/25';
  return 'bg-primary/10 text-primary border-primary/25';
}

function LegendItem({ className, label }) {
  return (
    <span className="inline-flex items-center gap-1.5 text-xs text-muted-foreground">
      <span className={cn('h-2.5 w-2.5 rounded-full border', className)} />
      {label}
    </span>
  );
}

function MoneyMetric({ icon: Icon, label, value, hint, valueClassName }) {
  return (
    <div className="min-w-0 rounded-lg border border-border/60 bg-background/55 p-3">
      <div className="flex items-center gap-2">
        <Icon className="h-4 w-4 text-muted-foreground" />
        <p className="truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground">{label}</p>
      </div>
      <p className={cn('mt-2 font-mono text-xl font-bold tracking-tight', valueClassName || 'text-foreground')}>
        {fmt(value)}
      </p>
      {hint && <p className="mt-1 truncate text-xs text-muted-foreground">{hint}</p>}
    </div>
  );
}

function MoneyMap({ summaryData, loading }) {
  if (loading) {
    return (
      <Card>
        <CardContent className="grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-4">
          {Array.from({ length: 4 }).map((_, index) => (
            <div key={index} className="h-24 animate-pulse rounded-lg bg-muted" />
          ))}
        </CardContent>
      </Card>
    );
  }

  const starting = summaryData?.starting_amounts || {};
  const summary = summaryData?.summary || {};
  const available = Number(starting.combined_amount || 0);
  const assigned = Number(summary.expense_total || 0);
  const paid = Number(summary.paid_total || 0);
  const remaining = Number(summary.result || 0);
  const extraIncome = Number(starting.other_amount || 0);

  return (
    <Card className="overflow-hidden">
      <CardHeader className="pb-3">
        <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
          <div>
            <CardTitle className="text-base">Monthly Money Map</CardTitle>
            <CardDescription>Available money, extra income, assigned bills, and what remains.</CardDescription>
          </div>
          <Button asChild variant="outline" size="sm" className="w-full gap-2 sm:w-auto">
            <Link to="/summary">
              <WalletCards className="h-4 w-4" />
              Edit money plan
            </Link>
          </Button>
        </div>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
          <MoneyMetric icon={Banknote} label="Available" value={available} hint="1st + 15th + extra" />
          <MoneyMetric icon={PiggyBank} label="Extra Income" value={extraIncome} hint="Extra beyond paychecks" valueClassName={extraIncome > 0 ? 'text-teal-500' : ''} />
          <MoneyMetric icon={CalendarDays} label="Assigned Bills" value={assigned} hint={`${summary.expense_count || 0} active bills`} />
          <MoneyMetric
            icon={CircleDollarSign}
            label="After Bills"
            value={remaining}
            hint={`${fmt(paid)} already paid`}
            valueClassName={remaining >= 0 ? 'text-emerald-500' : 'text-destructive'}
          />
        </div>

        <div className="grid gap-2 text-sm md:grid-cols-3">
          <div className="flex items-center justify-between gap-3 rounded-md bg-muted/35 px-3 py-2">
            <span className="text-muted-foreground">1st available</span>
            <span className="font-mono font-semibold">{fmt(starting.first_amount)}</span>
          </div>
          <div className="flex items-center justify-between gap-3 rounded-md bg-muted/35 px-3 py-2">
            <span className="text-muted-foreground">15th available</span>
            <span className="font-mono font-semibold">{fmt(starting.fifteenth_amount)}</span>
          </div>
          <div className="flex items-center justify-between gap-3 rounded-md bg-muted/35 px-3 py-2">
            <span className="text-muted-foreground">Monthly income</span>
            <span className="truncate font-mono font-semibold">{fmt(summaryData?.income?.amount)}</span>
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

function SummaryProgress({ summary }) {
  const percent = Number(summary?.paid_percent || 0);

  return (
    <Card className="overflow-hidden">
      <CardHeader className="pb-3">
        <div className="flex items-center gap-2">
          <CircleDollarSign className="h-4 w-4 text-emerald-500" />
          <CardTitle className="text-base">Total Expenses Paid</CardTitle>
        </div>
        <CardDescription>Monthly progress across active, unskipped bills.</CardDescription>
      </CardHeader>
      <CardContent>
        <div className="flex items-end justify-between gap-4">
          <div>
            <p className="font-mono text-2xl font-semibold tracking-tight">
              {fmt(summary?.paid_total)}
              <span className="mx-2 text-sm font-normal text-muted-foreground">/</span>
              <span className="text-base text-muted-foreground">{fmt(summary?.expected_total)}</span>
            </p>
            <p className="mt-1 text-sm text-muted-foreground">{fmt(summary?.remaining_total)} remaining</p>
          </div>
          <div className="text-right">
            <p className="text-2xl font-semibold">{percent}%</p>
            <p className="text-xs text-muted-foreground">paid</p>
          </div>
        </div>

        <div className="mt-4 h-3 overflow-hidden rounded-full bg-muted">
          <div
            className="h-full rounded-full bg-emerald-500 transition-all duration-500"
            style={{ width: `${percent}%` }}
          />
        </div>

        <div className="mt-3 flex flex-wrap gap-2 text-xs text-muted-foreground">
          <span>{summary?.bill_count || 0} active bills</span>
          <span>{summary?.paid_count || 0} paid</span>
          {!!summary?.skipped_count && <span>{summary.skipped_count} skipped</span>}
          {!!summary?.missed_count && <span className="text-destructive">{summary.missed_count} late or missed</span>}
        </div>
      </CardContent>
    </Card>
  );
}

function DayIndicators({ day, moneyMarker }) {
  const summary = day.status_summary;
  const hasPaid = summary.paid_count > 0;
  const hasDue = summary.due_count > summary.paid_count + summary.skipped_count + summary.missed_count;
  const hasSkipped = summary.skipped_count > 0;
  const hasMissed = summary.missed_count > 0;
  const paymentOnly = day.payments.length > 0 && day.bills_due.length === 0;

  return (
    <div className="mt-auto flex flex-wrap gap-1">
      {moneyMarker && <span className="h-1.5 w-1.5 rounded-full bg-teal-500 ring-1 ring-teal-500/30" title="Available money" />}
      {hasPaid && <span className="h-1.5 w-1.5 rounded-full bg-emerald-500" title="Paid" />}
      {(hasDue || paymentOnly) && <span className="h-1.5 w-1.5 rounded-full bg-primary" title="Due or payment" />}
      {hasSkipped && <span className="h-1.5 w-1.5 rounded-full bg-muted-foreground/50" title="Skipped" />}
      {hasMissed && <span className="h-1.5 w-1.5 rounded-full bg-destructive" title="Missed or late" />}
    </div>
  );
}

function CalendarGrid({ data, selectedDate, onSelectDay, moneyMarkers }) {
  const firstWeekday = new Date(data.year, data.month - 1, 1).getDay();
  const cells = [
    ...Array.from({ length: firstWeekday }, (_, index) => ({ type: 'blank', key: `blank-${index}` })),
    ...data.days.map(day => ({ type: 'day', key: day.date, day })),
  ];
  const today = todayStr();

  return (
    <Card className="overflow-hidden">
      <div className="grid grid-cols-7 border-b border-border/70 bg-muted/30">
        {WEEKDAYS.map(day => (
          <div key={day} className="px-1 py-2 text-center text-[11px] font-semibold uppercase tracking-wide text-muted-foreground sm:text-xs">
            {day}
          </div>
        ))}
      </div>

      <div className="grid grid-cols-7">
        {cells.map(cell => {
          if (cell.type === 'blank') {
            return <div key={cell.key} className="min-h-16 border-b border-r border-border/50 bg-muted/10 sm:min-h-24" />;
          }

          const day = cell.day;
          const isToday = day.date === today;
          const isSelected = day.date === selectedDate;
          const summary = day.status_summary;
          const moneyMarker = moneyMarkers?.[day.date] || null;
          const hasActivity = day.bills_due.length > 0 || day.payments.length > 0 || !!moneyMarker;
          const isPaidDay = summary.due_count > 0 && summary.paid_count >= summary.due_count - summary.skipped_count;
          const hasMissed = summary.missed_count > 0;

          return (
            <button
              key={day.date}
              type="button"
              onClick={() => onSelectDay(day)}
              className={cn(
                'flex min-h-16 flex-col border-b border-r border-border/50 p-1.5 text-left transition-colors sm:min-h-24 sm:p-2',
                'focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',
                hasActivity && 'bg-primary/[0.03] hover:bg-accent/60',
                isPaidDay && 'bg-emerald-500/[0.07]',
                hasMissed && 'bg-destructive/[0.08]',
                isSelected && 'ring-2 ring-primary ring-inset',
              )}
              aria-label={`View ${fmtDate(day.date)}`}
            >
              <div className="flex items-start justify-between gap-1">
                <span className={cn(
                  'flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium sm:text-sm',
                  isToday && 'border border-primary bg-primary/10 text-primary',
                )}>
                  {day.day}
                </span>
                {summary.due_count > 0 && (
                  <span className="rounded bg-background/75 px-1 font-mono text-[10px] text-muted-foreground">
                    {summary.due_count}
                  </span>
                )}
              </div>

              <div className="mt-1 hidden min-w-0 space-y-0.5 sm:block">
                {moneyMarker && (
                  <p className="truncate font-mono text-[11px] font-semibold text-teal-500">
                    +{fmt(moneyMarker.amount)}
                  </p>
                )}
                {day.bills_due.slice(0, 2).map(bill => (
                  <p key={bill.bill_id} className="truncate text-[11px] text-muted-foreground">
                    {bill.name}
                  </p>
                ))}
                {day.bills_due.length > 2 && (
                  <p className="text-[11px] text-muted-foreground">+{day.bills_due.length - 2} more</p>
                )}
              </div>

              <DayIndicators day={day} moneyMarker={moneyMarker} />
            </button>
          );
        })}
      </div>
    </Card>
  );
}

function DebtPayoffGlance({ projection }) {
  const snowball = projection?.snowball;
  const comparison = projection?.comparison;
  const targetDebt = snowball?.debts?.[0] || null;
  const targetMonths = Number(targetDebt?.months || 0);
  const monthsSaved = comparison?.months_saved;

  return (
    <Card className="overflow-hidden">
      <CardHeader className="pb-3">
        <div className="flex items-center justify-between gap-3">
          <div className="flex items-center gap-2">
            <Target className="h-4 w-4 text-emerald-500" />
            <CardTitle className="text-base">Snowball Target</CardTitle>
          </div>
          <Badge variant="outline" className="border-emerald-500/25 bg-emerald-500/10 text-emerald-600 dark:text-emerald-300">
            Focus
          </Badge>
        </div>
        <CardDescription>Current payoff focus, with the final debt-free date close by.</CardDescription>
      </CardHeader>
      <CardContent>
        {snowball?.months_to_freedom ? (
          <div className="space-y-3">
            {targetDebt && (
              <div className="rounded-xl border border-emerald-500/25 bg-emerald-500/[0.08] p-3">
                <div className="flex items-start gap-3">
                  <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-emerald-500/15 text-emerald-600 dark:text-emerald-300">
                    <Target className="h-5 w-5" />
                  </span>
                  <div className="min-w-0">
                    <p className="text-xs font-semibold uppercase tracking-wide text-emerald-600 dark:text-emerald-300">
                      Target debt
                    </p>
                    <p className="mt-1 truncate text-lg font-semibold tracking-tight">{targetDebt.name}</p>
                    <p className="mt-1 text-sm text-muted-foreground">
                      Clears {targetDebt.payoff_display || 'on the current plan'}
                    </p>
                  </div>
                </div>

                <div className="mt-3 grid grid-cols-2 gap-2 text-sm">
                  <div className="rounded-lg border border-emerald-500/15 bg-background/65 p-3">
                    <p className="text-xs text-muted-foreground">Target runway</p>
                    <p className="font-mono font-semibold text-emerald-600 dark:text-emerald-300">
                      {targetMonths ? `${targetMonths} mo` : '—'}
                    </p>
                  </div>
                  <div className="rounded-lg border border-sky-500/15 bg-sky-500/[0.08] p-3">
                    <p className="text-xs text-muted-foreground">Debt-free</p>
                    <p className="font-semibold text-sky-600 dark:text-sky-300">{snowball.payoff_display}</p>
                  </div>
                </div>
              </div>
            )}

            <div className="grid grid-cols-2 gap-2 text-sm">
              <div className="rounded-lg border border-border/60 bg-muted/35 p-3">
                <div className="flex items-center gap-2">
                  <Trophy className="h-4 w-4 text-amber-500" />
                  <p className="text-xs text-muted-foreground">Time saved</p>
                </div>
                <p className="mt-2 font-mono font-semibold text-amber-600 dark:text-amber-300">
                  {monthsSaved !== undefined ? `${monthsSaved} mo` : '—'}
                </p>
              </div>
              <div className="rounded-lg border border-border/60 bg-muted/35 p-3">
                <div className="flex items-center gap-2">
                  <TrendingDown className="h-4 w-4 text-teal-500" />
                  <p className="text-xs text-muted-foreground">Interest</p>
                </div>
                <p className="mt-2 font-mono font-semibold">{fmt(snowball.total_interest_paid)}</p>
              </div>
            </div>

            {!targetDebt && (
              <div className="rounded-lg border border-sky-500/25 bg-sky-500/[0.08] p-3">
                <p className="text-sm font-medium text-sky-700 dark:text-sky-300">Projection ready</p>
                <p className="mt-1 text-sm text-muted-foreground">
                  Open Snowball to review the active payoff order.
                </p>
              </div>
            )}

            <div className="grid grid-cols-2 gap-2 text-sm">
              <div className="rounded-lg bg-muted/30 p-3">
                <p className="text-xs text-muted-foreground">Full plan</p>
                <p className="font-mono font-semibold">{snowball.months_to_freedom} mo</p>
              </div>
              <div className="rounded-lg bg-muted/30 p-3">
                <p className="text-xs text-muted-foreground">Interest saved</p>
                <p className="font-mono font-semibold text-emerald-500">
                  {comparison ? fmt(comparison.interest_saved) : '—'}
                </p>
              </div>
            </div>
            <Button asChild variant="outline" size="sm" className="w-full border-emerald-500/30 text-emerald-700 hover:bg-emerald-500/10 dark:text-emerald-300">
              <Link to="/snowball">Open Snowball</Link>
            </Button>
          </div>
        ) : (
          <div className="space-y-3 rounded-xl border border-sky-500/25 bg-sky-500/[0.08] p-3">
            <div className="flex items-start gap-3">
              <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-sky-500/15 text-sky-600 dark:text-sky-300">
                <Target className="h-5 w-5" />
              </span>
              <div>
                <p className="text-sm font-medium">Choose a first target</p>
                <p className="mt-1 text-sm text-muted-foreground">
                  Add debt balances and minimum payments to see the next payoff milestone here.
                </p>
              </div>
            </div>
            <Button asChild variant="outline" size="sm" className="w-full border-sky-500/30 text-sky-700 hover:bg-sky-500/10 dark:text-sky-300">
              <Link to="/snowball">Set up Snowball</Link>
            </Button>
          </div>
        )}
      </CardContent>
    </Card>
  );
}

function DayDetailDialog({ day, open, onOpenChange, moneyMarker }) {
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg border-border/60 bg-card/95 backdrop-blur-xl">
        <DialogHeader>
          <DialogTitle className="text-base font-semibold">{day ? fmtDate(day.date) : 'Day details'}</DialogTitle>
          <p className="text-sm text-muted-foreground">Bills due and payments recorded for this date.</p>
        </DialogHeader>

        {day && (
          <div className="space-y-5">
            {moneyMarker && (
              <section className="rounded-lg border border-teal-500/25 bg-teal-500/10 p-3">
                <h3 className="text-xs font-semibold uppercase tracking-wide text-teal-600 dark:text-teal-300">
                  Available Money
                </h3>
                <p className="mt-1 font-mono text-lg font-semibold text-teal-600 dark:text-teal-300">
                  +{fmt(moneyMarker.amount)}
                </p>
                <p className="text-xs text-muted-foreground">{moneyMarker.label}</p>
              </section>
            )}
            <section>
              <h3 className="mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground">Bills Due</h3>
              {day.bills_due.length === 0 ? (
                <div className="rounded-lg border border-dashed border-border/70 p-4 text-sm text-muted-foreground">
                  No bills are due on this day.
                </div>
              ) : (
                <div className="space-y-2">
                  {day.bills_due.map(bill => (
                    <div key={bill.bill_id} className="rounded-lg border border-border/60 bg-background/60 p-3">
                      <div className="flex items-start justify-between gap-3">
                        <div className="min-w-0">
                          <p className="truncate text-sm font-medium">{bill.name}</p>
                          <p className="mt-0.5 text-xs text-muted-foreground">{bill.category_name || 'Uncategorized'}</p>
                        </div>
                        <Badge variant="outline" className={cn('shrink-0 capitalize', statusTone(bill.status))}>
                          {displayStatus(bill.status)}
                        </Badge>
                      </div>
                      <div className="mt-3 grid grid-cols-3 gap-2 text-xs text-muted-foreground">
                        <div>
                          <p>Expected</p>
                          <p className="font-mono text-sm text-foreground">{fmt(bill.effective_amount)}</p>
                        </div>
                        <div>
                          <p>Paid</p>
                          <p className="font-mono text-sm text-emerald-500">{fmt(bill.paid_amount)}</p>
                        </div>
                        <div>
                          <p>Due</p>
                          <p className="font-mono text-sm text-foreground">{fmtDate(bill.due_date)}</p>
                        </div>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </section>

            <section>
              <h3 className="mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground">Payments</h3>
              {day.payments.length === 0 ? (
                <div className="rounded-lg border border-dashed border-border/70 p-4 text-sm text-muted-foreground">
                  No payments were recorded on this day.
                </div>
              ) : (
                <div className="space-y-2">
                  {day.payments.map(payment => (
                    <div key={payment.payment_id} className="flex items-center justify-between gap-3 rounded-lg border border-border/60 bg-background/60 p-3">
                      <div className="min-w-0">
                        <p className="truncate text-sm font-medium">{payment.bill_name}</p>
                        <p className="text-xs text-muted-foreground">{payment.method || 'Payment'}</p>
                      </div>
                      <span className="font-mono text-sm text-emerald-500">{fmt(payment.amount)}</span>
                    </div>
                  ))}
                </div>
              )}
            </section>

            <div className="flex flex-wrap justify-end gap-2 border-t border-border/60 pt-4">
              <Button asChild variant="outline" size="sm">
                <Link to="/">Open Tracker</Link>
              </Button>
              <Button asChild size="sm">
                <Link to="/bills">Manage Bills</Link>
              </Button>
            </div>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}

export default function CalendarPage() {
  const initial = currentMonth();
  const [year, setYear] = useState(initial.year);
  const [month, setMonth] = useState(initial.month);
  const [data, setData] = useState(null);
  const [summaryData, setSummaryData] = useState(null);
  const [snowballProjection, setSnowballProjection] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [selectedDay, setSelectedDay] = useState(null);
  const [detailOpen, setDetailOpen] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const [calendarResult, summaryResult, snowballResult] = await Promise.allSettled([
        api.calendar(year, month),
        api.summary(year, month),
        api.snowballProjection(),
      ]);

      if (calendarResult.status === 'rejected') {
        throw calendarResult.reason;
      }

      const result = calendarResult.value;
      setData(result);
      setSummaryData(summaryResult.status === 'fulfilled' ? summaryResult.value : null);
      setSnowballProjection(snowballResult.status === 'fulfilled' ? snowballResult.value : null);
      setSelectedDay(current => current ? result.days.find(day => day.date === current.date) || null : null);
    } catch (err) {
      setError(err.message || 'Calendar data could not be loaded.');
      toast.error(err.message || 'Calendar data could not be loaded.');
    } finally {
      setLoading(false);
    }
  }, [year, month]);

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

  const monthLabel = useMemo(() => `${MONTHS[month - 1]} ${year}`, [year, month]);
  const hasAnyBills = Number(data?.summary?.bill_count || 0) + Number(data?.summary?.skipped_count || 0) > 0;
  const moneyMarkers = useMemo(() => {
    const starting = summaryData?.starting_amounts;
    if (!starting) return {};

    const markers = {};
    const firstAmount = Number(starting.first_amount || 0);
    const fifteenthAmount = Number(starting.fifteenth_amount || 0);

    if (firstAmount > 0) {
      markers[`${year}-${String(month).padStart(2, '0')}-01`] = {
        label: '1st available',
        amount: firstAmount,
      };
    }
    if (fifteenthAmount > 0) {
      markers[`${year}-${String(month).padStart(2, '0')}-15`] = {
        label: '15th available',
        amount: fifteenthAmount,
      };
    }

    return markers;
  }, [month, summaryData, year]);
  const selectedMoneyMarker = selectedDay ? moneyMarkers[selectedDay.date] || null : null;

  function navigate(delta) {
    const next = shiftMonth(year, month, delta);
    setYear(next.year);
    setMonth(next.month);
    setSelectedDay(null);
    setDetailOpen(false);
  }

  function goToday() {
    const next = currentMonth();
    setYear(next.year);
    setMonth(next.month);
    setSelectedDay(null);
    setDetailOpen(false);
  }

  return (
    <div className="space-y-5">
      <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
        <div>
          <p className="mb-1 text-[11px] font-semibold uppercase tracking-[0.15em] text-muted-foreground">
            Monthly Calendar
          </p>
          <h1 className="text-3xl font-semibold tracking-tight">Calendar</h1>
          <p className="mt-1 text-sm text-muted-foreground">
            View bills, payments, and monthly progress by date.
          </p>
        </div>

        <div className="flex flex-wrap items-center gap-2">
          <div className="flex items-center rounded-full border border-border/70 bg-card/90 p-1 shadow-sm">
            <Button variant="ghost" size="icon" className="h-8 w-8 rounded-full" onClick={() => navigate(-1)} aria-label="Previous month">
              <ChevronLeft className="h-4 w-4" />
            </Button>
            <div className="min-w-40 px-3 text-center text-sm font-semibold">{monthLabel}</div>
            <Button variant="ghost" size="icon" className="h-8 w-8 rounded-full" onClick={() => navigate(1)} aria-label="Next month">
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>
          <Button variant="outline" size="sm" onClick={goToday}>Today</Button>
          <Button variant="ghost" size="icon" className="h-9 w-9 rounded-full" onClick={load} aria-label="Refresh calendar">
            <RefreshCw className={cn('h-4 w-4', loading && 'animate-spin')} />
          </Button>
        </div>
      </div>

      <MoneyMap summaryData={summaryData} loading={loading} />

      <div className="grid gap-5 xl:grid-cols-[minmax(0,1fr)_360px]">
        <div className="space-y-4">
          <div className="flex flex-wrap items-center gap-3 rounded-xl border border-border/70 bg-card/70 px-4 py-3">
            <LegendItem className="border-emerald-500 bg-emerald-500" label="Paid" />
            <LegendItem className="border-primary bg-primary" label="Due" />
            <LegendItem className="border-teal-500 bg-teal-500 ring-1 ring-teal-500/30" label="Available money" />
            <LegendItem className="border-muted-foreground/50 bg-muted-foreground/50" label="Skipped" />
            <LegendItem className="border-destructive bg-destructive" label="Missed/Late" />
            <span className="inline-flex items-center gap-1.5 text-xs text-muted-foreground">
              <span className="h-5 w-5 rounded-full border border-primary bg-primary/10" />
              Today
            </span>
          </div>

          {loading && (
            <Card>
              <CardContent className="flex min-h-[360px] items-center justify-center p-6 text-sm text-muted-foreground">
                Loading calendar...
              </CardContent>
            </Card>
          )}

          {!loading && error && (
            <Card>
              <CardContent className="flex min-h-[260px] flex-col items-center justify-center gap-3 p-6 text-center">
                <p className="text-sm text-destructive">{error}</p>
                <Button variant="outline" size="sm" onClick={load}>Try again</Button>
              </CardContent>
            </Card>
          )}

          {!loading && !error && data && (
            <>
              <CalendarGrid
                data={data}
                selectedDate={selectedDay?.date}
                moneyMarkers={moneyMarkers}
                onSelectDay={day => {
                  setSelectedDay(day);
                  setDetailOpen(true);
                }}
              />
              {!hasAnyBills && (
                <Card>
                  <CardContent className="flex flex-col items-center justify-center gap-3 p-6 text-center">
                    <CalendarDays className="h-8 w-8 text-muted-foreground" />
                    <div>
                      <p className="text-sm font-medium">No bills on this calendar yet.</p>
                      <p className="mt-1 text-sm text-muted-foreground">Add a bill to start seeing due dates and payment progress.</p>
                    </div>
                    <Button asChild size="sm">
                      <Link to="/bills">Add bill</Link>
                    </Button>
                  </CardContent>
                </Card>
              )}
            </>
          )}
        </div>

        <div className="space-y-4">
          <SummaryProgress summary={data?.summary} />
          <DebtPayoffGlance projection={snowballProjection} />
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-base">Selected Day</CardTitle>
              <CardDescription>Tap a date to inspect bills and payments.</CardDescription>
            </CardHeader>
            <CardContent>
              {selectedDay ? (
                <div className="space-y-3">
                  <p className="text-sm font-semibold">{fmtDate(selectedDay.date)}</p>
                  <div className="grid grid-cols-2 gap-2 text-sm">
                    <div className="rounded-lg bg-muted/40 p-3">
                      <p className="text-xs text-muted-foreground">Due</p>
                      <p className="font-mono font-semibold">{fmt(selectedDay.status_summary.total_due)}</p>
                    </div>
                    <div className="rounded-lg bg-muted/40 p-3">
                      <p className="text-xs text-muted-foreground">Paid</p>
                      <p className="font-mono font-semibold text-emerald-500">{fmt(selectedDay.status_summary.total_paid)}</p>
                    </div>
                  </div>
                  <Button className="w-full" size="sm" onClick={() => setDetailOpen(true)}>
                    View day details
                  </Button>
                </div>
              ) : (
                <p className="text-sm text-muted-foreground">No day selected.</p>
              )}
            </CardContent>
          </Card>
        </div>
      </div>

      <DayDetailDialog
        day={selectedDay}
        moneyMarker={selectedMoneyMarker}
        open={detailOpen}
        onOpenChange={setDetailOpen}
      />
    </div>
  );
}
