import { useEffect, useState } from "react";
import Image from "next/image";
import { games } from "../data/games";
import { usePrivy, useSolanaWallets } from "@privy-io/react-auth";
import { joinBet } from "@/shared/solana_helpers";
import { Bet } from "../types/Bet";
import { fetchUserById } from "@/shared/data_fetcher";
import { toast } from "sonner";
import { connection, EXPLORER_TX_TEMPLATE, API_BASE_URL } from "@/data/shared";
import { CONFIRMATION_THRESHOLD, WAGER_PRIZE_MULT } from "@/shared/constants";

interface GameModalProps {
  bets: Bet[];
}

export default function YourGames({ bets }: GameModalProps) {
  const { wallets } = useSolanaWallets();
  const [myBets, setMyBets] = useState<Bet[]>([]);
  const [loading, setLoading] = useState(true);
  const { user } = usePrivy();
  const [selectedBet, setSelectedBet] = useState<Bet | null>(null); // Track selected bet
  const [isProcessing, setIsProcessing] = useState(false); // Track processing state
  const [failedImages, setFailedImages] = useState<Set<string>>(new Set());
  const defaultPFP = '/duelfiassets/PFP (1).png';

  const handleJoinGame = async () => {
    if (!selectedBet) return;

    let wallet = wallets[0];
    wallets.forEach((_wallet) => {
      if (wallet.type === "solana") {
        wallet = _wallet;
      }
    });
    
    setIsProcessing(true);
    toast.loading("Joining Bet");
    try {
      const tx = await joinBet(wallet, user?.id ?? "", selectedBet.id, selectedBet.address);
      const url = EXPLORER_TX_TEMPLATE.replace("{address}", tx);
      
      if (tx.length > 5) {
        connection.confirmTransaction(tx, CONFIRMATION_THRESHOLD).finally(()=>{
          toast.dismiss();
          toast.success("Joined game successfully!", {
            action: {
              label: "View TX",
              onClick: () => window.open(url, "_blank"),
            },
          });
        })
      } else {
        toast.dismiss();

        toast.error("Failed to join this game");
      }
    } catch (error) {
      console.error("Error joining bet:", error);
      toast.error("Failed to join this game");
    } finally {
      setIsProcessing(false);
      setSelectedBet(null);
    }
  };

  const updateBets = async () => {
    let filteredBets = bets;
    if(user){
      let wallet = wallets[0];
      wallets.forEach((_wallet) => {
      if (wallet.type === "solana") {
        wallet = _wallet;
      }
      });
      filteredBets = bets.filter((bet) => bet.owner !== wallet.address);
    }else{
      console.log("No user found, showing all bets");
    }

    const enrichedBets = await Promise.all(
      filteredBets.map(async (bet) => {
        const ownerProfile = await fetchUserById(bet.owner_id);
     
        return {
          ...bet,
          ownerProfile,
        };
      })
    );

    setMyBets(enrichedBets);
    setLoading(false);
    console.log(`Got ${bets.length} bets, enriched to ${enrichedBets.length}`);
  };

  useEffect(() => {
    updateBets();
    const interval = setInterval(updateBets, 10000);
    return () => clearInterval(interval);
  }, [bets]);

  return (
    <section className="py-16 px-6">
      <h2 className="text-3xl font-bold text-white mb-6">Open Games</h2>

      {loading ? (
        <p className="text-gray-400">Loading Open games...</p>
      ) : myBets.length === 0 ? (
        <p className="text-gray-400">No open games available</p>
      ) : (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
            {myBets.map((bet) => {
            console.log(`Bet ${bet}`);

            const game = games.find((g) => g.id === bet.id);
            let ownerPFP = bet.ownerProfile?.x_profile_url || `${API_BASE_URL}profile_pics/${bet.ownerProfile?.id}.jpg`;
            if (!game) return null;

            // Check if this image has already failed to load
            if (failedImages.has(ownerPFP)) {
              ownerPFP = defaultPFP;
            }

            return (
              <div
                key={bet.address}
                className="relative group bg-[rgb(30,30,30)] rounded-2xl p-2 w-50 overflow-hidden cursor-pointer transition-all duration-300"
                onClick={() => setSelectedBet(bet)} // Open modal
              >
                <div className="relative w-full h-60 overflow-hidden rounded-xl">
                  <Image
                    src={game.thumbnail}
                    alt={game.name}
                    layout="fill"
                    objectFit="cover"
                    className="transition-all duration-300 group-hover:brightness-50"
                  />
                  <div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
                    <span className="text-white text-xl font-bold">Join</span>
                  </div>
                </div>

                <div className="mt-4 px-3 text-left">
                  <h3 className="text-lg font-semibold text-white py-2">{game.name}</h3>

                  <div className="flex justify-between text-xs font-mono py-1">
                    <p className="text-gray-400">Wager</p>
                    <p className="text-gray-400">Prize</p>
                  </div>

                  <div className="flex justify-between text-xs font-mono py-1">
                    <p className="text-white">{bet.wager} SOL</p>
                    <p className="text-white">{(bet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL</p>
                  </div>

                  {bet.ownerProfile && (
                    <div className="flex items-center gap-2 mt-4">
                      <Image
                        src={ownerPFP}
                        alt={bet.ownerProfile.username}
                        width={24}
                        height={24}
                        className="rounded-full"
                        onError={(e) => {
                          //@ts-expect-error e.target has no src, but it needs to be changed
                          e.target.src = defaultPFP;
                          setFailedImages(prev => new Set(prev).add(ownerPFP));
                        }}
                      />
                      <p className="text-white text-sm font-mono">{bet.ownerProfile.username}</p>
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}

      {/* Modal */}
      {selectedBet && (
        <div className="fixed inset-0 flex items-center justify-center z-50 backdrop-blur-sm bg-black/50">
          <div className="bg-[rgb(30,30,30)] text-white p-6 rounded-lg shadow-lg max-w-sm w-full">
            {isProcessing ? (
              <div className="flex flex-col items-center">
                <svg
                  className="animate-spin h-8 w-8 text-blue-400 mb-4"
                  viewBox="0 0 24 24"
                  fill="none"
                >
                  <circle
                    className="opacity-25"
                    cx="12"
                    cy="12"
                    r="10"
                    stroke="currentColor"
                    strokeWidth="4"
                  ></circle>
                  <path
                    className="opacity-75"
                    fill="currentColor"
                    d="M4 12a8 8 0 018-8v8H4z"
                  ></path>
                </svg>
                <h3 className="text-lg font-semibold">Processing...</h3>
                <p className="text-gray-400 text-sm mt-2">Joining the Game, please wait...</p>
              </div>
            ) : (
              <>
                <h2 className="text-xl font-bold mb-4">Are you sure to join this Game?</h2>
                <div className="flex gap-4 mb-4">
                  <div className="w-1/2 relative h-48 overflow-hidden rounded-xl">
                    <Image
                      src={games.find(g => g.id === selectedBet.id)?.thumbnail || ''}
                      alt={games.find(g => g.id === selectedBet.id)?.name || ''}
                      layout="fill"
                      objectFit="cover"
                    />
                  </div>
                  <div className="w-1/2 flex flex-col justify-center space-y-4">
                    {selectedBet.ownerProfile && (
                      <>
                        <p className="text-gray-400 mb-2">Offered by:</p>
                        <div className="flex items-center">
                          {(() => {
                            let modalOwnerPFP = selectedBet.ownerProfile.x_profile_url || `${API_BASE_URL}profile_pics/${selectedBet.ownerProfile.id}.jpg`;
                            if (failedImages.has(modalOwnerPFP)) {
                              modalOwnerPFP = defaultPFP;
                            }
                            return (
                              <Image
                                src={modalOwnerPFP}
                                alt={selectedBet.ownerProfile.username}
                                width={32}
                                height={32}
                                className="w-8 h-8 rounded-full mr-2"
                                onError={(e) => {
                                  //@ts-expect-error e.target has no src, but it needs to be changed
                                  e.target.src = defaultPFP;
                                  setFailedImages(prev => new Set(prev).add(modalOwnerPFP));
                                }}
                              />
                            );
                          })()}
                          <p className="font-bold">{selectedBet.ownerProfile.username}</p>
                        </div>
                      </>
                    )}
                    <div className="flex justify-between items-center">
                      <span className="text-gray-400">Entry:</span>
                      <span className="font-bold">{selectedBet.wager} SOL</span>
                    </div>
                    <div className="flex justify-between items-center">
                      <span className="text-gray-400">Prize:</span>
                      <span className="font-bold">{(selectedBet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL</span>
                    </div>
                  </div>
                </div>
                <div className="flex justify-end gap-3 mt-4">
                  <button 
                    onClick={() => setSelectedBet(null)} 
                    className="bg-gray-700 px-4 py-2 rounded hover:scale-105 transition-all duration-300"
                    disabled={isProcessing}
                  >
                    Cancel
                  </button>
                  <button 
                    onClick={handleJoinGame} 
                    className="bg-[rgb(248,144,22)] text-black font-bold px-4 py-2 rounded hover:scale-105 transition-all duration-300"
                    disabled={isProcessing}
                  >
                    Confirm
                  </button>
                </div>
              </>
            )}
          </div>
        </div>
      )}
    </section>
  );
}
