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 { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton";
import { Textarea } from "@/components/ui/textarea";
import { signOut } from "@/lib/auth/client";
import { useCurrentUserState } from "@/lib/auth/use-current-user";
import {
  fetchProfile,
  listUserCards,
  toggleFollow,
  updateMyProfile,
} from "@/lib/server/api";
import type { CardItem, Profile } from "@/lib/types";

export const Route = createFileRoute("/u/$handle")({
  component: ProfilePage,
});

function ProfilePage() {
  const { handle } = Route.useParams();
  const { user } = useCurrentUserState();
  const [profile, setProfile] = useState<Profile | null | undefined>(undefined);
  const [cards, setCards] = useState<CardItem[] | null>(null);
  const [editing, setEditing] = useState(false);
  const [displayName, setDisplayName] = useState("");
  const [bio, setBio] = useState("");
  const [newHandle, setNewHandle] = useState("");
  const [busy, setBusy] = useState(false);

  function load() {
    return fetchProfile({ data: handle })
      .then(async (p) => {
        setProfile(p);
        if (p) {
          setDisplayName(p.displayName);
          setBio(p.bio);
          setNewHandle(p.handle);
          const c = await listUserCards({ data: p.userId });
          setCards(c);
        } else {
          setCards([]);
        }
      })
      .catch(() => {
        setProfile(null);
        setCards([]);
      });
  }

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

  if (profile === undefined) {
    return (
      <AppShell>
        <Skeleton className="h-40 w-full" />
      </AppShell>
    );
  }

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

  const isMe = user?.id === profile.userId;

  async function onFollow() {
    if (!user) {
      toast.message("Sign in to follow collectors");
      return;
    }
    try {
      const res = await toggleFollow({ data: profile!.userId });
      setProfile((p) =>
        p
          ? {
              ...p,
              isFollowing: res.following,
              followerCount: (p.followerCount ?? 0) + (res.following ? 1 : -1),
            }
          : p,
      );
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not follow");
    }
  }

  async function saveProfile(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    try {
      const updated = await updateMyProfile({
        data: {
          displayName,
          bio,
          handle: newHandle !== profile!.handle ? newHandle : undefined,
        },
      });
      toast.success("Profile updated");
      setEditing(false);
      if (updated.handle !== handle) {
        window.location.href = `/u/${updated.handle}`;
        return;
      }
      await load();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Update failed");
    } finally {
      setBusy(false);
    }
  }

  return (
    <AppShell>
      <div className="space-y-6 max-w-3xl mx-auto">
        <Card>
          <CardContent className="pt-6">
            <div className="flex flex-col sm:flex-row gap-4 sm:items-start">
              <Avatar className="h-20 w-20">
                {profile.avatarUrl ? <AvatarImage src={profile.avatarUrl} /> : null}
                <AvatarFallback className="text-2xl">
                  {profile.displayName.charAt(0)}
                </AvatarFallback>
              </Avatar>
              <div className="flex-1 min-w-0 space-y-2">
                <div>
                  <h1 className="text-2xl font-semibold tracking-tight">{profile.displayName}</h1>
                  <p className="text-muted text-sm">@{profile.handle}</p>
                </div>
                {profile.bio && <p className="text-sm text-fg/90 leading-relaxed">{profile.bio}</p>}
                <div className="flex flex-wrap gap-4 text-sm">
                  <span>
                    <strong className="text-fg">{profile.cardCount ?? cards?.length ?? 0}</strong>{" "}
                    <span className="text-muted">cards</span>
                  </span>
                  <span>
                    <strong className="text-fg">{profile.followerCount ?? 0}</strong>{" "}
                    <span className="text-muted">followers</span>
                  </span>
                  <span>
                    <strong className="text-fg">{profile.followingCount ?? 0}</strong>{" "}
                    <span className="text-muted">following</span>
                  </span>
                </div>
              </div>
              <div className="flex flex-wrap gap-2">
                {isMe ? (
                  <>
                    <Button variant="secondary" size="sm" onClick={() => setEditing((v) => !v)}>
                      {editing ? "Close" : "Edit profile"}
                    </Button>
                    <Button variant="ghost" size="sm" onClick={() => void signOut("/")}>
                      Sign out
                    </Button>
                  </>
                ) : (
                  <Button
                    size="sm"
                    variant={profile.isFollowing ? "secondary" : "default"}
                    onClick={() => void onFollow()}
                  >
                    {profile.isFollowing ? "Following" : "Follow"}
                  </Button>
                )}
              </div>
            </div>

            {isMe && editing && (
              <form onSubmit={saveProfile} className="mt-6 grid gap-3 border-t border-border pt-5">
                <div className="space-y-1.5">
                  <Label htmlFor="dn">Display name</Label>
                  <Input
                    id="dn"
                    value={displayName}
                    onChange={(e) => setDisplayName(e.target.value)}
                    maxLength={40}
                  />
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="h">Handle</Label>
                  <Input
                    id="h"
                    value={newHandle}
                    onChange={(e) => setNewHandle(e.target.value.toLowerCase())}
                    maxLength={24}
                  />
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="bio">Bio</Label>
                  <Textarea
                    id="bio"
                    value={bio}
                    onChange={(e) => setBio(e.target.value)}
                    maxLength={280}
                  />
                </div>
                <Button type="submit" disabled={busy} className="w-fit">
                  {busy ? "Saving…" : "Save changes"}
                </Button>
              </form>
            )}
          </CardContent>
        </Card>

        <div>
          <h2 className="font-display text-3xl tracking-wide mb-3">Collection</h2>
          {cards === null ? (
            <div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
              {Array.from({ length: 3 }).map((_, i) => (
                <Skeleton key={i} className="aspect-[3/5] w-full" />
              ))}
            </div>
          ) : cards.length === 0 ? (
            <p className="text-sm text-muted">No cards in this collection yet.</p>
          ) : (
            <div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
              {cards.map((c) => (
                <BaseballCard key={c.id} card={c} size="sm" className="w-full max-w-none" showOwner={false} />
              ))}
            </div>
          )}
        </div>
      </div>
    </AppShell>
  );
}
