"use client";

import { Suspense, useCallback, useEffect, useState } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import Link from "next/link";
import { motion } from "framer-motion";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { AnimatedSection } from "@/components/animated-section";

const SPREAD_COUNT: Record<string, number> = { "7-card": 7, "18-card": 18, "48-card": 48 };
const FOLLOW_UP_COUNT = 10;

const CARD_BACK_IMAGE = "/cards/card-back.png";

interface TarotCardType {
  id: string;
  nameFa: string;
  slug: string;
  imageUrl: string;
  orderIndex: number;
}

function shuffleCards<T>(items: T[]): T[] {
  const arr = [...items];
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  return arr;
}

function toFaDigits(n: number): string {
  return n.toLocaleString("fa-IR");
}

function getGridClass(count: number): string {
  if (count === 18) return "grid-cols-3 sm:grid-cols-6";
  if (count === 7) return "grid-cols-4 sm:grid-cols-7";
  if (count === 48) return "grid-cols-4 sm:grid-cols-6 lg:grid-cols-8";
  if (count === 10) return "grid-cols-5";
  return "grid-cols-4 sm:grid-cols-6 md:grid-cols-8";
}

function TitleDiamond() {
  return (
    <span className="inline-block size-2 rotate-45 bg-amber-500/70 sm:size-2.5" aria-hidden />
  );
}

function SelectPageTitle({ count, followUp }: { count: number; followUp: boolean }) {
  return (
    <div className="mb-6 text-center md:mb-8">
      <h1 className="flex items-center justify-center gap-3 text-xl font-bold text-foreground sm:text-2xl md:gap-4">
        <TitleDiamond />
        {toFaDigits(count)} کارت انتخاب کنید
        <TitleDiamond />
      </h1>
      <p className="mt-3 text-sm text-foreground/75 sm:text-base">
        {followUp
          ? "۱۰ کارت برای پاسخ به سوال خود انتخاب کنید. پس از انتخاب، دکمه تأیید را بزنید."
          : "روی کارت‌ها کلیک کنید. پس از انتخاب، دکمه تأیید را بزنید."}
      </p>
    </div>
  );
}

function CardBackImage({ eager }: { eager?: boolean }) {
  return (
    // eslint-disable-next-line @next/next/no-img-element
    <img
      src={CARD_BACK_IMAGE}
      alt="پشت کارت"
      loading={eager ? "eager" : "lazy"}
      decoding="async"
      className="h-full w-full object-cover"
      draggable={false}
    />
  );
}

