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 } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { RedirectToSignIn } from "@/lib/auth/gates";
import { useCurrentUserState } from "@/lib/auth/use-current-user";
import { listMyTrades, respondTrade } from "@/lib/server/api";
import type { TradeItem } from "@/lib/types";
import { formatRelativeTime } from "@/lib/utils";

export const Route = createFileRoute("/trades")({
  component: TradesPage,
});

function TradesPage() {
  const { user, isPending } = useCurrentUserState();
  const [trades, setTrades] = useState<TradeItem[] | null>(null);

  function reload() {
    return listMyTrades()
      .then(setTrades)
      .catch(() => setTrades([]));
  }

  useEffect(() => {
    if (!user) return;
    void reload();
  }, [user?.id]);

  if (isPending) {
    return (
      <AppShell>
        <Skeleton className="h-40 w-full" />
      </AppShell>
    );
  }
  if (!user) return <RedirectToSignIn />;

  const incoming = trades?.filter((t) => t.toUserId === user.id) ?? [];
  const outgoing = trades?.filter((t) => t.fromUserId === user.id) ?? [];

  async function act(tradeId: string, action: "accept" | "decline" | "cancel") {
    try {
      await respondTrade({ data: { tradeId, action } });
      toast.success(
        action === "accept" ? "Trade completed" : action === "decline" ? "Trade declined" : "Trade cancelled",
      );
      await reload();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Action failed");
    }
  }

  return (
    <AppShell>
      <div className="space-y-5">
        <div>
          <h1 className="font-display text-4xl tracking-wide">Trades</h1>
          <p className="text-sm text-muted">Incoming offers and your proposals.</p>
        </div>

        {trades === null ? (
          <Skeleton className="h-48 w-full" />
        ) : (
          <Tabs defaultValue="incoming">
            <TabsList className="w-full sm:w-auto">
              <TabsTrigger value="incoming" className="flex-1 sm:flex-none">
                Incoming ({incoming.filter((t) => t.status === "pending").length})
              </TabsTrigger>
              <TabsTrigger value="outgoing" className="flex-1 sm:flex-none">
                Outgoing ({outgoing.length})
              </TabsTrigger>
            </TabsList>
            <TabsContent value="incoming" className="space-y-3">
              {incoming.length === 0 ? (
                <Empty label="No incoming trades yet. Browse the market and wait for offers." />
              ) : (
                incoming.map((t) => (
                  <TradeRow
                    key={t.id}
                    trade={t}
                    perspective="incoming"
                    onAct={act}
                  />
                ))
              )}
            </TabsContent>
            <TabsContent value="outgoing" className="space-y-3">
              {outgoing.length === 0 ? (
                <Empty label="You haven't proposed any trades. Find a card you want on the market." />
              ) : (
                outgoing.map((t) => (
                  <TradeRow
                    key={t.id}
                    trade={t}
                    perspective="outgoing"
                    onAct={act}
                  />
                ))
              )}
            </TabsContent>
          </Tabs>
        )}

        <div className="text-center">
          <Button asChild variant="secondary">
            <Link to="/marketplace">Browse marketplace</Link>
          </Button>
        </div>
      </div>
    </AppShell>
  );
}

function Empty({ label }: { label: string }) {
  return (
    <Card>
      <CardContent className="py-10 text-center text-sm text-muted">{label}</CardContent>
    </Card>
  );
}

function TradeRow({
  trade,
  perspective,
  onAct,
}: {
  trade: TradeItem;
  perspective: "incoming" | "outgoing";
  onAct: (id: string, action: "accept" | "decline" | "cancel") => Promise<void>;
}) {
  const statusVariant =
    trade.status === "accepted"
      ? "success"
      : trade.status === "pending"
        ? "accent"
        : trade.status === "declined"
          ? "danger"
          : "default";

  return (
    <Card>
      <CardContent className="pt-5 space-y-4">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <div className="text-sm">
            {perspective === "incoming" ? (
              <>
                From{" "}
                <Link
                  to="/u/$handle"
                  params={{ handle: trade.fromHandle }}
                  className="font-semibold hover:underline"
                >
                  @{trade.fromHandle}
                </Link>
              </>
            ) : (
              <>
                To{" "}
                <Link
                  to="/u/$handle"
                  params={{ handle: trade.toHandle }}
                  className="font-semibold hover:underline"
                >
                  @{trade.toHandle}
                </Link>
              </>
            )}
            <span className="text-subtle"> · {formatRelativeTime(trade.createdAt)}</span>
          </div>
          <Badge variant={statusVariant} className="capitalize">
            {trade.status}
          </Badge>
        </div>

        {trade.message && (
          <p className="text-sm text-muted border-l-2 border-border pl-3">{trade.message}</p>
        )}

        <div className="flex flex-wrap items-center justify-center gap-4 sm:gap-8">
          <div className="text-center space-y-1">
            <p className="text-[10px] uppercase tracking-wider text-subtle">
              {perspective === "incoming" ? "They offer" : "You offer"}
            </p>
            <BaseballCard card={trade.offeredCard} size="sm" showOwner={false} />
          </div>
          <span className="font-display text-2xl text-muted">⇄</span>
          <div className="text-center space-y-1">
            <p className="text-[10px] uppercase tracking-wider text-subtle">
              {perspective === "incoming" ? "For your" : "For their"}
            </p>
            <BaseballCard card={trade.requestedCard} size="sm" showOwner={false} />
          </div>
        </div>

        {trade.status === "pending" && (
          <div className="flex flex-wrap justify-end gap-2">
            {perspective === "incoming" ? (
              <>
                <Button variant="danger" size="sm" onClick={() => void onAct(trade.id, "decline")}>
                  Decline
                </Button>
                <Button size="sm" onClick={() => void onAct(trade.id, "accept")}>
                  Accept trade
                </Button>
              </>
            ) : (
              <Button variant="secondary" size="sm" onClick={() => void onAct(trade.id, "cancel")}>
                Cancel offer
              </Button>
            )}
          </div>
        )}
      </CardContent>
    </Card>
  );
}
