"use client";
import { JoinGameModal } from "@/app/components/crashGame/JoinGameModal";
import PlayersList from "@/app/components/crashGame/PlayerList";
import SessionListing from "@/app/components/crashGame/SessionWinnings";
import { PackOpeningUI } from "@/app/components/crashGame/StartGame";
import ProgressGlowBar from "@/app/components/Header/ProgressGlowBar";
import AlertModal from "@/app/components/ui/AlertModal";
import { sendRequest } from "@/constants/index";
import {
  BorderButton,
  InternalButton,
  PrimaryButton,
} from "@/app/components/ui/Button";
import NotAvailable from "@/app/components/ui/NotAvailable";
import { getSocket } from "@/app/components/utils/socket";
import { fetchInventoryCards, InventoryCard } from "@/app/lib/api/inventory";
import { User } from "@/constants/types";
import { useState, useEffect, useRef } from "react";
import { useSelector } from "react-redux";

type GameState = {
  phase: "waiting" | "progress" | "multiplier" | "break";
  timeLeft: number;
  multiplier: number;
  players: any[];
  progressDuration: number;
};

type SelectedInvCard = {
  inv_id: number;
  image: string;
  price: number;
  name: string;
  rarity?: string;
};

export default function CrashGame() {
  // State Hooks
  const [progress, setProgress] = useState(0);
  const [isRunning, setIsRunning] = useState(false);
  const [isJoinModalOpen, setJoinModalOpen] = useState(false);
  const [playGame, setPlayGame] = useState(false);
  const [gameState, setGameState] = useState(""); // 'opening', 'cashedout', 'crashed'
  const [isLoadingCards, setIsLoadingCards] = useState(false);
  const [cardsError, setCardsError] = useState<string | null>(null);
  const [cards, setCards] = useState<InventoryCard[]>([]);
  const [hasLoadedCards, setHasLoadedCards] = useState(false);

  const [totalValue, setTotalValue] = useState(0);
  const [modalOpen, setModalOpen] = useState(false);
  const [modalType, setModalType] = useState<"success" | "error">("success");
  const [modalMsg, setModalMsg] = useState("");
  const [offset, setOffset] = useState<number | null>(null);
  const [hasMoreInv, setHasMoreInv] = useState(true);
  const [isLoadingMoreInv, setIsLoadingMoreInv] = useState(false);

  const [game, setGame] = useState<GameState | null>(null);
  const [playersList, setPlayersList] = useState<any[]>([]);
  const [gameId, setGameId] = useState<string>("");
  const [didCashout, setDidCashout] = useState(false);
  const [myWinCards, setMyWinCards] = useState([]);
  const [show_cards, set_show_cards] = useState([]);
  const [def_cards, set_def_cards] = useState([]);
  const [selectedInvCards, setSelectedInvCards] = useState<SelectedInvCard[]>(
    [],
  );
  const [progressDuration, setProgressDuration] = useState(10);
  const rafId = useRef<number | null>(null);
  const progressStartMs = useRef<number>(0);

  const [players, setPlayers] = useState(0);
  const [phase, setPHase] = useState("");
  const [timeLeft, setTimeLeft] = useState(0);
  const [multiplier, setmMltiplier] = useState(1.0);
  const isRun = useRef(false);

  //  Hooks (state / redux / context)
  const user = useSelector((state: any) => state.auth.user) as any | null;

  // Inventory Cards Laoded
  const loadCards = async (userId: any, token: any) => {
    if (!user?.userId || !user?.token) return; // ✅ guard
    try {
      setIsLoadingCards(true);
      setCardsError(null);

      const data = await fetchInventoryCards(userId, "yes", token);

      setCards(data.cards);
      setOffset(data.offset);
      setHasMoreInv(data.cards.length > 0);
      setHasLoadedCards(true);
    } catch (err: any) {
      console.error(err);
      const msg =
        err?.response?.data?.error ||
        err?.response?.data?.message ||
        err?.message;
      setCardsError(msg || "Failed to load cards");
    } finally {
      setIsLoadingCards(false);
    }
  };

  useEffect(() => {
    const opt = {
      action: "crash-cards",
    };
    sendRequest(opt, function (g: any) {
      if (g.resp == "success") {
        console.log(g.cards);
        set_def_cards(g.cards);
      }
    });
  }, []);

  const loadMoreInventory = async () => {
    if (!user?.userId || !user?.token) return;
    if (!hasMoreInv) return;
    if (isLoadingMoreInv) return;
    if (offset == null) return;

    try {
      setIsLoadingMoreInv(true);

      const data = await fetchInventoryCards(
        user.userId,
        "yes",
        user.token,
        offset,
      );

      // 🔴 STOP CONDITION
      if (data.cards.length === 0) {
        setHasMoreInv(false); // ❌ no more requests
        setIsLoadingMoreInv(false);
        return;
      }

      setCards((prev) => [...prev, ...data.cards]); // ✅ append
      setOffset(data.offset ?? null); // ✅ next offset
    } catch (err) {
      console.error(err);
    } finally {
      setIsLoadingMoreInv(false);
    }
  };

  useEffect(() => {
    const socket = getSocket();
    socket.on("connect", () => {
      console.log("Connected:", socket.id);
    });

    socket.on(
      "gameUpdate",
      (state: GameState & { game_id?: string; players?: any[] }) => {
        const myPlayer = Array.isArray(state.players)
          ? state.players.find((p) => p?.user_id === user.userId)
          : null;
        if (myPlayer) {
          set_show_cards(myPlayer.show_cards);
          setMyWinCards(myPlayer.win_cards);
        } else {
          set_show_cards([]);
        }
        setPHase(state.phase);
        setTimeLeft(state.timeLeft);

        setProgressDuration(state.progressDuration ?? 10);

        if (state.phase == "multiplier") {
          setmMltiplier(state.multiplier);
        }

        setGameId(state.game_id || "");

        setPlayersList(
          Array.isArray(state.players) ? state.players.filter(Boolean) : [],
        );

        setGame({ ...state });
      },
    );

    socket.on("playerCount", (count: number) => {
      setPlayers(count);
    });
    return () => {
      socket.off("gameUpdate");
      socket.off("playerCount");
    };
  }, []);

  useEffect(() => {
    if (phase == "progress") {
      setDidCashout(false);

      // const pct = ((progressDuration - timeLeft) / progressDuration) * 100;
      // setProgress(Math.max(0, Math.min(100, pct)));
      setPlayGame(false);
      setmMltiplier(1.0);
    } else if (phase == "multiplier") {
      setProgress(0);
      setPlayGame(true);
      setmMltiplier(multiplier);
      setGameState("opening");
    } else if (phase == "break") {
      setProgress(0);
      if (!didCashout) {
        setGameState("crashed");
      }
      setSelectedInvCards([]);
      setTotalValue(0);
    }
  }, [phase, timeLeft, multiplier, didCashout]);

  useEffect(() => {
    if (phase !== "progress") {
      if (rafId.current) cancelAnimationFrame(rafId.current);
      rafId.current = null;
      return;
    }

    const now = Date.now();
    progressStartMs.current = now - (progressDuration - timeLeft) * 1000;

    const tick = () => {
      const elapsed = Date.now() - progressStartMs.current;
      const pct = (elapsed / (progressDuration * 1000)) * 100;

      setProgress(Math.max(0, Math.min(100, pct)));

      if (pct < 100 && phase === "progress") {
        rafId.current = requestAnimationFrame(tick);
      }
    };

    if (rafId.current) cancelAnimationFrame(rafId.current);
    rafId.current = requestAnimationFrame(tick);

    return () => {
      if (rafId.current) cancelAnimationFrame(rafId.current);
      rafId.current = null;
    };
  }, [phase, timeLeft, progressDuration]);

  // useEffect(() => {
  //   if (isRun.current) return;
  //   isRun.current = true;
  //   if (!hasLoadedCards) {
  //     (async () => {
  //       await loadCards(user?.userId, user?.token);
  //     })();
  //   }
  // }, [hasLoadedCards]);

  useEffect(() => {
    if (gameState === "crashed") {
      setSelectedInvCards([]);
      setTotalValue(0);
    }
  }, [gameState]);

  useEffect(() => {
    if (phase !== "progress") {
      setJoinModalOpen(false);
    }
  }, [phase]);

  useEffect(() => {
    if (!playGame) {
      setMyWinCards([]);
    }
  }, [playGame]);

  return (
    <div className="text-white">
      {user?.activeMode === "gems" ? (
        <NotAvailable />
      ) : (
        <>
          <div
            className={`px-2 min-h-125 md:min-h-screen md:flex flex-col items-center justify-center transition-all duration-300 relative overflow-hidden `}
          >
            {/* ${
          gameState === "crashed" ? "CrashGame-bottom-effect" : ""
        } */}

            {!playGame ? (
              <div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-full h-50 md:h-80 bg-[#4D4CFE] blur-3xl rounded-full opacity-40"></div>
            ) : (
              <>
                {gameState === "crashed" && (
                  <div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-full h-50 md:h-80 bg-[#F14B3F] blur-3xl rounded-full opacity-40"></div>
                )}
                {(gameState === "opening" ||
                  gameState === "cashedout" ||
                  gameState === "running") && (
                  <div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-full h-[200px] md:h-[320px] bg-[#24C18D] blur-3xl rounded-full opacity-40"></div>
                )}
              </>
            )}

            <div
              className={`${
                playGame ? "-translate-y-200" : "transition-y-0"
              } transition-all duration-300 absolute -top-36 transform md:text-[370px] 2xl:text-[600px] !my-p !py-0 font-black text-transparent opacity-20 !font-onest select-none pointer-events-none heading font-onest `}
            >
              CRASH
            </div>

            <div
              className={`${
                gameState === "crashed" ? " transition-y-0" : "-translate-y-200"
              } transition-all duration-300 absolute -top-36 transform md:text-[370px] 2xl:text-[600px] !my-p !py-0 font-black text-transparent opacity-20 !font-onest select-none pointer-events-none heading font-onest `}
            >
              CRASH
            </div>
            {/* main ui of game */}
            {playGame ? (
              <>
                <PlayersList players={playersList} />
                <PackOpeningUI
                  def_cards={def_cards}
                  show_cards={show_cards}
                  gameState={gameState}
                  setGameState={setGameState}
                  multiplier={multiplier}
                  phase={phase}
                  userId={user?.userId}
                  onCashout={() => setDidCashout(true)}
                />
              </>
            ) : (
              <div className="z-10 mt-20 md:mt-0 flex flex-col items-center gap-8 w-full max-w-md">
                <div className="text-center ">
                  <h2 className="text-(--color-pink) font-extrabold text-xl md:text-4xl  mb-4 uppercase italic font-sofia tracking-wide">
                    Next Round Starts In
                  </h2>

                  {/* Progress Bar */}

                  <ProgressGlowBar
                    value={progress}
                    // timeLeft
                    max={100}
                    showLabel
                    label={`${Math.round(progress)}%`}
                  />
                </div>

                {/* Multiplier Display */}
                <div className="text-center md:mt-10 2xl:absolute bottom-60">
                  <div className="text-7xl font-sofia font-extrabold text-white  italic tracking-wider">
                    {multiplier.toFixed(2)}x
                  </div>
                  {/* onClick={handleJoinGame} */}
                  {user ? (
                    <BorderButton
                      onClick={async () => {
                        if (totalValue > 0) return;
                        if (!user) {
                          setModalType("error");
                          setModalMsg("Please log in to play game.");
                          setModalOpen(true);
                          return;
                        }
                        // setMyWinCards([]);
                        setJoinModalOpen(true);
                        await loadCards(user.userId, user.token);
                      }}
                    >
                       {totalValue ? `Joined $${totalValue.toFixed(2)}` : "Join Game"}
                    </BorderButton>
                  ) : null}
                </div>

                {/* Card Control Section */}
              </div>
            )}

            <div className="xl:min-w-139 min-w-[320px] z-10 absolute left-1/2 -translate-x-1/2 bottom-8 md:bottom-0 2xl:bottom-16 bg-(--color-naviBlue) p-3">
              <div className="flex items-center py-3 md:py-4 2xl:py-6 px-4 gap-4 bg-(--color-gray) justify-between">
                {/* game positions like cards are selected or not */}
                {playGame ? (
                  <div className="flex w-full  cursor-pointer items-center justify-between gap-3">
                    <div className="flex items-center gap-3">
                      <>
                        {selectedInvCards.slice(0, 3).map((c) => (
                          <img
                            key={c.inv_id}
                            src={c.image.replace("cardsimages", "cards/images")}
                            alt={c.name}
                            className=" w-14 rounded-md border border-white/20 object-cover"
                          />
                        ))}

                        {selectedInvCards.length > 3 && (
                          <div className="h-8 w-8 rounded-full border border-white/20 bg-[var(--color-gray)] flex items-center justify-center text-xs text-white">
                            +{selectedInvCards.length - 3}
                          </div>
                        )}
                      </>
                      <p className="font-bold font-sofia flex items-center gap-1 text-text-base md:text-2xl text-[#FF348D]">
                        {totalValue ? (
                          <>
                            {user?.activeMode === "coins" ? (
                              <img
                                src="/images/header/win.svg"
                                alt=""
                                className="h-4 w-4"
                              />
                            ) : (
                              <img
                                src="/images/header/star.svg"
                                alt=""
                                className="h-4 w-4"
                              />
                            )}
                            {totalValue.toFixed(2)}
                          </>
                        ) : (
                          ""
                        )}
                      </p>
                    </div>

                    <p className="text-bold uppercase font-sofia text-(--color-slate) text-sm md:text-2xl font-medium">
                      {didCashout
                        ? "ADDED TO INVENTORY"
                        : gameState === "crashed"
                          ? "CARD LOST"
                          : "Game in progress ..."}
                    </p>
                  </div>
                ) : (
                  <>
                    <div className="flex items-center gap-3">
                      <>
                        {selectedInvCards.slice(0, 3).map((c) => (
                          <img
                            key={c.inv_id}
                            src={c.image.replace("cardsimages", "cards/images")}
                            alt={c.name}
                            className=" w-14 rounded-md border border-white/20 object-cover"
                          />
                        ))}

                        {selectedInvCards.length > 3 && (
                          <div className="h-8 w-8 rounded-full border border-white/20 bg-[var(--color-gray)] flex items-center justify-center text-xs text-white">
                            +{selectedInvCards.length - 3}
                          </div>
                        )}
                      </>
                      <p className="font-bold font-sofia flex items-center gap-1 text-text-base md:text-2xl text-[#FF348D]">
                        {!user ? (
                          <img
                            src="/images/header/win.svg"
                            alt=""
                            className="h-4 w-4"
                          />
                        ) : (
                          <>
                            {user?.activeMode === "coins" ? (
                              <img
                                src="/images/header/win.svg"
                                alt=""
                                className="h-4 w-4"
                              />
                            ) : (
                              <img
                                src="/images/header/star.svg"
                                alt=""
                                className="h-4 w-4"
                              />
                            )}
                          </>
                        )}
                        {totalValue ? <>{totalValue.toFixed(2)}</> : ""}
                      </p>
                    </div>

                    <div className="flex font-onest  font-medium gap-3">
                      {totalValue > 0 ? (
                        <InternalButton
                          onClick={() => {
                            setSelectedInvCards([]);
                            setTotalValue(0);
                            setJoinModalOpen(true);
                          }}
                          className=" *:**: border hover:border-white !py-2 !px-10 border-white hover:!bg-transparent !bg-[var(--color-naviBlue)]"
                        >
                          Change
                        </InternalButton>
                      ) : (
                        <span className="text-bold uppercase font-sofia text-(--color-slate) text-sm md:text-2xl font-medium">
                          Add Card to Play With
                        </span>
                      )}
                    </div>
                  </>
                )}
              </div>
            </div>
            {/* )} */}
            <div className="absolute left-0 right-0 bottom-0 bg-black min-h-20 2xl:min-h-37.5 w-full"></div>
            <JoinGameModal
              user={user}
              cards={cards}
              isOpen={isJoinModalOpen}
              onClose={() => setJoinModalOpen(false)}
              cardLoading={isLoadingCards}
              cardsError={cardsError}
              onTotalValueChange={setTotalValue}
              gameState={gameState}
              onLoadMore={loadMoreInventory}
              hasMore={hasMoreInv}
              isLoadingMore={isLoadingMoreInv}
              onSelectedCardsChange={(cards) => setSelectedInvCards(cards)}
            />
          </div>
          {playGame && <SessionListing myWinCards={myWinCards} />}
          <AlertModal
            open={modalOpen}
            type={modalType}
            message={modalMsg}
            onClose={() => setModalOpen(false)}
          />
        </>
      )}
    </div>
  );
}
