"use client";

import { useEffect, useState, useRef } from "react";
import Image from "next/image";
import OpenGames from "./OpenGames";
import GameModal from "./GameModal";
import { HowItWorksModal } from "./HowItWorksModal";
import YourGames from "./YourGames";
import { Bet } from "@/types/Bet";
import { fetchOpenBets, createBet, joinBet, getVaultByAddress } from "@/shared/solana_helpers";
import { ConnectedSolanaWallet, usePrivy, useSolanaWallets } from "@privy-io/react-auth";
import { RematchModal } from "./RematchModal";

export default function HeroSection() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isGameModalOpen, setIsGameModalOpen] = useState(false);
  const [bets, setBets] = useState<Bet[]>([]);
  const [solWallet, setSolWallet] = useState<ConnectedSolanaWallet>();
  const [myActiveBet, setMyActiveBet] = useState<Bet>();
  const [rematch, setRematch] = useState(false);
  const [lastActiveBet, setLastActiveBet] = useState<Bet>();
  const [rematchInProgress, setRematchInProgress] = useState(false);
  const [rematchTxError, setRematchTxError] = useState(false);
  const [rematchBetAddress, setRematchBetAddress] = useState<string | null>(null);

  const { wallets, ready } = useSolanaWallets();
  const { user } = usePrivy();
  const iframeRef = useRef<HTMLIFrameElement>(null);


  useEffect(()=>{
    if(rematch){
      if(!lastActiveBet){
        console.log(`last active bet was null, heres active bet ${myActiveBet}`);
      }
      const isOwner = lastActiveBet?.owner_id == user?.id;
      console.log(`rematch function ${isOwner ? "owner" : "joiner"} owner_id:${lastActiveBet?.owner_id}`);
  
      if(isOwner){
        handleCreateRematch();
      }else{
        handleJoinRematch();
      }
    }
    
  },[rematch])

  const game_close_signal = (status: number) => {
    setRematch(status == 1);
    setMyActiveBet(undefined);
  };



  const updateBets = async () => {
    if (!ready || wallets.length === 0) return;

    const wallet = wallets.find((_wallet) => _wallet.type === "solana") || wallets[0];
    setSolWallet(wallet);

    const fetchedBets = await fetchOpenBets(wallet);
    const filteredBets = fetchedBets.filter((bet) => !(bet.owner_id && bet.joiner_id));
    const filledBets = fetchedBets.filter((bet) => bet.owner_id && bet.joiner_id);
    const activeBet = filledBets.find((bet) => bet.owner_id === user?.id || bet.joiner_id === user?.id);

    if(rematch){
      setMyActiveBet(undefined);
      return;
    }
    setBets(filteredBets);
    if (!myActiveBet && lastActiveBet?.address !== activeBet?.address) {
      setMyActiveBet(activeBet);
      setLastActiveBet(activeBet);
    }
  };

  const handleCreateRematch = async () => {
    console.log('Creating rematch...');
    if (!lastActiveBet || !solWallet) return;
  
    setRematchInProgress(true);
    setRematchTxError(false);
  
    try {
      // Step 1: Create new bet
      const tx = await createBet(
        solWallet,
        user?.id ?? "",
        lastActiveBet.wager,
        lastActiveBet.id,
        true
      );
      console.log("Rematch created. Transaction ID:", tx);
  
      // Step 2: Inform backend of rematch link
      const set_response = await fetch(
        `https://vps.playpoolstudios.com/duelfi/api/set_rematch_address.php?address=${lastActiveBet.address}&rematch_address=${tx}`
      );
      console.log(await set_response.text());
  
      // Step 3: Poll until vault account is found
      const pollUntilFound = async (
        maxRetries = 10,
        delayMs = 3000
      ): Promise<any> => {
        for (let i = 0; i < maxRetries; i++) {
          const vault = await getVaultByAddress(solWallet, tx);
          if (vault) return vault;
          console.log(`Waiting for vault account... (${i + 1}/${maxRetries})`);
          await new Promise(res => setTimeout(res, delayMs));
        }
        return undefined;
      };
  
      const newBetAcc = await pollUntilFound();
  
      if (!newBetAcc) {
        console.error("Failed to retrieve new bet vault after retries.");
        setRematchTxError(true);
      } else {
        // Step 4: Set new active bet
        setMyActiveBet(newBetAcc);
        setLastActiveBet(newBetAcc);
        setRematch(false);
      }
    } catch (err) {
      console.error("Create rematch failed:", err);
      setRematchTxError(true);
    } finally {
      setRematchInProgress(false);
    }
  };
  
  const handleJoinRematch = async () => {
    if (!lastActiveBet || !solWallet) return;
  
    try {
      const pollForRematchAddress = async (
        maxRetries = 10,
        delayMs = 3000
      ): Promise<string | null> => {
        for (let i = 0; i < maxRetries; i++) {
          console.log(`Polling rematch address... (${i + 1}/${maxRetries})`);
          const response = await fetch(
            `https://vps.playpoolstudios.com/duelfi/api/get_rematch_address.php?address=${lastActiveBet.address}`
          );
          const rematchAddress = (await response.text()).trim();
  
          if (rematchAddress.length > 5) {
            console.log("Found rematch address:", rematchAddress);
            return rematchAddress;
          }
  
          await new Promise(res => setTimeout(res, delayMs));
        }
  
        console.warn("Rematch address not found after max retries.");
        return null;
      };
  
      const rematchAddress = await pollForRematchAddress();
  
      if (!rematchAddress) return;
  
      const pollForVault = async (
        address: string,
        maxRetries = 10,
        delayMs = 3000
      ): Promise<any> => {
        for (let i = 0; i < maxRetries; i++) {
          console.log(`Polling vault for address ${address}... (${i + 1}/${maxRetries})`);
          const vault = await getVaultByAddress(solWallet, address);
          if (vault) return vault;
          await new Promise(res => setTimeout(res, delayMs));
        }
  
        console.warn("Vault not found after max retries.");
        return null;
      };
  
      const rematchVault:Bet = await pollForVault(rematchAddress);
  
      if (rematchVault) {
        const tx = await joinBet(solWallet, user?.id!, rematchVault.id, rematchVault.address);
        setMyActiveBet(rematchVault);
        setLastActiveBet(rematchVault);
        setRematch(false);
        console.log("Rematch vault set as active.");
      }
    } catch (err) {
      console.error("Error during handleJoinRematch:", err);
    }
  };
  
  // const handleJoinRematch = async () => {
  //   console.log('rejoining rematch');

  //   if (!solWallet || !lastActiveBet?.owner_id || !lastActiveBet?.wager) return;
  
  //   setRematchInProgress(true);
  //   setRematchTxError(false);
  
  //   const maxAttempts = 50;
  //   let attempts = 0;
  
  //   const pollForMatchingBet = async (): Promise<Bet | null> => {
  //     try {
  //       const openBets = await fetchOpenBets(solWallet);
  //       const match = openBets.find(
  //         (bet) =>
  //           bet.owner_id === lastActiveBet.owner_id &&
  //           bet.wager === lastActiveBet.wager &&
  //           bet.address !== lastActiveBet.address // to ensure it's a new one
  //       );
  //       return match ?? null;
  //     } catch (err) {
  //       console.error("Error fetching bets:", err);
  //       return null;
  //     }
  //   };
  
  //   const tryJoin = async () => {
  //     while (attempts < maxAttempts) {
  //       const matchingBet = await pollForMatchingBet();
  //       if (matchingBet) {
  //         try {
  //           setRematchBetAddress(matchingBet.address);
  //           const tx = await joinBet(
  //             solWallet,
  //             user?.id ?? "",
  //             lastActiveBet.id ?? "tetris",
  //             matchingBet.address
  //           );
  //           console.log("Joined rematch:", tx);
  //           setRematch(false);
  //           return;
  //         } catch (err) {
  //           console.error("Join rematch failed:", err);
  //           setRematchTxError(true);
  //           return;
  //         } finally {
  //           setRematchInProgress(false);
  //         }
  //       }
  
  //       attempts++;
  //       await new Promise((res) => setTimeout(res, 5000));
  //     }
  
  //     // Max attempts reached
  //     setRematchTxError(true);
  //     setRematchInProgress(false);
  //   };
  
  //   tryJoin();
  // };
  

  useEffect(() => {
    if (!ready) return;

    updateBets();
    const interval = setInterval(updateBets, 3500);

    return () => clearInterval(interval);
  }, [ready]);

  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      if (event.origin === window.location.origin && typeof event.data === "string") {
        try {
          const message = JSON.parse(event.data);
          if (message?.type === "gameClose" && typeof message.status === "number") {
            game_close_signal(message.status);
          }
        } catch (error) {
          console.error("JSON parse error from Unity message:", error);
        }
      }
    };

    window.addEventListener("message", handleMessage);
    return () => window.removeEventListener("message", handleMessage);
  }, []);

  return (
    <>
      {myActiveBet && !rematch ? (
        <div className="w-full h-screen flex justify-center items-center bg-black">
          <iframe
            ref={iframeRef}
            src={`/UnityBuild/${myActiveBet.id}/index.html?betId=${myActiveBet.id}&owner=${myActiveBet.owner_id}&joiner=${myActiveBet.joiner_id}&address=${myActiveBet.address}&uid=${user?.id}&pubkey=${solWallet?.address}&wager=${myActiveBet.wager * 1e8}`}
            className="w-full h-full"
            allowFullScreen
          />
        </div>
      ) : (
        <section className="flex flex-col items-center text-center py-16">
          <Image
            src="/duelfiassets/Playing on Arcade Machine no BG.png"
            alt="DuelFi Hero"
            width={150}
            height={50}
            className="mb-6"
          />

          <h1 className="text-4xl font-bold text-white">
            Instant <span className="text-[rgb(248,144,22)]">Duels</span>, Instant{" "}
            <span className="text-[rgb(248,144,22)]">Wins</span>
          </h1>

          <button
            className="mt-12 px-12 py-4 bg-[rgb(248,144,22)] hover:bg-white text-black text-sm font-semibold rounded-xl flex items-center gap-2 transition duration-300 hover:scale-110"
            onClick={() => setIsGameModalOpen(true)}
          >
            Create a Game
            <svg
              xmlns="http://www.w3.org/2000/svg"
              className="w-5 h-5"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="M7 7h10v10" />
              <path d="M7 17 17 7" />
            </svg>
          </button>

          <p
            className="mt-4 text-gray-400 cursor-pointer hover:underline font-mono"
            onClick={() => setIsModalOpen(true)}
          >
            How it works?..
          </p>

          <YourGames bets={bets} />
          <OpenGames bets={bets} />
        </section>
      )}

      {rematch && (
        <RematchModal
          isOwner= {lastActiveBet?.owner_id === user?.id}
          inProgress={rematchInProgress}
          hasError={rematchTxError}
          wallets={solWallet!}
        />
      )}

      <GameModal isOpen={isGameModalOpen} onClose={() => setIsGameModalOpen(false)} />
      <HowItWorksModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
    </>
  );
}