function ReadingSelectPageContent() {
  const searchParams = useSearchParams();
  const router = useRouter();
  const readingId = searchParams.get("readingId");
  const followUp = searchParams.get("followUp") === "1";

  const [reading, setReading] = useState<{ spreadType: string } | null>(null);
  const [cards, setCards] = useState<TarotCardType[]>([]);
  const [selected, setSelected] = useState<string[]>([]);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [fetchError, setFetchError] = useState<string | null>(null);

  const count = followUp ? FOLLOW_UP_COUNT : (reading ? SPREAD_COUNT[reading.spreadType] ?? 7 : 0);

  useEffect(() => {
    if (!readingId) {
      setFetchError("readingId لازم است");
      setLoading(false);
      return;
    }
    Promise.all([
      fetch(`/api/readings/${readingId}`).then((r) => (r.ok ? r.json() : null)),
      fetch("/api/cards").then((r) => r.json()).then((d) => (Array.isArray(d) ? d : [])),
    ])
      .then(([readingData, cardsData]) => {
        if (!readingData) {
          setFetchError("فال یافت نشد یا دسترسی ندارید.");
          return;
        }
        setReading(readingData);
        setCards(shuffleCards(cardsData));
      })
      .catch(() => setFetchError("خطا در بارگذاری"))
      .finally(() => setLoading(false));
  }, [readingId]);

  useEffect(() => {
    const link = document.createElement("link");
    link.rel = "preload";
    link.as = "image";
    link.href = CARD_BACK_IMAGE;
    document.head.appendChild(link);
    return () => {
      link.remove();
    };
  }, []);

  const toggle = useCallback(
    (id: string) => {
      setSelected((prev) => {
        if (prev.includes(id)) return prev.filter((x) => x !== id);
        if (prev.length >= count) return prev;
        return [...prev, id];
      });
    },
    [count]
  );

  async function handleConfirm() {
    if (!readingId || selected.length !== count) return;
    setSubmitting(true);
    try {
      if (followUp) {
        const res = await fetch(`/api/readings/${readingId}/follow-up`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ cardIds: selected }),
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error ?? "خطا");
        router.push(`/reading/result/${readingId}`);
      } else {
        const res = await fetch(`/api/readings/${readingId}/cards`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ cardIds: selected }),
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error ?? "خطا");
        router.push(`/checkout?readingId=${readingId}`);
      }
    } catch {
      setSubmitting(false);
    }
  }

  if (!readingId || fetchError) {
    return (
      <div className="container mx-auto px-4 py-12 text-center">
        <p>{fetchError ?? "شناسه فال معتبر نیست."}</p>
        <Link href="/reading" className="mt-4 inline-block underline">
          بازگشت به انتخاب نوع فال
        </Link>
      </div>
    );
  }

  if (loading || !reading) {
    return (
      <div className="container mx-auto px-4 py-8">
        <SelectPageTitle count={count || 18} followUp={followUp} />
        <div className="mx-auto max-w-5xl rounded-2xl bg-white/45 px-4 py-6 backdrop-blur-sm sm:px-6">
          <div className={`grid gap-3 sm:gap-4 ${getGridClass(count || 18)}`}>
            {Array.from({ length: 18 }).map((_, i) => (
              <Skeleton key={i} className="aspect-[200/340] rounded-lg" />
            ))}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="container mx-auto px-4 py-4 md:py-6">
      <SelectPageTitle count={count} followUp={followUp} />

      <div className="mx-auto max-w-5xl rounded-2xl bg-white/45 px-3 py-5 backdrop-blur-sm sm:px-6 sm:py-7">
        <div className={`grid gap-3 sm:gap-4 ${getGridClass(count)}`}>
          {cards.map((card, index) => {
            const isSelected = selected.includes(card.id);
            const selectionOrder = isSelected ? selected.indexOf(card.id) + 1 : null;

            return (
              <div key={card.id} className="flex flex-col items-center">
                <motion.button
                  type="button"
                  className={`relative w-full max-w-[120px] cursor-pointer overflow-hidden rounded-lg transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1a2e1a]/40 ${
                    isSelected
                      ? "ring-2 ring-[#1a2e1a] shadow-lg shadow-[#1a2e1a]/15"
                      : "hover:shadow-md"
                  } ${selected.length >= count && !isSelected ? "pointer-events-none opacity-50" : ""}`}
                  whileHover={selected.length >= count && !isSelected ? undefined : { scale: 1.04 }}
                  whileTap={{ scale: 0.98 }}
                  onClick={() => toggle(card.id)}
                >
                  <div className="relative aspect-[200/340] w-full">
                    <CardBackImage eager={index < 24} />
                    {isSelected && (
                      <div className="absolute inset-0 flex items-center justify-center bg-[#1a2e1a]/25">
                        <span className="text-lg font-bold text-white drop-shadow">
                          {toFaDigits(selectionOrder!)}
                        </span>
                      </div>
                    )}
                  </div>
                </motion.button>
                <p className="mt-1.5 text-center text-xs font-medium text-foreground/70">
                  {isSelected ? toFaDigits(selectionOrder!) : ""}
                </p>
              </div>
            );
          })}
        </div>
      </div>

      <AnimatedSection delay={0.15}>
        <div className="mt-8 flex flex-col items-center gap-4 md:mt-10">
          <p className="text-sm text-foreground/70">
            {toFaDigits(selected.length)} از {toFaDigits(count)} کارت انتخاب شده
          </p>
          <div className="flex flex-wrap justify-center gap-3">
            <Button
              variant="outline"
              asChild
              className="rounded-full border-foreground/20 bg-white/60 backdrop-blur-sm"
            >
              <Link href={followUp ? `/reading/result/${readingId}` : "/reading"}>
                {followUp ? "بازگشت به نتیجه" : "تغییر نوع فال"}
              </Link>
            </Button>
            <Button
              onClick={handleConfirm}
              disabled={selected.length !== count || submitting}
              className="rounded-full bg-[#1a2e1a] px-6 text-white hover:bg-[#243824]"
            >
              {submitting
                ? "در حال ثبت..."
                : followUp
                  ? "تأیید و مشاهده پاسخ"
                  : "تأیید و ادامه به پرداخت"}
            </Button>
          </div>
        </div>
      </AnimatedSection>
    </div>
  );
}

export default function ReadingSelectPage() {
  return (
    <Suspense fallback={null}>
      <ReadingSelectPageContent />
    </Suspense>
  );
}
