"use client";
import { useState, useEffect, useRef } from "react";
import "./css/turn.css";
import { IMAGE_BASE } from "@/constants";
import { setSelectedPackCover } from "../../../store/inventorySlice";
import { useAppDispatch } from "../../../lib/hooks";
import Link from "next/link";
import { redirect } from "next/navigation";

export default function Cards({
  is_last,
  mode,
  next,
  cards,
  pack,
  set_is_last,
  muted,
  getNext,
}) {
  const inRef = useRef(null);
  const [perRow, setPerRow] = useState(5);

  const [lastShake, setLastShake] = useState(false);

  const [rev, setRev] = useState(0);
  const [flipped, setFlipped] = useState(() => cards.map(() => false));
  const [total, setTotal] = useState(0);
  const [totalFx, setTotalFx] = useState(false);
  const pitchRef = useRef(0); // (cardWidth + gap)
  const arc = 17; // curve depth (increase/decrease)
  const gap = 7;
  const mutedRef = useRef(muted);
  const dispatch = useAppDispatch();
  const didRun = useRef(false);

  useEffect(() => {
    mutedRef.current = muted;
  }, [muted]);

  const doFlip = (i) => {
    const isLastCard = i === cards.length - 1;
    if (!isLastCard) {
      playSfx("/sfx/cardTurn.mp3");
    }

    setFlipped((prev) => {
      if (prev[i]) return prev;
      const copy = [...prev];
      copy[i] = true;
      return copy;
    });

    setRev((r) => r + 1);
  };

  const toggle = (i) => {
    const isLastCard = i === cards.length - 1;

    // last card locked
    if (isLastCard && rev < cards.length - 1) return;
    if (flipped[i]) return;

    // 👉 LAST CARD SPECIAL FLOW
    if (isLastCard) {
      setLastShake(true);
      playSfx("/sfx/lastCard.mp3");

      // shake duration ke baad flip
      setTimeout(() => {
        setLastShake(false);
        doFlip(i);
      }, 450); // same as shake animation duration

      return;
    }

    // normal cards
    doFlip(i);
  };

  const getCardValue = (card) => {
    const n = Number(card?.price ?? 0);
    return Number.isFinite(n) ? n : 0;
  };

  useEffect(() => {
    const sum = flipped.reduce((acc, isOn, idx) => {
      if (!isOn) return acc;

      // because cards are rendered in reverse order
      const realIndex = cards.length - 1 - idx;
      const card = cards?.[realIndex];

      return acc + getCardValue(card);
    }, 0);

    setTotal(sum);
  }, [flipped, cards]);

  useEffect(() => {
    if (!inRef.current) return;

    const el = inRef.current;

    const measure = () => {
      const first = el.querySelector(".flip");
      if (!first) return;

      const cardW = first.getBoundingClientRect().width;

      const styles = window.getComputedStyle(el);
      // ✅ real grid gap (works for gap / column-gap)
      const g = parseFloat(styles.columnGap || styles.gap || "0") || 0;

      pitchRef.current = cardW + g; // ✅ correct step
    };

    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);

    return () => ro.disconnect();
  }, [cards.length, perRow]);

  useEffect(() => {
    if (cards.length > 0 && cards.length == rev) {
      set_is_last(true);
    }
  }, [rev]);

  useEffect(() => {
    setFlipped(cards.map(() => false));

    setTotal(0);
    setRev(0);
  }, [cards.length]);

  useEffect(() => {
    // first render par unwanted shake avoid:
    if (rev === 0) return;

    setTotalFx(true);
    const t = setTimeout(() => setTotalFx(false), 220); // animation duration jitna
    return () => clearTimeout(t);
  }, [total]);

  const playSfx = (src) => {
    if (mutedRef.current) return;
    const audio = new Audio(src);
    audio.volume = 0.6;
    audio.play().catch(() => {
      // mobile browsers user gesture ke baghair block kar dete hain
    });
  };

  useEffect(() => {
    if (didRun.current) return;
    didRun.current = true;
    playSfx("/sfx/stackPlaced.mp3");
    getNext();
  }, []);

  // helper (optional)
  const clamp = (n, min, max) => Math.max(min, Math.min(max, n));

  useEffect(() => {
    const updatePerRow = () => {
      const w = window.innerWidth;

      // ✅ Mobile behavior same as before for ALL brands
      if (w < 640) {
        setPerRow(2);
        return;
      }
      if (w < 768) {
        setPerRow(3);
        return;
      }
      if (w < 1024) {
        setPerRow(4);
        return;
      }
      // ✅ Desktop rules:
      // MTG => 4 in a row
      if (pack?.brand === "MTG") {
        setPerRow(4);
        return;
      }

      // ✅ Pokemon/Lorcana/others => always 2 rows on big screens
      const forced = Math.ceil((cards?.length || 0) / 2) || 1;

      // keep it in range (optional)
      setPerRow(Math.max(1, Math.min(forced, 8)));
    };

    updatePerRow();
    window.addEventListener("resize", updatePerRow);
    return () => window.removeEventListener("resize", updatePerRow);
  }, [pack?.brand, cards.length]);

  return (
    <>
      <div className="cards turn no-scrollbar mt-14 mb-2 ">
        <div
          className="in pt-7 2xl:pt-4"
          ref={inRef}
          // style={{ "--perRow": perRow, "--gap": "10px" }}
          style={{ "--perRow": perRow, "--gap": `${0 + gap}px` }}
        >
          {(() => {
            const floatDuration = 2.8; // seconds (same as CSS)

            const arcOffset = (pos, total) => {
              const t = total <= 1 ? 0 : (pos / (total - 1)) * 2 - 1; // -1..1
              return -arc * (1 - t * t); // ∩ : ends 0, center -arc
            };

            const maxTilt = 4; // ✅ tilt strength (deg)

            const tiltOffset = (pos, total) => {
              const t = total <= 1 ? 0 : (pos / (total - 1)) * 2 - 1; // -1..1
              return t * maxTilt; // ✅ center 0deg, left +deg, right -deg
            };

            return [...cards].reverse().map((c, index) => {
              const row = Math.floor(index / perRow);
              const pos = index % perRow;
              const total = Math.min(perRow, cards.length - row * perRow);

              const lastRow = Math.floor((cards.length - 1) / perRow);
              const lastRowCount = cards.length - lastRow * perRow;

              const baseOffset = Math.floor((perRow - lastRowCount) / 2) + 1;

              const needsHalf = (perRow - lastRowCount) % 2 !== 0;
              const shiftPx =
                row === lastRow && lastRowCount < perRow && needsHalf
                  ? -0.5 * (pitchRef.current || 0)
                  : 0;

              const y = arcOffset(pos, total);
              const tilt = tiltOffset(pos, total);

              // odd rows opposite animation (row 1,3,5...)
              const delay = row % 2 === 1 ? -(floatDuration / 2) : 0;
              return (
                <div
                  className="enter-wrap"
                  style={{
                    "--i": index,
                    ...(row === lastRow && lastRowCount < perRow && pos === 0
                      ? { gridColumnStart: baseOffset }
                      : {}),
                    ...(row === lastRow && lastRowCount < perRow
                      ? { transform: `translateX(${shiftPx}px)` }
                      : {}),
                  }}
                  key={index}
                >
                  <div
                    className={`flip ${flipped[index] ? "flipped" : ""}
                    
                      ${index === cards.length - 1 && rev < cards.length - 1 ? "last-locked" : ""}
                       ${index === cards.length - 1 && lastShake ? "last-shake" : ""}
                      `}
                    key={index}
                    onClick={() => {
                      toggle(index);
                    }}
                    onKeyDown={(e) => {
                      if (e.key === "Enter" || e.key === " ") {
                        e.preventDefault();
                        toggle(index);
                      }
                    }}
                  >
                    {/* NEW wrapper for curve + float (so it doesn't conflict with rotateY) */}
                    <div
                      className={`float-wrap !relative !z-[10000]`}
                      style={{
                        "--arcY": `${y}px`,
                        "--tilt": `${tilt}deg`, // ✅ NEW
                        "--delay": `${delay}s`,
                      }}
                    >
                      <div className="flip-inner">
                        <div
                          className={[
                            " flip-front bg-transparent",
                            index === cards.length - 1 ? "is-last" : "",
                          ].join(" ")}
                        >
                          <img
                            src={
                              pack.brand === "MTG"
                                ? "/images/inventory/magicBack.webp"
                                : pack.brand === "Pokemon"
                                  ? "/images/inventory/pokemonBack.png"
                                  : "/images/inventory/lorcanaBack.png"
                            }
                            alt={`back-${index}`}
                            draggable="false"
                            className={[
                              "object-contain transition duration-300",
                              !flipped[index]
                                ? "hover:drop-shadow-[0_0_18px_rgba(37,99,235,0.45)]"
                                : "drop-shadow-none",
                            ].join(" ")}
                          />
                        </div>

                        <div
                          className={
                            c.probability === "Reverse Holofoil"
                              ? "card-image-wrapper flip-back"
                              : "flip-back"
                          }
                        >
                          <img
                            src={`${IMAGE_BASE}/${c.cover_image.replace(/^\/+/, "")}`}
                            alt={`front-${index}`}
                            draggable="false"
                            className="object-contain"
                          />
                        </div>
                        {index === cards.length - 1 &&
                          rev < cards.length - 1 && (
                            <div className="absolute py-1 left-0 right-0 bottom-0 z-20 mb-0.5 mx-auto w-[95%] text-center yellow-bg text-xs rounded-md font-onest">
                              Last card
                            </div>
                          )}
                      </div>
                    </div>
                  </div>
                </div>
              );
            });
          })()}
        </div>
      </div>

      <div className="flex flex-col md:flex-row items-center gap-1 md:gap-3 mb-4 md:mb-10">
        {is_last && mode != "flip" ? (
          <>
            {next?.id &&
            next.image &&
            next.image !== "/undefined" &&
            next.image !== "undefined" &&
            next.image !== "" &&
            next.image !== "null" ? (
              // {pack ? (
              <div className="pack">
                <button
                  className="font-onest !hover:bg-transparent text-xs md:text-sm 2xl:text-base py-1.5 px-3 hover:border-white duration-300 border border-transparent bg-(--color-blue) text-white rounded-md"
                  // href={`/inventory/${next.brand}/${next.un_id}`}
                  onClick={(e) => {
                    e.stopPropagation();

                    // ✅ instantly set cover before navigation
                    dispatch(
                      setSelectedPackCover(
                        next.image || next.cover_image || null,
                      ),
                    );

                    window.location.href = `/inventory/${next.brand}/${next.un_id}`;
                  }}
                >
                  Simulate another pack
                </button>
              </div>
            ) : (
              <div />
            )}
          </>
        ) : null}

        <button
          onClick={() => {
            redirect("/inventory?packs=true");
          }}
          className="font-onest !hover:bg-transparent text-xs md:text-sm 2xl:text-base px-3 py-1 hover:border-white duration-300  border border-(--color-slate) text-white rounded-md"
        >
          Back
        </button>
        <div
          className={`font-onest !hover:bg-transparent text-xs md:text-sm 2xl:text-base px-3 py-1 hover:border-white duration-300 border border-transparent bg-(--color-blue) yellow-bg text-black rounded-md ${
            totalFx ? "total-shake total-glow" : ""
          }`}
        >
          Total: ${total.toFixed(2)}
        </div>
      </div>
    </>
  );
}
