import { createFileRoute } from "@tanstack/react-router";
import { useQuery } from "@tanstack/react-query";
import { useState, useEffect, useMemo } from "react";
import { motion } from "framer-motion";
import {
  ChevronLeft,
  ChevronRight,
  Shuffle,
  RotateCcw,
  Check,
  AlertCircle,
  Layers,
} from "lucide-react";
import { PageHeader } from "@/components/common/PageBits";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { Badge } from "@/components/ui/badge";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import { flashcardsService } from "@/services";
import { cn } from "@/lib/utils";

export const Route = createFileRoute("/_app/flashcards")({
  head: () => ({ meta: [{ title: "Flashcards — Study Unique" }] }),
  component: FlashcardsPage,
});

function FlashcardsPage() {
  const decks = useQuery({ queryKey: ["decks"], queryFn: flashcardsService.decks });
  const [deckId, setDeckId] = useState<string>("deck1");
  const cards = useQuery({
    queryKey: ["cards", deckId],
    queryFn: () => flashcardsService.cards(deckId),
    enabled: !!deckId,
  });

  const [order, setOrder] = useState<number[]>([]);
  const [idx, setIdx] = useState(0);
  const [flipped, setFlipped] = useState(false);
  const [marks, setMarks] = useState<Record<string, "known" | "difficult">>({});

  useEffect(() => {
    if (cards.data) {
      setOrder(cards.data.map((_, i) => i));
      setIdx(0);
      setFlipped(false);
      setMarks({});
    }
  }, [cards.data]);

  const current = cards.data?.[order[idx] ?? 0];

  const next = useMemo(
    () => () => {
      setFlipped(false);
      setIdx((i) => Math.min(order.length - 1, i + 1));
    },
    [order.length],
  );
  const prev = useMemo(
    () => () => {
      setFlipped(false);
      setIdx((i) => Math.max(0, i - 1));
    },
    [],
  );
  const shuffle = () => {
    const o = [...order].sort(() => Math.random() - 0.5);
    setOrder(o);
    setIdx(0);
    setFlipped(false);
  };
  const reset = () => {
    if (cards.data) setOrder(cards.data.map((_, i) => i));
    setIdx(0);
    setFlipped(false);
    setMarks({});
  };
  const mark = (m: "known" | "difficult") => {
    if (!current) return;
    setMarks((p) => ({ ...p, [current.id]: m }));
    next();
  };

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === " ") {
        e.preventDefault();
        setFlipped((f) => !f);
      } else if (e.key === "ArrowRight") next();
      else if (e.key === "ArrowLeft") prev();
      else if (e.key.toLowerCase() === "k") mark("known");
      else if (e.key.toLowerCase() === "d") mark("difficult");
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [current?.id, next, prev]);

  const progress = order.length ? ((idx + 1) / order.length) * 100 : 0;
  const known = Object.values(marks).filter((m) => m === "known").length;
  const difficult = Object.values(marks).filter((m) => m === "difficult").length;

  return (
    <div className="mx-auto w-full max-w-4xl space-y-6 p-4 md:p-6">
      <PageHeader
        title="Flashcards"
        description="Spaced-repetition decks generated from your documents."
        actions={
          <Select value={deckId} onValueChange={setDeckId}>
            <SelectTrigger className="w-[220px]">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {(decks.data ?? []).map((d) => (
                <SelectItem key={d.id} value={d.id}>
                  {d.title} ({d.cardCount})
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        }
      />

      <div className="grid grid-cols-3 gap-3">
        <div className="rounded-xl border border-border bg-card p-3 text-center">
          <p className="text-xs text-muted-foreground">Card</p>
          <p className="text-lg font-semibold">{order.length ? idx + 1 : 0} / {order.length}</p>
        </div>
        <div className="rounded-xl border border-border bg-card p-3 text-center">
          <p className="text-xs text-success">Known</p>
          <p className="text-lg font-semibold">{known}</p>
        </div>
        <div className="rounded-xl border border-border bg-card p-3 text-center">
          <p className="text-xs text-warning">Difficult</p>
          <p className="text-lg font-semibold">{difficult}</p>
        </div>
      </div>
      <Progress value={progress} className="h-1.5" />

      {cards.isLoading || !current ? (
        <Skeleton className="h-80 w-full rounded-3xl" />
      ) : (
        <div className="relative flex flex-col items-center">
          <button
            onClick={() => setFlipped((f) => !f)}
            className="group relative h-80 w-full max-w-2xl [perspective:1200px]"
            aria-label="Flip card"
          >
            <motion.div
              className="relative h-full w-full [transform-style:preserve-3d]"
              animate={{ rotateY: flipped ? 180 : 0 }}
              transition={{ duration: 0.5 }}
            >
              <CardFace>
                <Badge variant="outline" className="absolute left-4 top-4 text-[10px]">
                  Question
                </Badge>
                <p className="text-2xl font-semibold tracking-tight">{current.front}</p>
                <p className="absolute bottom-4 right-4 text-[10px] text-muted-foreground">
                  Tap or press Space to flip
                </p>
              </CardFace>
              <CardFace back>
                <Badge variant="outline" className="absolute left-4 top-4 text-[10px]">
                  Answer
                </Badge>
                <p className="text-lg leading-relaxed">{current.back}</p>
              </CardFace>
            </motion.div>
          </button>

          <div className="mt-6 flex flex-wrap items-center justify-center gap-2">
            <Button variant="outline" size="sm" onClick={prev}>
              <ChevronLeft className="mr-1 h-4 w-4" /> Prev
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={() => mark("difficult")}
              className="border-warning/40 text-warning hover:bg-warning/10"
            >
              <AlertCircle className="mr-1 h-4 w-4" /> Difficult <kbd className="ml-1 text-[10px] opacity-60">D</kbd>
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={() => mark("known")}
              className="border-success/40 text-success hover:bg-success/10"
            >
              <Check className="mr-1 h-4 w-4" /> Known <kbd className="ml-1 text-[10px] opacity-60">K</kbd>
            </Button>
            <Button variant="outline" size="sm" onClick={next}>
              Next <ChevronRight className="ml-1 h-4 w-4" />
            </Button>
            <Button variant="ghost" size="sm" onClick={shuffle}>
              <Shuffle className="mr-1 h-4 w-4" /> Shuffle
            </Button>
            <Button variant="ghost" size="sm" onClick={reset}>
              <RotateCcw className="mr-1 h-4 w-4" /> Reset
            </Button>
          </div>

          <p className="mt-4 flex items-center gap-2 text-xs text-muted-foreground">
            <Layers className="h-3.5 w-3.5" /> Shortcuts: Space flips • ← → navigates • K known • D difficult
          </p>
        </div>
      )}
    </div>
  );
}

function CardFace({ children, back }: { children: React.ReactNode; back?: boolean }) {
  return (
    <div
      className={cn(
        "absolute inset-0 flex items-center justify-center rounded-3xl border border-border bg-card p-10 text-center shadow-xl [backface-visibility:hidden]",
        back && "[transform:rotateY(180deg)]",
      )}
    >
      <div className="absolute inset-0 -z-10 gradient-mesh opacity-20" aria-hidden />
      {children}
    </div>
  );
}
