<script lang="ts">
    import { onMount } from "svelte";
    //@ts-ignore
    import { TAClient, Response_ResponseType, Map, Tournament, QualifierEvent, GameplayModifiers_GameOptions, QualifierEvent_EventSettings, QualifierEvent_LeaderboardSort } from 'moons-ta-client';
    import { TABotTokenStore, TAServerAPIPort, TAServerPort, TAServerUrl, authTokenStore, client } from "$lib/stores";
    import { bufferToImageUrl, convertImageToUint8Array, linkToUint8Array } from "$lib/services/taImages.js";
    import SideMenu from "$lib/components/menus/SideMenuTournaments.svelte";
    import Popup from "$lib/components/notifications/Popup.svelte";
    import InfoPopup from "$lib/components/notifications/InfoPopup.svelte";
    import EditMapModal from "$lib/components/popups/EditMap.svelte";
    import { goto } from "$app/navigation";
    import { saveAs } from 'file-saver';
    import * as XLSX from 'xlsx';
    import { fetchMapByHashOrKey, fetchMapsByLevelIds, type BeatSaverMap } from "$lib/services/beatsaver.js";
    import QualifierLeaderboard from "$lib/components/popups/QualifierLeaderboard.svelte";

    export let data;

    interface CustomMap {
        taData: Map,
        beatsaverData: BeatSaverMap
    }

    interface Score {
        accuracy: number;
        badCuts: number;
        color: string;
        eventId: string;
        fullCombo: boolean;
        goodCuts: number;
        isPlaceholder: boolean;
        mapId: string;
        maxCombo: number;
        maxPossibleScore: number;
        modifiedScore: number;
        multipliedScore: number;
        notesMissed: number;
        platformId: string;
        username: string;
    }

    const colorPresets = {
        primary: 'var(--accent-glow)',
        secondary: 'var(--text-secondary)',
        success: '#4CAF50',
        warning: '#FFC107',
        error: '#F44336',
        info: '#2196F3',
        default: 'var(--text-primary)'
    };
    type ColorPreset = keyof typeof colorPresets;
    
    type ButtonType = 'primary' | 'secondary' | 'text' | 'outlined';
    interface ButtonConfig {
        text: string;
        type: ButtonType;
        href?: string;
        color?: ColorPreset;
        icon?: string;
        action?: () => void;
    }

    const tournamentGuid: string = data.tournamentGuid;
    const qualifierGuid: string = data.qualifierGuid;
    
    let tournament: Tournament | undefined;
    let qualifier: QualifierEvent | undefined;
    let isLoading = false;
    let error: string | null = null;
    let maps: CustomMap[] = [];

    // Qualifier settings
    let qualifierName: string = "";
    let qualifierImage: Uint8Array = new Uint8Array([]);
    let qualifierImagePreview: string | null = null;
    let hideScoresFromPlayers: boolean = false;
    let disableScoresaberSubmission: boolean = false;
    let enableDiscordBotLeaderboard: boolean = false;
    let enableDiscordScoreFeed: boolean = false;
    let discordChannelId: string = "";
    let leaderboardSortType: QualifierEvent_LeaderboardSort = 0;

    // Leaderboard Popup variables
    let showLeaderboardPopup: boolean = false;
    let currentlyViewingLeaderboardMap: CustomMap | null;
    let currentlyViewingLeaderboardMapScores: Score[] = [];

    // Generic Modal default
    let modalMessage: string = "";
    let modalIcon: string = "check";
    let modalIconColor: ColorPreset = 'success';
    let modalButtons: ButtonConfig[] = [];
    let modalCustomImage: string = "";
    let modalAutoClose: number = 0; // no auto close
    let showGenericModal: boolean = false;

    // Export type definition
    type ExportType = 'json' | 'csv' | 'excel' | 'txt';
    let selectedExportType: ExportType = 'json';
    let showExportDropdown = false;

    enum MapDifficulty {
        "Easy" = 0,
        "Normal" = 1,
        "Hard" = 2,
        "Expert" = 3,
        "Expert+" = 4
    }

    const modifierNameMap: Record<number, string> = {
        [GameplayModifiers_GameOptions.None]: "",
        [GameplayModifiers_GameOptions.NoFail]: "No Fail",
        [GameplayModifiers_GameOptions.NoBombs]: "No Bombs",
        [GameplayModifiers_GameOptions.NoArrows]: "No Arrows",
        [GameplayModifiers_GameOptions.NoObstacles]: "No Walls",
        [GameplayModifiers_GameOptions.SlowSong]: "Slower Song",
        [GameplayModifiers_GameOptions.InstaFail]: "One Life",
        [GameplayModifiers_GameOptions.FailOnClash]: "Fail on Clash",
        [GameplayModifiers_GameOptions.BatteryEnergy]: "Four Lives",
        [GameplayModifiers_GameOptions.FastNotes]: "Fast Notes",
        [GameplayModifiers_GameOptions.FastSong]: "Faster Song",
        [GameplayModifiers_GameOptions.DisappearingArrows]: "Disappearing Arrows",
        [GameplayModifiers_GameOptions.GhostNotes]: "Ghost Notes",
        [GameplayModifiers_GameOptions.DemoNoFail]: "Demo No Fail",
        [GameplayModifiers_GameOptions.DemoNoObstacles]: "Demo No Obstacles",
        [GameplayModifiers_GameOptions.StrictAngles]: "Strict Angles",
        [GameplayModifiers_GameOptions.ProMode]: "Pro Mode",
        [GameplayModifiers_GameOptions.ZenMode]: "Zen Mode",
        [GameplayModifiers_GameOptions.SmallCubes]: "Small Notes",
        [GameplayModifiers_GameOptions.SuperFastSong]: "Super Fast Song"
    };
    
    // Modal states
    let showEditMapModal: boolean = false;
    let currentEditMap: Map | null = null;
    let showDeleteConfirmation = false;
    let mapToDelete: string | null = null;
    let showInfoPopup: boolean = false;
    let infoPopupContent: string = "";
    let successMessage = "";
    let fileInput: HTMLInputElement;

    if ($authTokenStore) {
        const cleanToken = $authTokenStore.replace('Bearer ', '');
        client.setAuthToken(cleanToken);
    }
    
    function openInfoPopup(content: string) {
        infoPopupContent = content;
        showInfoPopup = true;
    }
    
    function closeInfoPopup() {
        showInfoPopup = false;
    }
    
    function openEditMapModal(map: Map | null = null) {
        currentEditMap = map;
        showEditMapModal = true;
    }
    
    function closeEditMapModal() {
        showEditMapModal = false;
        currentEditMap = null;
    }
    
    function openDeleteConfirmation(mapId: string) {
        mapToDelete = mapId;
        showDeleteConfirmation = true;
    }
    
    function closeDeleteConfirmation() {
        showDeleteConfirmation = false;
        mapToDelete = null;
    }
    
    function closeNotification() {
        showGenericModal = false;
    }

    function handleImageUpload() {
        fileInput.click();
    }
    
    function onFileSelected(event: Event) {
        const target = event.target as HTMLInputElement;
        const files = target.files;
        
        if (files && files.length > 0) {
            const file = files[0];
            const reader = new FileReader();
            
            reader.onload = (e) => {
                const result = e.target?.result;
                if (result instanceof ArrayBuffer) {
                    qualifierImage = new Uint8Array(result);
                    console.log("result", result)
                    console.log("newQualImage", qualifierImage)
                    const blob = new Blob([result as ArrayBuffer], { type: file.type });
                    qualifierImagePreview = URL.createObjectURL(blob);
                }
            };
            
            reader.readAsArrayBuffer(file);
        }
    }

    async function saveQualifierSettings() {
        if (!qualifier) return;

        try {
            const setImageResponse = await client.setQualifierImage(tournamentGuid, qualifierGuid, qualifierImage);
            const setNameResponse = await client.setQualifierName(tournamentGuid, qualifierGuid, qualifierName);
            const setFlagsResponse = await client.setQualifierFlags(tournamentGuid, qualifierGuid, qualifier.flags);
            console.log("Qualifier Updated!", setImageResponse, setNameResponse, setFlagsResponse);

            modalMessage = `Successfully Updated the Qualifier!`;
            modalIcon = 'check';
            modalButtons = [];
            modalAutoClose = 1;
            showGenericModal = true;
        } catch (err) {
            console.error('Error saving qualifier settings:', err);
            error = err instanceof Error ? err.message : 'Failed to save settings';
        }
    }
    
    async function handleMapUpdated(event: CustomEvent) {
        await client.updateQualifierMap(tournamentGuid, qualifierGuid, event.detail.map);
        fetchQualifierData();
        modalMessage = `Successfully updated the map!`;
        modalIcon = 'check';
        modalButtons = [];
        modalAutoClose = 1;
        showGenericModal = true;
    }
    
    async function handleMapAdded(event: CustomEvent) {
        await client.addQualifierMaps(tournamentGuid, qualifierGuid, [event.detail.map]);
        fetchQualifierData();
        modalMessage = `Successfully added the map!`;
        modalIcon = 'check';
        modalButtons = [];
        modalAutoClose = 1;
        showGenericModal = true;
    }
    
    async function deleteMap() {
        if (!mapToDelete) return;
        
        isLoading = true;
        
        try {
            const removeMapResponse = await client.removeQualifierMap(tournamentGuid, qualifierGuid, mapToDelete);
            
            if (removeMapResponse.type !== Response_ResponseType.Success) {
                throw new Error("Failed to remove map! Please refresh this page!");
            }
            
            maps = maps.filter(map => map.taData.guid !== mapToDelete);
            modalMessage = `Successfully deleted the map!`;
            modalIcon = 'check';
            modalButtons = [];
            modalAutoClose = 1;
            showGenericModal = true;
        } catch (err) {
            console.error('Error deleting map:', err);
            error = err instanceof Error ? err.message : 'An unknown error occurred';
        } finally {
            isLoading = false;
            closeDeleteConfirmation();
        }
    }
    
    function goBackToQualifiers() {
        goto(`/tournaments/${tournamentGuid}/qualifiers`);
    }
    
    async function fetchQualifierData() {
        if (!$authTokenStore) {
            window.location.href = '/discordAuth';
            return;
        }
        
        isLoading = true;
        error = null;
        
        try {
            if(!client.isConnected) {
                const connectResult = await client.connect($TAServerUrl, $TAServerPort);
                if (connectResult.details.oneofKind === "connect" && connectResult.type === Response_ResponseType.Fail) {
                    throw new Error(connectResult.details.connect.message);
                }
            }
            
            if(!client.stateManager.getTournament(tournamentGuid)!.users.some(user => user.guid == client.stateManager.getSelfGuid())) {
                const joinResult = await client.joinTournament(tournamentGuid);
                if (joinResult.details.oneofKind !== 'join' || joinResult.type === Response_ResponseType.Fail) {
                    throw new Error('Could not join tournament');
                }
            }

            tournament = client.stateManager.getTournament(tournamentGuid)!;
            qualifier = tournament.qualifiers.find(q => q.guid === qualifierGuid);
            
            if (!qualifier) {
                throw new Error('Qualifier not found');
            }

            disableScoresaberSubmission = (qualifier.flags & QualifierEvent_EventSettings.DisableScoresaberSubmission) === QualifierEvent_EventSettings.DisableScoresaberSubmission;
            enableDiscordBotLeaderboard = (qualifier.flags & QualifierEvent_EventSettings.EnableDiscordLeaderboard) === QualifierEvent_EventSettings.EnableDiscordLeaderboard;
            enableDiscordScoreFeed = (qualifier.flags & QualifierEvent_EventSettings.EnableDiscordScoreFeed) === QualifierEvent_EventSettings.EnableDiscordScoreFeed;
            hideScoresFromPlayers = (qualifier.flags & QualifierEvent_EventSettings.HideScoresFromPlayers) === QualifierEvent_EventSettings.HideScoresFromPlayers;

            console.log("qualifier", qualifier)

            // Set initial values
            qualifierName = qualifier.name;
            qualifierImage = qualifier.image && qualifier.image.length > 2 ? await linkToUint8Array(`https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${qualifier.image}`) : new Uint8Array([]);
            qualifierImagePreview = qualifier.image && qualifier.image.length > 2 ? `https://${$TAServerUrl}:${$TAServerAPIPort}/api/file/${qualifier.image}` : '/talogo.png';
            
            // Load maps
            const mapLevelIds = qualifier.qualifierMaps.map(map => map.gameplayParameters!.beatmap!.levelId);
            const beatSaverMaps = await fetchMapsByLevelIds(mapLevelIds);
            
            maps = qualifier.qualifierMaps.map((map, index) => ({
                taData: map,
                beatsaverData: beatSaverMaps[index]
            }));

        } catch (err) {
            console.error('Error fetching qualifier data:', err);
            error = err instanceof Error ? err.message : 'An unknown error occurred';
        } finally {
            isLoading = false;
        }
    }

    function getActiveModifiersCompact(gameplayModifiers: number): string[] {
        const activeModifiers: string[] = [];
        const values = Object.values(GameplayModifiers_GameOptions)
            .filter((value): value is number => 
                typeof value === 'number' && 
                value !== GameplayModifiers_GameOptions.None &&
                value > 0
            )
            .sort((a, b) => a - b);
        
        for (const value of values) {
            if ((gameplayModifiers & value) === value) {
                const name = modifierNameMap[value];
                if (name && name.trim() !== "") {
                    activeModifiers.push(name);
                }
            }
        }
        
        return activeModifiers;
    }

    async function openLeaderboardPopup(map: CustomMap) {
        currentlyViewingLeaderboardMap = map;
        const mapScores = await client.getLeaderboard(tournamentGuid, qualifierGuid, map.taData.guid);
        currentlyViewingLeaderboardMapScores = (mapScores as any).details.leaderboardEntries.scores;
        showLeaderboardPopup = true;
    }

    function closeLeaderboardPopup() {
        showLeaderboardPopup = false;
    }

    function setFlag(flagType: QualifierEvent_EventSettings, flagValue: boolean) {
        if (!qualifier) return;
        
        qualifier.flags = flagValue 
            ? qualifier.flags | flagType      // Add flag
            : qualifier.flags & ~flagType;    // Remove flag
    }

    function getModifierArray(map: any): string[] {
        if (map.taData.gameplayParameters?.gameplayModifiers?.options == 0) {
            return [];
        }
        return getActiveModifiersCompact(map.taData.gameplayParameters?.gameplayModifiers?.options || 0);
    }

    function getCurrentlyEditingMap(): { taData: Map, beatsaverData: BeatSaverMap } | null | undefined {
        const tempMap = maps.find(map => map.taData.guid == currentEditMap?.guid);
        return tempMap ? tempMap : undefined;
    }

    async function handleDeleteQualifierClicked() {
        modalMessage = `Are you sure that you want to remove this qualifier? You will not be able to access the scores again and players will not be able to submit new scores!`;
        modalIcon = 'warning';
        modalIconColor = 'warning';
        modalButtons = [
            {
                text: 'Close (NO)',
                type: 'primary',
                icon: 'cancel',
                color: 'primary',
                action: () => showGenericModal = false,
            },
            {
                text: 'Delete (YES)',
                type: 'secondary',
                icon: 'warning',
                color: 'warning',
                action: async() => await handleDeleteQualifierConfirm(),
            },
        ];
        modalAutoClose = 0;
        showGenericModal = true;
    }

    async function handleDeleteQualifierConfirm() {
        const response = await client.deleteQualifierEvent(tournamentGuid, qualifierGuid);

        showGenericModal = false;
        goto(`/tournaments/${tournamentGuid}/qualifiers`);
    }

    async function formatLeaderboardData() {
        const mapsAndScores = [];
        
        // Use Promise.all to wait for all async operations
        const mapPromises = maps.map(async (map) => {
            const mapScoreResponse = await client.getLeaderboard(tournamentGuid, qualifierGuid, map.taData.guid);
            if(mapScoreResponse.type == Response_ResponseType.Fail) return;
            const mapScores = (mapScoreResponse as any).details.leaderboardEntries.scores;
            return {
                map: map,
                scores: (mapScores as any).map((score: Score) => ({
                    playerUsername: score.username,
                    playerPlatformId: score.platformId,
                    score: score.modifiedScore,
                    accuracy: score.accuracy,
                    misses: score.notesMissed,
                    badCuts: score.badCuts,
                    isFC: score.fullCombo,
                    multipliedScore: score.multipliedScore,
                    maxCombo: score.maxCombo,
                    goodCuts: score.goodCuts,
                    maxScore: score.maxPossibleScore
                }))
            };
        });
        
        const results = await Promise.all(mapPromises);
        return results;
    }

    // Export functions - only JSON and Excel as requested
    async function exportJSON() {
        const data = await formatLeaderboardData();
        const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
        saveAs(blob, `${qualifier!.name}_qualifier_scores.json`);
    }

    async function exportExcel() {
        const data = await formatLeaderboardData();
        const workbook = XLSX.utils.book_new();
        
        // Create a separate sheet for each map
        data.forEach((mapData) => {
            const worksheet = XLSX.utils.json_to_sheet(mapData!.scores);
            XLSX.utils.book_append_sheet(workbook, worksheet, mapData!.map.beatsaverData.metadata.songName.substring(0, 30) || "No Map Name");
        });
        
        XLSX.writeFile(workbook, `${qualifier!.name}_qualifier_scores.xlsx`);
    }

    async function handleExport() {
        switch(selectedExportType) {
            case 'json': 
                await exportJSON(); 
                break;
            case 'excel': 
                await exportExcel(); 
                break;
            default:
                console.warn('Unsupported export type:', selectedExportType);
                break;
        }
        showExportDropdown = false;
    }
    
    onMount(async() => {
        if ($authTokenStore) {
            await fetchQualifierData();
        } else {
            window.location.href = "/discordAuth";
        }
    });

    $: setFlag(QualifierEvent_EventSettings.HideScoresFromPlayers, hideScoresFromPlayers);
    $: setFlag(QualifierEvent_EventSettings.DisableScoresaberSubmission, disableScoresaberSubmission);
    $: setFlag(QualifierEvent_EventSettings.EnableDiscordScoreFeed, enableDiscordScoreFeed);
    $: setFlag(QualifierEvent_EventSettings.EnableDiscordLeaderboard, enableDiscordBotLeaderboard);
