import { createFileRoute, Link } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { BaseballCard } from "@/components/cards/baseball-card";
import { AppShell } from "@/components/layout/app-shell";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import { Textarea } from "@/components/ui/textarea";
import { useCurrentUserState } from "@/lib/auth/use-current-user";
import { getCard, listMyCards, proposeTrade, toggleCardTrade } from "@/lib/server/api";
import type { CardItem } from "@/lib/types";

export const Route = createFileRoute("/cards/$cardId")({
  component: CardDetailPage,
});

function CardDetailPage() {
  const { cardId } = Route.useParams();
  const { user } = useCurrentUserState();
  const [card, setCard] = useState<CardItem | null | undefined>(undefined);
  const [myCards, setMyCards] = useState<CardItem[]>([]);
  const [tradeOpen, setTradeOpen] = useState(false);
  const [offerId, setOfferId] = useState<string>("");
  const [message, setMessage] = useState("");
  const [busy, setBusy] = useState(false);

  useEffect(() => {
    let cancelled = false;
    void getCard({ data: cardId })
      .then((c) => {
        if (!cancelled) setCard(c);
      })
      .catch(() => {
        if (!cancelled) setCard(null);
      });
    return () => {
      cancelled = true;
    };
  }, [cardId]);

  useEffect(() => {
    if (!user) return;
    void listMyCards()
      .then(setMyCards)
      .catch(() => setMyCards([]));
  }, [user?.id]);

  if (card === undefined) {
    return (
      <AppShell>
        <Skeleton className="h-80 w-full max-w-md mx-auto" />
      </AppShell>
    );
  }

  if (!card) {
    return (
      <AppShell>
        <div className="text-center py-16 space-y-3">
          <p className="font-medium">Card not found</p>
          <Button asChild variant="secondary">
            <Link to="/marketplace">Back to market</Link>
          </Button>
        </div>
      </AppShell>
    );
  }

  const current = card;
  const isOwner = user?.id === current.ownerId;
  const canTrade = Boolean(user && !isOwner && current.forTrade && myCards.length > 0);

  async function submitTrade() {
    if (!offerId) {
      toast.error("Pick a card to offer");
      return;
    }
    setBusy(true);
    try {
      await proposeTrade({
        data: {
          offeredCardId: offerId,
          requestedCardId: current.id,
          message,
        },
      });
      toast.success("Trade proposed");
      setTradeOpen(false);
      setMessage("");
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Trade failed");
    } finally {
      setBusy(false);
    }
  }

  async function flipTrade() {
    try {
      const updated = await toggleCardTrade({
        data: { cardId: current.id, forTrade: !current.forTrade },
      });
      setCard(updated);
      toast.success(updated.forTrade ? "Open for trade" : "Removed from market");
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Update failed");
    }
  }

  return (
    <AppShell>
      <div className="grid gap-8 md:grid-cols-[auto_1fr] md:items-start max-w-3xl mx-auto">
        <BaseballCard card={current} size="lg" interactive={false} className="mx-auto" />

        <div className="space-y-4">
          <div>
            <div className="flex flex-wrap items-center gap-2 mb-2">
              <Badge variant={current.rarity} className="capitalize">
                {current.rarity}
              </Badge>
              {current.forTrade && <Badge variant="success">Open for trade</Badge>}
            </div>
            <h1 className="font-display text-5xl tracking-wide leading-none">{current.playerName}</h1>
            <p className="text-muted mt-1">
              {current.team} · {current.position} · {current.seasonYear}
            </p>
          </div>

          {current.ownerHandle && (
            <p className="text-sm">
              Owned by{" "}
              <Link
                to="/u/$handle"
                params={{ handle: current.ownerHandle }}
                className="font-medium text-accent hover:underline"
              >
                @{current.ownerHandle}
              </Link>
            </p>
          )}

          {current.description && (
            <Card>
              <CardHeader className="pb-2">
                <CardTitle className="text-base">About</CardTitle>
              </CardHeader>
              <CardContent>
                <p className="text-sm text-muted leading-relaxed">{current.description}</p>
              </CardContent>
            </Card>
          )}

          <div className="flex flex-wrap gap-2">
            {isOwner && (
              <Button variant="secondary" onClick={() => void flipTrade()}>
                {current.forTrade ? "Unlist from market" : "List for trade"}
              </Button>
            )}
            {canTrade && (
              <Button onClick={() => setTradeOpen(true)}>Propose trade</Button>
            )}
            {!user && current.forTrade && (
              <Button asChild>
                <Link to="/login">Sign in to trade</Link>
              </Button>
            )}
            {user && !isOwner && !current.forTrade && (
              <p className="text-sm text-muted self-center">Not currently open for trade.</p>
            )}
          </div>
        </div>
      </div>

      <Dialog open={tradeOpen} onOpenChange={setTradeOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Propose trade</DialogTitle>
            <DialogDescription>
              Offer one of your cards for {current.playerName}.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            <div className="space-y-1.5">
              <Label>Your offer</Label>
              <Select value={offerId} onValueChange={setOfferId}>
                <SelectTrigger>
                  <SelectValue placeholder="Select a card" />
                </SelectTrigger>
                <SelectContent>
                  {myCards.map((c) => (
                    <SelectItem key={c.id} value={c.id}>
                      {c.playerName} · {c.team} ({c.rarity})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label>Message (optional)</Label>
              <Textarea
                value={message}
                onChange={(e) => setMessage(e.target.value)}
                placeholder="Add a note for the owner…"
                maxLength={280}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="secondary" onClick={() => setTradeOpen(false)}>
              Cancel
            </Button>
            <Button onClick={() => void submitTrade()} disabled={busy || !offerId}>
              {busy ? "Sending…" : "Send offer"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </AppShell>
  );
}
