import { useState } from 'react';
import { type Expense, type Person, type Transfer } from '@splint/shared';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Item, ItemContent, ItemTitle, ItemDescription, ItemActions } from '@/components/ui/item';
import { Pencil, Trash2 } from 'lucide-react';

interface Props {
  expenses: Expense[];
  transfers: Transfer[];
  people: Person[];
  onEditExpense: (expense: Expense) => void;
  onDeleteExpense: (id: string) => Promise<void>;
  onEditTransfer: (transfer: Transfer) => void;
  onDeleteTransfer: (id: string) => Promise<void>;
}

/** Format an ISO date string as "DD-MMMM-YYYY - HH:mm (AM/PM)". */
function formatDate(iso: string): string {
  const d = new Date(iso);
  const day = d.getDate().toString().padStart(2, '0');
  const months = ['January', 'February', 'March', 'April', 'May', 'June',
    'July', 'August', 'September', 'October', 'November', 'December'];
  const month = months[d.getMonth()];
  const year = d.getFullYear();
  let hours = d.getHours();
  const ampm = hours >= 12 ? 'PM' : 'AM';
  hours = hours % 12 || 12;
  const mins = d.getMinutes().toString().padStart(2, '0');
  return `${day}-${month}-${year} - ${hours}:${mins} ${ampm}`;
}

/** Merge expenses and transfers into a single chronological timeline. */
export function ExpenseTimeline({
  expenses,
  transfers,
  people,
  onEditExpense,
  onDeleteExpense,
  onEditTransfer,
  onDeleteTransfer,
}: Props) {
  const getName = (id: string) => people.find((p) => p.id === id)?.name ?? '?';
  const [deleteExpenseId, setDeleteExpenseId] = useState<string | null>(null);
  const [deleteTransferId, setDeleteTransferId] = useState<string | null>(null);

  async function handleDeleteExpense(id: string) {
    try {
      await onDeleteExpense(id);
      setDeleteExpenseId(null);
    } catch {
      /* delete error is silent */
    }
  }

  async function handleDeleteTransfer(id: string) {
    try {
      await onDeleteTransfer(id);
      setDeleteTransferId(null);
    } catch {
      /* delete error is silent */
    }
  }

  const events: { kind: 'expense' | 'transfer'; date: string; item: Expense | Transfer }[] = [
    ...expenses.map((e) => ({ kind: 'expense' as const, date: e.createdAt, item: e })),
    ...transfers.map((t) => ({ kind: 'transfer' as const, date: t.createdAt, item: t })),
  ].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

  if (events.length === 0) {
    return <p className="text-xs text-muted-foreground">No activity yet. Add expenses or transfers to see the timeline.</p>;
  }

  return (
    <div role="list" aria-label="Activity timeline">
      {events.map((event) => {
        if (event.kind === 'expense') {
          const e = event.item as Expense;

          if (deleteExpenseId === e.id) {
            return (
              <div
                key={e.id}
                className="flex flex-col gap-2 py-3 border-b border-border last:border-0"
              >
                <p className="text-xs text-muted-foreground">
                  Delete &quot;<strong>{e.description}</strong>&quot; ($
                  {(e.amount / 100).toFixed(2)})?
                </p>
                <div className="flex gap-2">
                  <Button
                    variant="destructive"
                    size="sm"
                    onClick={() => handleDeleteExpense(e.id)}
                  >
                    Delete
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setDeleteExpenseId(null)}
                  >
                    Keep
                  </Button>
                </div>
              </div>
            );
          }

          return (
            <Item key={e.id} variant="outline" size="xs" role="listitem">
              <ItemContent>
                <ItemTitle>
                  <Badge variant="secondary" className="text-[0.65rem] px-1.5 py-0 shrink-0">
                    EXP
                  </Badge>
                  <span className="font-medium truncate">{e.description}</span>
                  <span className="text-primary font-medium shrink-0 ml-auto">${(e.amount / 100).toFixed(2)}</span>
                </ItemTitle>
                <ItemDescription>
                  <span>Paid by {getName(e.paidBy)} · {e.splitAmong.map(getName).join(', ')}</span>
                  <span className="block text-xs text-muted-foreground mt-0.5">{formatDate(e.createdAt)}</span>
                </ItemDescription>
              </ItemContent>
              <ItemActions>
                <Button
                  variant="ghost"
                  size="icon-sm"
                  onClick={() => onEditExpense(e)}
                  aria-label={`Edit ${e.description}`}
                >
                  <Pencil />
                </Button>
                <Button
                  variant="ghost"
                  size="icon-sm"
                  onClick={() => setDeleteExpenseId(e.id)}
                  aria-label={`Delete ${e.description}`}
                >
                  <Trash2 className="text-destructive" />
                </Button>
              </ItemActions>
            </Item>
          );
        } else {
          const t = event.item as Transfer;

          if (deleteTransferId === t.id) {
            return (
              <div
                key={t.id}
                className="flex flex-col gap-2 py-3 border-b border-border last:border-0"
              >
                <p className="text-xs text-muted-foreground">
                  Delete transfer: {getName(t.from)} → {getName(t.to)} ($
                  {(t.amount / 100).toFixed(2)})?
                </p>
                <div className="flex gap-2">
                  <Button
                    variant="destructive"
                    size="sm"
                    onClick={() => handleDeleteTransfer(t.id)}
                  >
                    Delete
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setDeleteTransferId(null)}
                  >
                    Keep
                  </Button>
                </div>
              </div>
            );
          }

          return (
            <Item key={t.id} variant="outline" size="xs" role="listitem">
              <ItemContent>
                <ItemTitle>
                  <Badge variant="secondary" className="text-[0.65rem] px-1.5 py-0 shrink-0">
                    TRF
                  </Badge>
                  <span>{getName(t.from)} → {getName(t.to)}</span>
                  <span className="text-primary font-medium shrink-0 ml-auto">${(t.amount / 100).toFixed(2)}</span>
                </ItemTitle>
                <ItemDescription>
                  <span>{formatDate(t.createdAt)}</span>
                </ItemDescription>
              </ItemContent>
              <ItemActions>
                <Button
                  variant="ghost"
                  size="icon-sm"
                  onClick={() => onEditTransfer(t)}
                  aria-label="Edit transfer"
                >
                  <Pencil />
                </Button>
                <Button
                  variant="ghost"
                  size="icon-sm"
                  onClick={() => setDeleteTransferId(t.id)}
                  aria-label="Delete transfer"
                >
                  <Trash2 className="text-destructive" />
                </Button>
              </ItemActions>
            </Item>
          );
        }
      })}
    </div>
  );
}
