const youtubeService = require('../services/youtubeService');

let cleanupGameState;

const setCleanupGameState = (cleanupFunction) => {
    cleanupGameState = cleanupFunction;
};

let rooms = {};

module.exports.roomExists = (roomId) => rooms[roomId] !== undefined;

module.exports.isRoomOpen = (roomId) => rooms[roomId] && rooms[roomId].state === 'waiting';

const initializeRoom = async (roomId, user) => {
    try {
        const randomPlaylists = await youtubeService.getRandomPlaylists(3);
        rooms[roomId] = {
            members: [{...user, creator: true}],
            settings: {},
            state: 'waiting',
            playlistVotes: {},
            selectedPlaylist: null,
            availablePlaylists: randomPlaylists
        };
    } catch (error) {
        console.error("Error initializing room playlists:", error);
        rooms[roomId] = {
            members: [{...user, creator: true}],
            settings: {},
            state: 'waiting',
            playlistVotes: {},
            selectedPlaylist: null,
            availablePlaylists: {
                seventies: youtubeService.PLAYLISTS.seventies
            }
        };
    }
};

module.exports.connectUserToRoom = async (roomId, user) => {
    roomId = roomId.toUpperCase();
    if (rooms[roomId]) {
        rooms[roomId].members.push({...user, creator: false});
    } else {
        await initializeRoom(roomId, user);
    }
    console.log(`User ${user.name} connected to room ${roomId}`);
};

module.exports.getUserRoom = (userId) => {
    for (const roomId in rooms) {
        const room = rooms[roomId];
        const memberIndex = room.members.findIndex(member => member.id === userId);

        if (memberIndex !== -1) return roomId;
    }
    return null;
}

module.exports.getRoomUsers = (roomId) => {
    if (rooms[roomId]) {
        return rooms[roomId].members;
    }
    return [];
}

module.exports.getRoomCreator = (roomId) => {
    if (rooms[roomId]) {
        return rooms[roomId].members.find(member => member.creator);
    }
    return null;
}

module.exports.isUserHost = (userId) => {
    for (const roomId in rooms) {
        const room = rooms[roomId];
        const member = room.members.find(m => m.id === userId);
        if (member && member.creator) {
            return true;
        }
    }
    return false;
}

module.exports.startGame = (roomId) => {
    if (rooms[roomId]) {
        rooms[roomId].state = 'playing';
        console.log(`Game started in room ${roomId}`);
        return true;
    }
    return false;
}

module.exports.getRoomState = (roomId) => {
    if (rooms[roomId]) {
        return rooms[roomId].state;
    }
    return null;
}

module.exports.disconnectUser = (userId) => {
    for (const roomId in rooms) {
        const room = rooms[roomId];
        const memberIndex = room.members.findIndex(member => member.id === userId);

        if (memberIndex !== -1) {
            if (room.members[memberIndex].creator && room.members.length > 1) {
                room.members[1].creator = true;
            }

            room.members.splice(memberIndex, 1);
            console.log(`User ${userId} disconnected from room ${roomId}`);

            if (room.members.length === 0) {
                if (cleanupGameState) {
                    cleanupGameState(roomId);
                }
                delete rooms[roomId];
                console.log(`Room ${roomId} deleted because it's empty`);
            }

            break;
        }
    }
}

module.exports.validateRoomMembers = (io, roomId) => {
    if (!rooms[roomId]) return [];
    
    const validMembers = [];
    const connectedSockets = io.sockets.adapter.rooms.get(roomId) || new Set();

    rooms[roomId].members = rooms[roomId].members.filter(member => {
        const stillConnected = connectedSockets.has(member.id);
        if (stillConnected) {
            validMembers.push(member);
        } else {
            console.log(`Removing disconnected user ${member.name} (${member.id}) from room ${roomId}`);
        }
        return stillConnected;
    });
    
    return validMembers;
}

module.exports.setCleanupGameState = setCleanupGameState;

module.exports.getUserName = (userId) => {
    for (const roomId in rooms) {
        const room = rooms[roomId];
        const member = room.members.find(m => m.id === userId);
        if (member) {
            return member.name;
        }
    }
    return null;
};

module.exports.voteForPlaylist = (roomId, userId, playlistId) => {
    if (!rooms[roomId]) return false;
    
    const room = rooms[roomId];
    if (room.state !== 'waiting') return false;

    if (!room.playlistVotes) {
        room.playlistVotes = {};
    }

    Object.entries(room.playlistVotes).forEach(([pid, voters]) => {
        room.playlistVotes[pid] = voters.filter(id => id !== userId);
    });

    if (!room.playlistVotes[playlistId]) {
        room.playlistVotes[playlistId] = [];
    }
    room.playlistVotes[playlistId].push(userId);
    
    console.log(`Updated votes for room ${roomId}:`, room.playlistVotes);
    return true;
};

module.exports.getPlaylistVotes = (roomId) => {
    return rooms[roomId]?.playlistVotes || {};
};

module.exports.getWinningPlaylist = (roomId) => {
    const room = rooms[roomId];
    if (!room || !room.playlistVotes) {
        console.log(`No votes found for room ${roomId}, using default playlist`);
        return room.availablePlaylists[Object.keys(room.availablePlaylists)[0]];
    }
    
    let maxVotes = 0;
    let winningPlaylist = null;
    
    console.log(`Calculating winning playlist for room ${roomId}`);
    console.log('Current votes:', room.playlistVotes);
    
    Object.entries(room.playlistVotes).forEach(([playlistId, voters]) => {
        console.log(`Playlist ${playlistId} has ${voters.length} votes`);
        if (voters.length > maxVotes) {
            maxVotes = voters.length;
            winningPlaylist = playlistId;
        }
    });
    
    if (!winningPlaylist) {
        console.log('No winning playlist found, using first available');
        winningPlaylist = room.availablePlaylists[Object.keys(room.availablePlaylists)[0]];
    }
    
    console.log(`Selected winning playlist: ${winningPlaylist}`);
    return winningPlaylist;
};

module.exports.getAvailablePlaylists = (roomId) => {
    return rooms[roomId]?.availablePlaylists || {};
};

module.exports.updateAvailablePlaylists = (roomId, newPlaylists) => {
    if (rooms[roomId]) {
        rooms[roomId].availablePlaylists = newPlaylists;
        rooms[roomId].playlistVotes = {};
        return true;
    }
    return false;
};