import "./styles.sass";
import {SocketContext} from "@/common/contexts/SocketContext";
import {useContext, useState, useEffect, useRef, useCallback} from "react";
import MusicSlider from "@/pages/Game/components/MusicSlider";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {
    faMessage,
    faMusic,
    faHeadphones,
    faClock,
    faCrown,
    faPaperPlane,
    faCheckCircle,
    faVolumeUp,
    faStepForward
} from "@fortawesome/free-solid-svg-icons";
import { fetchPlaylistSongs } from "@/services/youtubeService.js";
import YouTubePlayer from "../../components/YouTubePlayer/YouTubePlayer";

export const Game = () => {
    const {send, on, socket, connected, connect} = useContext(SocketContext);

    useEffect(() => {
        if (!connected) {
            connect();
        }
    }, [connected, connect]);

    const [role, setRole] = useState(null);
    const [round, setRound] = useState(1);
    const [phase, setPhase] = useState("waiting");
    const [timeLeft, setTimeLeft] = useState(30);
    const [frequency, setFrequency] = useState(440);
    const [currentSong, setCurrentSong] = useState(null);
    const [songOptions, setSongOptions] = useState([]);
    const [scores, setScores] = useState({});
    const [selectedSong, setSelectedSong] = useState(null);
    const [guessResult, setGuessResult] = useState(null);
    const [isHost, setIsHost] = useState(false);
    const [hasGuessed, setHasGuessed] = useState(false);

    const [messages, setMessages] = useState([]);
    const [inputValue, setInputValue] = useState("");
    const [connectedUsers, setConnectedUsers] = useState([]);
    const [username, setUsername] = useState("");
    const messageEndRef = useRef(null);
    const timerIntervalRef = useRef(null);

    const [allSongs, setAllSongs] = useState([]);
    const [songsLoading, setSongsLoading] = useState(false);
    const [composerIsPlaying, setComposerIsPlaying] = useState(false);

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


        const eventHandlers = {
            "roles-assigned": (roles) => {
                const myRole = roles[socket?.id];
                if (myRole) {
                    setRole(myRole);
                    setMessages(prev => [...prev, {
                        system: true,
                        text: myRole === "composer" 
                            ? "Du bist der Komponist! Spiele den Song mit dem Tonregler." 
                            : "Du bist ein Rater! Höre die Frequenzen und versuche, den Song zu erkennen."
                    }]);
                }
            },
            "song-selected": setCurrentSong,
            "round-started": (data) => {
                setRound(data.round);
                setPhase("composing");
                setTimeLeft(data.timeRemaining);
            },
            "guessing-phase-started": (data) => {
                console.log("Guessing phase started:", data);
                setPhase("guessing");
                setTimeLeft(data.timeRemaining);
                setSongOptions(data.songOptions || []);
            },
            "guess-result": (result) => {
                setGuessResult(result.isCorrect);
                setCurrentSong(result.correctSong);
            },
            "round-results": (results) => {
                setPhase("results");
                const scoresWithNames = {};
                Object.entries(results.scores).forEach(([userId, score]) => {
                    const user = connectedUsers.find(u => u.id === userId);
                    scoresWithNames[userId] = {
                        score: score,
                        name: user?.name || results.playerNames?.[userId] || "Player"
                    };
                });
                
                setScores(scoresWithNames);
                
                if (!currentSong) {
                    setCurrentSong(results.selectedSong);
                }
            },
            "room-users-update": (users) => {
                setConnectedUsers(users);
                const currentUser = users.find(u => u.id === socket?.id);
                if (currentUser) setUsername(currentUser.name);
            },
            "host-status": (status) => setIsHost(status.isHost),
            "chat-message": (msg) => setMessages(prev => [...prev, msg]),
            "user-connected": (userData) => {
                setMessages(prev => [...prev, {
                    system: true,
                    text: `${userData.name} ist beigetreten`
                }]);
                setConnectedUsers(prev => [...prev, userData]);
            },
            "user-disconnected": (userId) => {
                setConnectedUsers(prev => {
                    const user = prev.find(u => u.id === userId);
                    if (user) {
                        setMessages(prevMsgs => [...prevMsgs, {
                            system: true,
                            text: `${user.name} hat den Raum verlassen`
                        }]);
                    }
                    return prev.filter(u => u.id !== userId);
                });
            },
            "frequency-update": (data) => {
                if (phase === "composing") {
                    console.log("Received frequency update:", data.frequency);
                    setFrequency(data.frequency);
                    setComposerIsPlaying(data.isPlaying); // Make sure isPlaying is handled
                }
            },
            "phase-changed": (data) => {
                console.log("Phase changed:", data);
                setPhase(data.phase);
                if (data.timeRemaining) {
                    setTimeLeft(data.timeRemaining);
                }
            },
            "chat-message-confirmation": (msg) => {
                setMessages(prev => prev.map(prevMsg => {
                    if (!prevMsg.system && prevMsg.text === msg.text && prevMsg.sender !== msg.sender) {
                        console.log(`Updating message sender from "${prevMsg.sender}" to "${msg.sender}"`);
                        return { ...prevMsg, sender: msg.sender };
                    }
                    return prevMsg;
                }));
            },
        };

        const cleanupFunctions = Object.entries(eventHandlers).map(
            ([event, handler]) => on(event, handler)
        );

        if (connected) {
            send("get-room-users");
            send("check-host-status");
        }

        return () => cleanupFunctions.forEach(cleanup => cleanup());
    }, [socket, on, send, role, currentSong, phase, connected, connectedUsers]);

    useEffect(() => {
        if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
        
        if (phase !== "waiting" && phase !== "results") {
            timerIntervalRef.current = setInterval(() => {
                setTimeLeft(prev => Math.max(0, prev - 1));
            }, 1000);
        }
        
        return () => {
            if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
        };
    }, [phase]);

    useEffect(() => {
        messageEndRef.current?.scrollIntoView({behavior: "smooth"});
    }, [messages]);

    useEffect(() => {
        if (!connected || !socket) return;
        
        const loadSongs = async () => {
            try {
                setSongsLoading(true);
                console.log("Fetching songs with active socket:", socket?.id);
                const songs = await fetchPlaylistSongs(socket);
                console.log(`Successfully loaded ${songs.length} songs`);
                setAllSongs(songs);
            } catch (error) {
                console.error("Error loading songs:", error);
            } finally {
                setSongsLoading(false);
            }
        };
        
        loadSongs();
    }, [socket, connected]);

    useEffect(() => {
        if (!allSongs.length || !currentSong || !currentSong.id) return;
        
        const enhancedSong = allSongs.find(song => song.id === currentSong.id);
        if (enhancedSong && enhancedSong !== currentSong) {
            setCurrentSong(enhancedSong);
        }
    }, [allSongs, currentSong]);

    useEffect(() => {
        if (!allSongs.length || !songOptions.length) return;
        
        const enhancedOptions = songOptions.map(option => {
            if (option.id && !option.title) {
                return allSongs.find(song => song.id === option.id) || option;
            }
            return option;
        });
        
        if (JSON.stringify(enhancedOptions) !== JSON.stringify(songOptions)) {
            setSongOptions(enhancedOptions);
        }
    }, [allSongs, songOptions]);

    const handleFrequencyChange = useCallback((newFrequency, isPlaying) => {
        setFrequency(newFrequency);
        setComposerIsPlaying(isPlaying);
        if (role === "composer") {
            send("submit-frequency", { frequency: newFrequency, isPlaying });
        }
    }, [role, send]);
    
    const handleSendMessage = useCallback(() => {
        if (inputValue.trim()) {
            const currentUser = connectedUsers.find(u => u.id === socket?.id);
            const senderName = currentUser?.name || username || "Player";
            
            const messageData = { text: inputValue, sender: senderName };
            send("send-message", messageData);
            setMessages(prev => [...prev, messageData]);
            setInputValue("");
        }
    }, [inputValue, send, socket?.id, connectedUsers, username]);
    
    const handleSongSelect = useCallback((song) => {
        setSelectedSong(song);
    }, []);

    const handleSubmitGuess = useCallback(() => {
        if (!selectedSong || phase !== 'guessing') return;
        
        console.log("Submitting guess:", selectedSong.id);
        send("submit-guess", { songId: selectedSong.id });

        setMessages(prev => [...prev, {
            system: true,
            text: `Du hast "${selectedSong.title}" von ${selectedSong.artist} gewählt.`
        }]);

        setHasGuessed(true);
    }, [selectedSong, send, phase]);
    
    const handleNextRound = useCallback(() => {
        send("next-round");
        setSelectedSong(null);
        setGuessResult(null);
        setTimeLeft(0);
    }, [send]);

    const handlePlayerReady = useCallback(() => {
        console.log("Player ready");
    }, []);

    const renderPhaseContent = () => {
        switch (phase) {
            case "waiting":
                return (
                    <div className="waiting-phase">
                        <h3>Warten auf Spielstart...</h3>
                    </div>
                );
                
            case "composing":
                return (
                    <div className="composing-phase">
                        <div className="phase-header">
                            <h3>Runde {round}: {role === "composer" ? "Spielen" : "Zuhören"}</h3>
                            <div className="timer">
                                <FontAwesomeIcon icon={faClock} /> {timeLeft}s
                            </div>
                        </div>
                        
                        {role === "composer" && currentSong && (
                            <div className="song-display">
                                <div className="song-card">
                                    <img src={currentSong.coverUrl} alt={currentSong.title} />
                                    <div className="song-info">
                                        <div className="song-names">{currentSong.title}</div>
                                        <div className="song-description">von {currentSong.artist}</div>
                                    </div>
                                </div>
                                
                                <div className="song-player-container">
                                    <YouTubePlayer 
                                        videoId={currentSong.youtubeId}
                                        autoplay={true}
                                        startTime={currentSong.refrainTime || 45}
                                        onReady={handlePlayerReady}
                                        className="song-embedded-player"
                                    />
                                </div>
                                
                                <div className="music-controls">
                                    <p className="instruction">Use the player above to listen, and the tone slider to play!</p>
                                </div>
                            </div>
                        )}
                        
                        {role === "guesser" && (
                            <div className="listening-display">
                                <div className="listening-icon">
                                    <FontAwesomeIcon icon={faHeadphones} size="4x" />
                                </div>
                                <p className="instruction">Höre genau zu und versuche, den Song zu erkennen!</p>
                            </div>
                        )}
                    </div>
                );
                
            case "guessing":
                return (
                    <div className="guessing-phase">
                        <div className="phase-header">
                            <h3>Runde {round}: Song erraten</h3>
                            <div className="timer">
                                <FontAwesomeIcon icon={faClock} /> {timeLeft}s
                            </div>
                        </div>
                        
                        {role === "composer" ? (
                            <div className="waiting-for-guessers">
                                <p>Die Rater versuchen nun, deinen Song zu erraten...</p>
                            </div>
                        ) : (
                            <div className="song-selection">
                                <p className="instruction">Welchen Song hat der Komponist gespielt?</p>
                                
                                {songOptions.length === 0 ? (
                                    <div className="loading-songs">
                                        <p>Lade Songoptionen...</p>
                                    </div>
                                ) : (
                                    <>
                                        <div className="song-grid">
                                            {songOptions.map(song => (
                                                <div 
                                                    key={song.id}
                                                    className={`song-option ${selectedSong?.id === song.id ? 'selected' : ''} ${hasGuessed ? 'disabled' : ''}`}
                                                    onClick={() => !hasGuessed && handleSongSelect(song)}
                                                >
                                                    <div className="song-image">
                                                        <img src={song.coverUrl} alt={song.title} />
                                                        {selectedSong?.id === song.id && (
                                                            <div className="selection-indicator">
                                                                <FontAwesomeIcon icon={faCheckCircle} />
                                                            </div>
                                                        )}
                                                    </div>
                                                    <div className="song-details">
                                                        <div className="song-title">{song.title}</div>
                                                        <div className="song-artist">{song.artist}</div>
                                                    </div>
                                                </div>
                                            ))}
                                        </div>
                                        
                                        <div className="guess-actions">
                                            {hasGuessed ? (
                                                <p className="guess-submitted">Deine Antwort wurde eingereicht!</p>
                                            ) : (
                                                <button 
                                                    className={`submit-guess-button ${!selectedSong ? 'disabled' : ''}`} 
                                                    onClick={handleSubmitGuess}
                                                    disabled={!selectedSong}
                                                >
                                                    <FontAwesomeIcon icon={faPaperPlane} />
                                                    Antwort einreichen
                                                </button>
                                            )}
                                        </div>
                                    </>
                                )}
                            </div>
                        )}
                    </div>
                );
                
            case "results":
                return (
                    <div className="results-phase">
                        <h3>Runde {round}: Ergebnisse</h3>
                        
                        <div className="round-results">
                            {role === "composer" ? (
                                <div className="composer-results">
                                    <p>Die Rater haben versucht, deinen Song zu erraten.</p>
                                </div>
                            ) : (
                                <div className="guesser-results">
                                    {currentSong && (
                                        <div className="correct-song">
                                            <p>Der richtige Song war:</p>
                                            <div className="song-card highlight">
                                                <img src={currentSong.coverUrl} alt={currentSong.title} />
                                                <div className="song-info">
                                                    <div className="song-names">{currentSong.title}</div>
                                                    <div className="song-description">von {currentSong.artist}</div>
                                                </div>
                                            </div>
                                        </div>
                                    )}
                                    
                                    {guessResult !== null && (
                                        <div className={`guess-result ${guessResult ? 'correct' : 'incorrect'}`}>
                                            {guessResult 
                                                ? 'Richtig! Du erhälst 10 Punkte.' 
                                                : 'Leider falsch. Kein Punkt.'}
                                        </div>
                                    )}
                                </div>
                            )}
                            
                            <div className="scoreboard">
                                <h4>Punktestand</h4>
                                <div className="scores">
                                    {Object.entries(scores).map(([userId, scoreData]) => {
                                        const isCurrentUser = userId === socket?.id;
                                        const isHost = connectedUsers.find(u => u.id === "user1")?.id === userId;
                                        const playerName = typeof scoreData === 'object' ? 
                                            scoreData.name : 
                                            (connectedUsers.find(u => u.id === userId)?.name || "Player");
                                        const playerScore = typeof scoreData === 'object' ? scoreData.score : scoreData;
                                        
                                        return (
                                            <div key={userId} className={`score-entry ${isCurrentUser ? 'current-user' : ''}`}>
                                                <span className="player-name">
                                                    {isCurrentUser && "👉 "}
                                                    {playerName}
                                                    {isHost && (
                                                        <FontAwesomeIcon icon={faCrown} className="host-icon" />
                                                    )}
                                                </span>
                                                <span className="player-score">{playerScore}</span>
                                            </div>
                                        );
                                    })}
                                </div>
                            </div>
                            
                            {isHost ? (
                                <button className="next-round-button" onClick={handleNextRound}>
                                    Nächste Runde
                                </button>
                            ) : (
                                <p className="waiting-message">Warten auf Rundenwechsel durch Host...</p>
                            )}
                        </div>
                    </div>
                );
                
            default:
                return <div>Unknown phase</div>;
        }
    };

    return (
        <div className={`game-page ${phase === "composing" ? "with-otamatone" : ""}`}>
            <div className="background-overlay">
                <div className="rotating-gradient"></div>
            </div>
            
            <div className="game-header">
                <div className="game-role">
                    <FontAwesomeIcon icon={role === "composer" ? faMusic : faHeadphones} />
                    <span>{role === "composer" ? "Komponist" : "Rater"}</span>
                </div>
                <h2>ToneGuessr</h2>
                <div className="game-round">Runde {round}</div>
            </div>
            
            <div className="game-layout">
                <div className="main-content">
                    {renderPhaseContent()}
                </div>
                
                <div className="chat-panel">
                    <div className="chat-header">
                        <FontAwesomeIcon icon={faMessage} />
                        <div className="chat-title">Chat</div>
                    </div>
                    <div className="chat-messages">
                        {messages.map((message, index) => (
                            <div key={index} className={`message ${message.system ? 'system-message' : ''}`}>
                                {message.system ? (
                                    <span className="message-text system">{message.text}</span>
                                ) : (
                                    <>
                                        <span className="message-sender">{message.sender}:</span>
                                        <span className="message-text">{message.text}</span>
                                    </>
                                )}
                            </div>
                        ))}
                        <div ref={messageEndRef}></div>
                    </div>
                    <div className="chat-input">
                        <input type="text" value={inputValue} 
                               onChange={(e) => setInputValue(e.target.value)}
                               onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}
                               placeholder="Nachricht..." 
                        />
                        <button onClick={handleSendMessage} className="send-button">
                            <FontAwesomeIcon icon={faPaperPlane} />
                        </button>
                    </div>
                </div>
            </div>

            {phase === "composing" && (
                <MusicSlider 
                    isReadOnly={role !== "composer"} 
                    onFrequencyChange={handleFrequencyChange}
                    frequency={frequency}
                    composerIsPlaying={composerIsPlaying}
                />
            )}

            {songsLoading && (
                <div className="songs-loading-indicator">
                    Loading songs...
                </div>
            )}
        </div>
    );
};

export default Game;