</script>

<div class="layout">
    <main class="dashboard">
        <SideMenu currentPage="qualifiers" tournamentName={tournament?.settings?.tournamentName} tournamnentGuid={tournamentGuid} />
        
        <div class="content-area">
            <div class="content-header">
                <div class="header-left">
                    <button class="back-button" on:click={goBackToQualifiers}>
                        <span class="material-icons">arrow_back</span>
                        Back to Qualifiers
                    </button>
                    <h2>{qualifierName || 'Qualifier'} Settings</h2>
                </div>
                <div class="actions">
                    {#if !error && !isLoading}
                        <button class="action-button save" on:click={saveQualifierSettings}>
                            <span class="material-icons">save</span>
                            Save Settings
                        </button>
                        <button class="action-button refresh" on:click={fetchQualifierData}>
                            <span class="material-icons">refresh</span>
                            Refresh
                        </button>
                    {/if}
                </div>
            </div>

            {#if isLoading}
                <div class="loading">
                    <div class="spinner"></div>
                    <p>Loading qualifier data...</p>
                </div>
            {:else if error}
                <div class="error-container">
                    <span class="material-icons">error_outline</span>
                    <p>{error}</p>
                    <button class="retry-button" on:click={fetchQualifierData}>Retry</button>
                </div>
            {:else}
                <!-- Qualifier Settings -->
                <div class="settings-section">
                    <div class="section-header">
                        <h3>Qualifier Settings</h3>
                        <div class="button-container">
                            <button class="action-button delete" on:click={handleDeleteQualifierClicked}>
                                <span class="material-icons">delete</span>
                                Delete Qualifier
                            </button>
                            <button class="info-button" on:click={() => openInfoPopup("Configure your qualifier settings including name, image, and Discord integration options.")}>
                                <span class="material-icons">info</span>
                            </button>
                        </div>
                    </div>

                    <div class="settings-grid">
                        <div class="setting-group">
                            <label for="qualifier-name">Qualifier Name</label>
                            <input 
                                id="qualifier-name" 
                                type="text" 
                                class="setting-input"
                                bind:value={qualifierName} 
                                placeholder="Enter qualifier name"
                            />
                        </div>

                        <div class="setting-group">
                            <!-- svelte-ignore a11y-label-has-associated-control -->
                            <label>Qualifier Image</label>
                            <div class="image-upload">
                                <div class="image-preview">
                                    <img src={qualifierImagePreview || '/talogo.png'} alt="Qualifier" />
                                </div>
                                <button class="upload-button" on:click={handleImageUpload}>
                                    <span class="material-icons">upload</span>
                                    Upload Image
                                </button>
                                <input 
                                    bind:this={fileInput}
                                    type="file" 
                                    accept="image/*" 
                                    on:change={onFileSelected}
                                    style="display: none;"
                                />
                            </div>
                        </div>

                        <div class="setting-group toggle-setting">
                            <div class="toggle-row">
                                <div class="toggle-label">
                                    <label for="hide-scores">Hide Scores From Players</label>
                                    <button class="info-button" on:click={() => openInfoPopup("When enabled, player scores will be hidden from other participants during the qualifier.")}>
                                        <span class="material-icons">info</span>
                                    </button>
                                </div>
                                <label class="toggle">
                                    <input type="checkbox" id="hide-scores" bind:checked={hideScoresFromPlayers} />
                                    <span class="slider"></span>
                                </label>
                            </div>
                        </div>

                        <div class="setting-group toggle-setting">
                            <div class="toggle-row">
                                <div class="toggle-label">
                                    <label for="disable-scoresaber">Disable ScoreSaber Submission</label>
                                    <button class="info-button" on:click={() => openInfoPopup("When enabled, scores from this qualifier will not be submitted to ScoreSaber.")}>
                                        <span class="material-icons">info</span>
                                    </button>
                                </div>
                                <label class="toggle">
                                    <input type="checkbox" id="disable-scoresaber" bind:checked={disableScoresaberSubmission} />
                                    <span class="slider"></span>
                                </label>
                            </div>
                        </div>

                        <div class="setting-group toggle-setting">
                            <div class="toggle-row">
                                <div class="toggle-label">
                                    <label for="enable-discord-leaderboard">Enable Discord Bot Leaderboard</label>
                                    <button class="info-button" on:click={() => openInfoPopup("When enabled, the bot will post leaderboard updates to the specified Discord channel.")}>
                                        <span class="material-icons">info</span>
                                    </button>
                                </div>
                                <label class="toggle">
                                    <input type="checkbox" id="enable-discord-leaderboard" bind:checked={enableDiscordBotLeaderboard} />
                                    <span class="slider"></span>
                                </label>
                            </div>
                        </div>

                        <div class="setting-group toggle-setting">
                            <div class="toggle-row">
                                <div class="toggle-label">
                                    <label for="enable-discord-feed">Enable Discord Score Feed</label>
                                    <button class="info-button" on:click={() => openInfoPopup("When enabled, individual scores will be posted to the specified Discord channel.")}>
                                        <span class="material-icons">info</span>
                                    </button>
                                </div>
                                <label class="toggle">
                                    <input type="checkbox" id="enable-discord-feed" bind:checked={enableDiscordScoreFeed} />
                                    <span class="slider"></span>
                                </label>
                            </div>
                        </div>

                        {#if enableDiscordBotLeaderboard || enableDiscordScoreFeed}
                            <div class="setting-group">
                                <label for="discord-channel">Discord Channel ID</label>
                                <input 
                                    id="discord-channel" 
                                    type="text" 
                                    class="setting-input"
                                    bind:value={discordChannelId} 
                                    placeholder="Enter Discord channel ID"
                                />
                            </div>
                        {/if}

                        <div class="setting-group">
                            <!-- <button class="info-button" on:click={() => openInfoPopup("Maps that players will compete on in this qualifier round.")}>
                                <span class="material-icons">info</span>
                            </button> -->
                            <label for="leaderboard-sort">Leaderboard Sort Type</label>
                            <select id="leaderboard-sort" bind:value={leaderboardSortType}>
                                <option value="score">Score</option>
                                <option value="accuracy">Accuracy</option>
                                <option value="time">Time</option>
                            </select>
                        </div>
                    </div>
                </div>

                <!-- Maps Section -->
                <div class="maps-section">
                    <div class="section-header">
                        <h3>Maps</h3>
                        <div class="button-container">
                            <div class="export-dropdown">
                                <button
                                    class="action-button add"
                                    class:disabled={maps.length === 0}
                                    on:click={() => showExportDropdown = !showExportDropdown}
                                    disabled={maps.length === 0}
                                >
                                    <span class="material-symbols-outlined">download</span>
                                    <span>Export All Scores</span>
                                </button>
                                {#if showExportDropdown}
                                    <div class="dropdown-content">
                                        <select bind:value={selectedExportType} class="export-select">
                                            <option value="json">JSON</option>
                                            <option value="excel">Excel</option>
                                        </select>
                                        <button class="export-action-btn" on:click={handleExport}>
                                            Export All Scores
                                        </button>
                                    </div>
                                {/if}
                            </div>
                            <div class="section-actions">
                                <button class="action-button add" on:click={() => openEditMapModal()}>
                                    <span class="material-icons">add</span>
                                    Add Map
                                </button>
                            </div>
                        </div>
                    </div>

                    {#if maps.length === 0}
                        <div class="no-maps">
                            <span class="material-icons">music_note</span>
                            <p>No maps have been added to this qualifier yet</p>
                            <button class="action-button add" on:click={() => openEditMapModal()}>
                                <span class="material-icons">add</span>
                                Add First Map
                            </button>
                        </div>
                    {:else}
                        <div class="maps-list">
                            {#each maps as map}
                                <div class="map-card">
                                    <div class="map-content">
                                        <div class="map-image">
                                            <img 
                                                src={map.beatsaverData.versions[0].coverURL} 
                                                alt="{map.taData.gameplayParameters?.beatmap?.name} cover"
                                            />
                                        </div>
                                        <div class="map-info">
                                            <h4>{map.taData.gameplayParameters?.beatmap?.name}</h4>
                                            <p class="map-author">By {map.beatsaverData.metadata.levelAuthorName || "Unknown Artist"}</p>
                                            <div class="map-details">
                                                {#if map.taData.gameplayParameters?.beatmap?.difficulty}
                                                    <span class="map-difficulty">
                                                        <span class="material-icons">speed</span>
                                                        {MapDifficulty[map.taData.gameplayParameters?.beatmap?.difficulty]}
                                                    </span>
                                                {/if}
                                                {#if map.beatsaverData.metadata.duration}
                                                    <span class="map-length">
                                                        <span class="material-icons">access_time</span>
                                                        {Math.floor(map.beatsaverData.metadata.duration / 60)}:{(map.beatsaverData.metadata.duration % 60).toString().padStart(2, '0')}
                                                    </span>
                                                {/if}
                                            </div>
                                        </div>
                                        <div class="map-actions">
                                            <button 
                                                class="map-action view" 
                                                title="View map scores" 
                                                on:click={() => openLeaderboardPopup(map)}
                                            >
                                                <span class="material-icons">visibility</span>
                                            </button>
                                            <button 
                                                class="map-action edit" 
                                                title="Edit map" 
                                                on:click={() => openEditMapModal(map.taData)}
                                            >
                                                <span class="material-icons">edit</span>
                                            </button>
                                            <button 
                                                class="map-action delete" 
                                                title="Delete map" 
                                                on:click={() => openDeleteConfirmation(map.taData.guid)}
                                            >
                                                <span class="material-icons">delete</span>
                                            </button>
                                        </div>
                                    </div>
                                    <div class="map-modifiers">
                                        <h5>Active Modifiers</h5>
                                        <div class="modifier-tags">
                                            {#each getModifierArray(map) as modifier}
                                                <span class="modifier-tag">{modifier}</span>
                                            {:else}
                                                <span class="no-modifiers">No modifiers active</span>
                                            {/each}
                                            {#if map.taData.gameplayParameters?.disableFail}
                                                <span class="modifier-tag">Disable Fail</span>
                                            {/if}
                                            {#if map.taData.gameplayParameters?.disableCustomNotesOnStream}
                                                <span class="modifier-tag">Disable Custom Notes On Stream</span>
                                            {/if}
                                            {#if map.taData.gameplayParameters?.disablePause}
                                                <span class="modifier-tag">Disable Pause</span>
                                            {/if}
                                            {#if map.taData.gameplayParameters?.disableScoresaberSubmission}
                                                <span class="modifier-tag">Disable ScoreSaber Submission</span>
                                            {/if}
                                        </div>
                                    </div>
                                </div>
                            {/each}
                        </div>
                    {/if}
                </div>
            {/if}
        </div>
    </main>
</div>

<!-- Edit Map Modal -->
{#if showEditMapModal}
    <EditMapModal 
        tournamentGuid={tournamentGuid}
        map={getCurrentlyEditingMap()}
        on:close={closeEditMapModal} 
        on:mapUpdated={handleMapUpdated}
        on:mapAdded={handleMapAdded}
        mode='qualifier'
    />
{/if}

<!-- Info Popup -->
{#if showInfoPopup}
    <InfoPopup content={infoPopupContent} onClose={closeInfoPopup} />
{/if}

<!-- Delete Confirmation Popup -->
{#if showDeleteConfirmation}
    <div class="popup-overlay">
        <div class="popup-container delete-confirmation">
            <div class="popup-header">
                <h3>Delete Map</h3>
                <button class="close-button" on:click={closeDeleteConfirmation}>
                    <span class="material-icons">close</span>
                </button>
            </div>
            
            <div class="popup-content">
                <p>Are you sure you want to delete this map?</p>
                <p class="warning">This action cannot be undone!</p>
                
                <div class="popup-actions">
                    <button class="action-button cancel" on:click={closeDeleteConfirmation}>Cancel</button>
                    <button class="action-button delete" on:click={deleteMap}>
                        Delete Map
                    </button>
                </div>
            </div>
        </div>
    </div>
{/if}

{#if showLeaderboardPopup}
    <QualifierLeaderboard 
        mapData={currentlyViewingLeaderboardMap} 
        scores={currentlyViewingLeaderboardMapScores} 
        sortType={qualifier?.sort} 
        on:close={closeLeaderboardPopup} 
    />
{/if}

<!-- Success Notification -->
<Popup
    bind:open={showGenericModal}
    message={modalMessage}
    icon={modalIcon}
    iconColor={modalIconColor}
    buttons={modalButtons}
    autoClose={modalAutoClose}
    on:close={closeNotification}
/>

<style>
    .layout {
        display: flex;
        height: 100vh;
        overflow: hidden;
    }
    
    .dashboard {
        display: flex;
        flex: 1;
        overflow: hidden;
    }
    
    .content-area {
        flex: 1;
        padding: 2rem;
        overflow-y: auto;
    }
    
    .content-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 2rem;
    }
    
    .header-left {
        display: flex;
        align-items: center;
        gap: 1rem;
    }
    
    .back-button {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        background: none;
        border: none;
        color: var(--accent-color);
        font-weight: 500;
        padding: 0.5rem 0;
        cursor: pointer;
        transition: color 0.2s;
        margin-right: 2rem;
    }
    
    .back-button:hover {
        color: var(--accent-hover);
    }
    
    .content-header h2 {
        font-size: 1.5rem;
        font-weight: 600;
        margin: 0;
    }
    
    .actions {
        display: flex;
        gap: 0.75rem;
    }
    
    .action-button {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        background-color: var(--bg-secondary);
        border: none;
        border-radius: 0.375rem;
        color: var(--text-primary);
        font-weight: 500;
        padding: 0.5rem 1rem;
        cursor: pointer;
        transition: background-color 0.2s;
    }
    
    .action-button.add, .action-button.save {
        background-color: var(--accent-color);
        color: white;
    }
    
    .action-button.add:hover, .action-button.save:hover {
        background-color: var(--accent-hover);
    }
    
    .action-button.cancel {
        background-color: var(--bg-secondary);
    }
    
    .action-button.cancel:hover {
        background-color: var(--bg-tertiary);
    }
    
    .action-button.delete {
        background-color: #c64141;
        color: white;
    }
    
    .action-button.delete:hover {
        background-color: #ff3333;
    }
    
    .action-button.refresh:hover {
        background-color: var(--bg-tertiary);
    }

    .settings-section, .maps-section {
        background-color: var(--bg-secondary);
        border-radius: 0.5rem;
        padding: 1.5rem;
        margin-bottom: 2rem;
    }

    .button-container {
        display: flex;
        align-items: center;
        gap: 1rem;
    }

    .section-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 1.5rem;
    }

    .section-header h3 {
        font-size: 1.25rem;
        font-weight: 500;
        margin: 0;
    }

    .section-actions {
        display: flex;
        align-items: center;
        gap: 0.5rem;
    }

    .info-button {
        background: none;
        border: none;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        color: var(--accent-color);
        padding: 0;
    }
    
    .info-button:hover {
        color: var(--accent-hover);
    }

    .settings-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 1.5rem;
    }

    .setting-group {
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
    }

    .setting-group label {
        font-weight: 500;
        display: flex;
        align-items: center;
        gap: 0.5rem;
    }

    .setting-group input[type="text"], .setting-group select {
        padding: 0.75rem;
        border: 1px solid var(--bg-tertiary);
        border-radius: 0.375rem;
        background-color: var(--bg-primary);
        color: var(--text-primary);
    }

    .setting-group input[type="checkbox"] {
        margin: 0;
    }

    .image-upload {
        display: flex;
        align-items: center;
        gap: 1rem;
    }

    .image-preview {
        width: 4rem;
        height: 4rem;
        border-radius: 0.375rem;
        overflow: hidden;
    }

    .image-preview img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .upload-button {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        background-color: var(--bg-tertiary);
        border: none;
        border-radius: 0.375rem;
        color: var(--text-primary);
        font-weight: 500;
        padding: 0.5rem 1rem;
        cursor: pointer;
        transition: background-color 0.2s;
    }

    .upload-button:hover {
        background-color: var(--bg-primary);
    }

    .maps-list {
        display: flex;
        flex-direction: column;
        gap: 1rem;
    }
    
    .map-card {
        background-color: var(--bg-primary);
        border-radius: 0.5rem;
        padding: 1.25rem;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
    
    .map-content {
        display: flex;
        gap: 1.25rem;
    }
    
    .map-image {
        flex-shrink: 0;
        width: 6rem;
        height: 6rem;
    }
    
    .map-image img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        border-radius: 0.375rem;
        background-color: var(--bg-tertiary);
    }
    
    .map-info {
        flex: 1;
        display: flex;
        flex-direction: column;
    }
    
    .map-info h4 {
        margin: 0 0 0.25rem 0;
        font-size: 1.125rem;
        font-weight: 500;
    }
    
    .map-author {
        color: var(--text-secondary);
        margin: 0 0 0.5rem 0;
        font-size: 0.875rem;
    }
    
    .map-details {
        display: flex;
        gap: 1rem;
        margin-top: 0.5rem;
    }
    
    .map-difficulty, .map-length {
        display: flex;
        align-items: center;
        gap: 0.25rem;
        font-size: 0.875rem;
        color: var(--text-secondary);
    }
    
    .map-difficulty .material-icons,
    .map-length .material-icons {
        font-size: 1rem;
    }
    
    .map-actions {
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
        align-self: flex-start;
    }
    
    .map-action {
        display: flex;
        align-items: center;
        justify-content: center;
        background: none;
        border: none;
        cursor: pointer;
        padding: 0.5rem;
        border-radius: 0.375rem;
        transition: background-color 0.2s;
    }
    
    .map-action.edit {
        color: var(--accent-color);
    }
    
    .map-action.edit:hover {
        background-color: var(--bg-secondary);
        color: var(--accent-hover);
    }

    .map-action.view {
        color: var(--accent-hover);
    }
    
    .map-action.view:hover {
        background-color: var(--bg-secondary);
        color: var(--accent-glow);
    }
    
    .map-action.delete {
        color: #ff5555;
    }
    
    .map-action.delete:hover {
        background-color: rgba(255, 85, 85, 0.1);
        color: #ff3333;
    }
    
    .map-modifiers {
        margin-top: 1rem;
        padding-top: 1rem;
        border-top: 1px solid var(--bg-secondary);
    }
    
    .map-modifiers h5 {
        margin: 0 0 0.75rem 0;
        font-size: 0.875rem;
        font-weight: 500;
        color: var(--text-secondary);
        text-transform: uppercase;
        letter-spacing: 0.025em;
    }
    
    .modifier-tags {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
    }
    
    .modifier-tag {
        background-color: var(--accent-color);
        color: white;
        font-size: 0.75rem;
        font-weight: 500;
        padding: 0.25rem 0.5rem;
        border-radius: 0.25rem;
    }
    
    .no-modifiers {
        color: var(--text-secondary);
        font-size: 0.875rem;
        font-style: italic;
    }
    
    .no-maps {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 3rem;
        text-align: center;
        color: var(--text-secondary);
    }
    
    .no-maps .material-icons {
        font-size: 3rem;
        margin-bottom: 1rem;
        opacity: 0.5;
    }
    
    .no-maps p {
        margin: 0 0 1.5rem 0;
        font-size: 1.125rem;
    }
    
    .loading {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 3rem;
        text-align: center;
    }
    
    .spinner {
        width: 2rem;
        height: 2rem;
        border: 2px solid var(--bg-tertiary);
        border-top: 2px solid var(--accent-color);
        border-radius: 50%;
        animation: spin 1s linear infinite;
        margin-bottom: 1rem;
    }
    
    @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }
    
    .loading p {
        margin: 0;
        color: var(--text-secondary);
    }
    
    .error-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 3rem;
        text-align: center;
        color: #ff5555;
    }
    
    .error-container .material-icons {
        font-size: 3rem;
        margin-bottom: 1rem;
        opacity: 0.7;
    }
    
    .error-container p {
        margin: 0 0 1.5rem 0;
        font-size: 1.125rem;
    }
    
    .retry-button {
        background-color: var(--accent-color);
        color: white;
        border: none;
        border-radius: 0.375rem;
        padding: 0.75rem 1.5rem;
        font-weight: 500;
        cursor: pointer;
        transition: background-color 0.2s;
    }
    
    .retry-button:hover {
        background-color: var(--accent-hover);
    }
    
    .popup-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 1000;
    }
    
    .popup-container {
        background-color: var(--bg-secondary);
        border-radius: 0.5rem;
        width: 90%;
        max-width: 400px;
        box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
    }
    
    .popup-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 1.5rem 1.5rem 0 1.5rem;
    }
    
    .popup-header h3 {
        margin: 0;
        font-size: 1.25rem;
        font-weight: 500;
    }
    
    .close-button {
        background: none;
        border: none;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        color: var(--text-secondary);
        padding: 0;
    }
    
    .close-button:hover {
        color: var(--text-primary);
    }
    
    .popup-content {
        padding: 1.5rem;
    }
    
    .popup-content p {
        margin: 0 0 1rem 0;
        line-height: 1.5;
    }
    
    .warning {
        color: #ff5555;
        font-weight: 500;
    }
    
    .popup-actions {
        display: flex;
        gap: 0.75rem;
        justify-content: flex-end;
        margin-top: 1.5rem;
    }

    /* Toggle Settings */
    .toggle-setting {
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
    }
    
    .toggle-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        padding: 0.5rem 0;
    }
    
    .toggle-label {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        flex: 1;
    }
    
    .toggle-label label {
        font-weight: 500;
        font-size: 0.9375rem;
        margin: 0;
        cursor: pointer;
    }
    
    /* Toggle switch */
    .toggle {
        position: relative;
        display: inline-block;
        width: 3rem;
        height: 1.5rem;
        flex-shrink: 0;
    }
    
    .toggle input {
        opacity: 0;
        width: 0;
        height: 0;
    }
    
    .slider {
        position: absolute;
        cursor: pointer;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: var(--bg-tertiary);
        transition: 0.3s ease;
        border-radius: 1.5rem;
    }
    
    .slider:before {
        position: absolute;
        content: "";
        height: 1.125rem;
        width: 1.125rem;
        left: 0.1875rem;
        bottom: 0.1875rem;
        background-color: var(--text-secondary);
        transition: 0.3s ease;
        border-radius: 50%;
    }
    
    input:checked + .slider {
        background-color: var(--accent-color);
    }
    
    input:checked + .slider:before {
        transform: translateX(1.5rem);
        background-color: white;
    }
    
    input:focus + .slider {
        box-shadow: 0 0 0 2px rgba(var(--accent-color-rgb), 0.2);
    }
    
    .toggle:hover .slider {
        opacity: 0.8;
    }

    .setting-input {
        background-color: var(--bg-tertiary);
        border: none;
        border-radius: 0.375rem;
        padding: 0.625rem 0.75rem;
        color: var(--text-primary);
        font-size: 0.9375rem;
        width: 100%;
    }
    
    .setting-input:focus {
        outline: 2px solid var(--accent-color);
    }

    /* Export styles */
    .btn {
        display: flex;
        align-items: center;
        gap: 0.25rem;
        background-color: var(--button-bg);
        color: var(--text);
        border: none;
        border-radius: 6px;
        padding: 0.625rem 1rem;
        font-size: 0.875rem;
        font-weight: 500;
        cursor: pointer;
        transition: all 0.2s ease;
    }

    .btn:hover {
        background-color: var(--button-hover-bg);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
    }

    .export-btn {
        background-color: var(--comfortable-blue);
        color: white;
        position: relative;
        box-shadow: 0 0 10px rgb(71, 73, 202);
    }

    .export-btn:hover:not(.disabled) {
        background-color: rgb(71, 73, 202);
        border-color: rgba(255, 255, 255, 0.2);
    }

    .export-btn.disabled {
        background-color: #4a4a4a;
        color: #888888;
        cursor: not-allowed;
        opacity: 0.6;
        transform: none;
        box-shadow: none;
    }

    .export-dropdown {
        position: relative;
        z-index: 100;
    }

    .dropdown-content {
        position: absolute;
        top: calc(100% + 8px);
        right: 0;
        background-color: var(--bg-secondary);
        border: 2px solid #4fc3f7;
        border-radius: 8px;
        padding: 1rem;
        z-index: 1001;
        min-width: 200px;
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 20px rgba(79, 195, 247, 0.3);
        animation: dropdownSlide 0.2s ease-out;
    }

    @keyframes dropdownSlide {
        from {
            opacity: 0;
        }
        to {
            opacity: 1;
        }
    }

    .dropdown-content::before {
        content: '';
        position: absolute;
        top: -10px;
        right: 16px;
        width: 0;
        height: 0;
        border-left: 8px solid transparent;
        border-right: 8px solid transparent;
        border-bottom: 8px solid #4fc3f7;
    }

    .export-select {
        background-color: var(--bg-secondary);
        color: var(--text);
        border: 1px solid #555;
        border-radius: 6px;
        padding: 0.5rem 0.75rem;
        font-size: 0.875rem;
        width: 100%;
        cursor: pointer;
        transition: all 0.2s ease;
        outline: none;
    }

    .export-select:hover {
        border-color: #4fc3f7;
        background-color: rgba(79, 195, 247, 0.05);
    }

    .export-select:focus {
        border-color: #4fc3f7;
        box-shadow: 0 0 0 2px rgba(79, 195, 247, 0.2);
        background-color: rgba(79, 195, 247, 0.05);
    }

    .export-action-btn {
        background-color: var(--pick-green);
        color: white;
        border: none;
        border-radius: 6px;
        padding: 0.5rem 1rem;
        font-size: 0.875rem;
        font-weight: 500;
        cursor: pointer;
        transition: all 0.2s ease;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }

    .export-action-btn:hover {
        background-color: var(--pick-green-hover);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
    }

    .export-action-btn:active {
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
    
    /* Responsive Design */
    @media (max-width: 768px) {
        .content-area {
            padding: 1rem;
        }
        
        .content-header {
            flex-direction: column;
            align-items: flex-start;
            gap: 1rem;
        }
        
        .header-left {
            width: 100%;
        }
        
        .actions {
            width: 100%;
            justify-content: flex-end;
        }
        
        .settings-grid {
            grid-template-columns: 1fr;
        }
        
        .map-content {
            flex-direction: column;
            gap: 1rem;
        }
        
        .map-image {
            width: 100%;
            height: 12rem;
        }
        
        .map-actions {
            flex-direction: row;
            justify-content: flex-end;
            align-self: stretch;
        }
        
        .image-upload {
            flex-direction: column;
            align-items: flex-start;
        }
        
        .popup-container {
            margin: 1rem;
        }
    }
    
    @media (max-width: 480px) {
        .back-button {
            margin-right: 0;
            margin-bottom: 0.5rem;
        }
        
        .header-left {
            flex-direction: column;
            align-items: flex-start;
            gap: 0.5rem;
        }
        
        .action-button {
            font-size: 0.875rem;
            padding: 0.5rem 0.75rem;
        }
        
        .map-details {
            flex-direction: column;
            gap: 0.5rem;
        }
        
        .modifier-tags {
            gap: 0.25rem;
        }
        
        .modifier-tag {
            font-size: 0.6875rem;
            padding: 0.1875rem 0.375rem;
        }
    }
</style>