import { useState } from 'react';
import type { Transfer, Person } from '@splint/shared';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from '@/components/ui/select';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { Item, ItemContent, ItemTitle, ItemActions } from '@/components/ui/item';
import { Badge } from '@/components/ui/badge';
import { Trash2 } from 'lucide-react';

// ── Types ───────────────────────────────────────────────────────────────────

interface TransfersListProps {
  transfers: Transfer[];
  people: Person[];
  onRequestAdd: () => void;
  onDelete: (id: string) => Promise<void>;
  saving: boolean;
}

// ── TransferModal ───────────────────────────────────────────────────────────

interface TransferModalProps {
  people: Person[];
  editingTransfer: Transfer | null;
  onSave: (fields: { from: string; to: string; amount: number }) => Promise<void>;
  onClose: () => void;
  saving: boolean;
}

export function TransferModal({
  people,
  editingTransfer,
  onSave,
  onClose,
  saving,
}: TransferModalProps) {
  const [form, setForm] = useState({
    from: editingTransfer?.from ?? '',
    to: editingTransfer?.to ?? '',
    amount: editingTransfer ? (editingTransfer.amount / 100).toFixed(2) : '',
  });
  const [error, setError] = useState('');

  function validate(): boolean {
    if (!form.from) {
      setError('Select who is paying.');
      return false;
    }
    if (!form.to) {
      setError('Select who is receiving.');
      return false;
    }
    if (form.from === form.to) {
      setError('Cannot transfer to the same person.');
      return false;
    }
    const amt = parseFloat(form.amount);
    if (!form.amount || isNaN(amt) || amt <= 0) {
      setError('Amount must be greater than zero.');
      return false;
    }
    setError('');
    return true;
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!validate()) return;
    try {
      await onSave({
        from: form.from,
        to: form.to,
        amount: Math.round(parseFloat(form.amount) * 100),
      });
      onClose();
    } catch (err) {
      setError(
        err instanceof Error ? err.message : 'Failed to save transfer.',
      );
    }
  }

  return (
    <Dialog open={true} onOpenChange={(open) => !open && onClose()}>
      <DialogContent aria-label={editingTransfer ? 'Edit transfer' : 'Record transfer'}>
        <DialogHeader>
          <DialogTitle>
            {editingTransfer ? 'Edit Transfer' : 'Record Transfer'}
          </DialogTitle>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="tr-from">From</Label>
            <Select
              value={form.from}
              onValueChange={(value: string) => setForm({ ...form, from: value })}
            >
              <SelectTrigger id="tr-from" className="w-full">
                <SelectValue placeholder="Select..." />
              </SelectTrigger>
              <SelectContent>
                {people.map((p) => (
                  <SelectItem key={p.id} value={p.id}>
                    {p.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="tr-to">To</Label>
            <Select
              value={form.to}
              onValueChange={(value: string) => setForm({ ...form, to: value })}
            >
              <SelectTrigger id="tr-to" className="w-full">
                <SelectValue placeholder="Select..." />
              </SelectTrigger>
              <SelectContent>
                {people.map((p) => (
                  <SelectItem key={p.id} value={p.id}>
                    {p.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="tr-amount">Amount ($)</Label>
            <Input
              id="tr-amount"
              type="number"
              step="0.01"
              value={form.amount}
              onChange={(e) => setForm({ ...form, amount: e.target.value })}
              placeholder="0.00"
              autoFocus
            />
          </div>
          {error && (
            <p className="text-xs text-destructive" role="alert">
              {error}
            </p>
          )}
          <DialogFooter>
            <Button type="submit" disabled={saving}>
              {editingTransfer ? 'Save Changes' : 'Record Transfer'}
            </Button>
            <Button type="button" variant="outline" onClick={onClose}>
              Cancel
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

// ── TransfersList ───────────────────────────────────────────────────────────

export function TransfersList({
  transfers,
  people,
  onRequestAdd,
  onDelete,
  saving,
}: TransfersListProps) {
  const [deleteTransferId, setDeleteTransferId] = useState<string | null>(null);
  const isEmpty = transfers.length === 0;

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

  if (isEmpty) return null;

  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardTitle>Transfers</CardTitle>
        <Button size="sm" onClick={onRequestAdd}>
          + Add
        </Button>
      </CardHeader>
      <CardContent>
        <div role="list">
          {transfers.map((t) => {
            const from = people.find((p) => p.id === t.from);
            const to = people.find((p) => p.id === t.to);

            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: {from?.name ?? '?'} → {to?.name ?? '?'} ($
                    {(t.amount / 100).toFixed(2)})?
                  </p>
                  <div className="flex gap-2">
                    <Button
                      variant="destructive"
                      size="sm"
                      onClick={() => handleDelete(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>
                    <span>{from?.name ?? '?'} → {to?.name ?? '?'}</span>
                    <Badge variant="default" className="shrink-0 bg-primary/15 text-primary hover:bg-primary/20">
                      ${(t.amount / 100).toFixed(2)}
                    </Badge>
                  </ItemTitle>
                </ItemContent>
                <ItemActions>
                  <Button
                    variant="ghost"
                    size="icon-sm"
                    onClick={() => setDeleteTransferId(t.id)}
                    aria-label="Delete transfer"
                  >
                    <Trash2 className="text-destructive" />
                  </Button>
                </ItemActions>
              </Item>
            );
          })}
        </div>
      </CardContent>
    </Card>
  );
}
