<script lang="ts">
    import { onMount } from 'svelte';

    interface Difficulty {
        characteristic: string;
        name: string;
    }

    interface Song {
        hash: string;
        difficulties: Difficulty[];
    }

    interface MapPool {
        playlistTitle: string;
        playlistAuthor: string;
        playlistDescription: string;
        syncURL: string;
        image: string;
        songs: Song[];
    }

    interface BeatSaverMap {
        id: string;
        name: string;
        description: string;
        uploader: {
            name: string;
        };
        metadata: {
            songName: string;
            songAuthorName: string;
            levelAuthorName: string;
        };
        versions: Array<{
            hash: string;
            diffs: Array<{
                difficulty: string;
                characteristic: string;
                nps: number;
                notes: number;
            }>;
        }>;
    }

    interface MapData extends BeatSaverMap {
        selectedDifficulty: string;
        selectedCharacteristic: string;
        maxScore: number;
        nps: number;
    }

    let mapPool: MapPool | null = null;
    let maps: MapData[] = [];
    let selectedMapIndex: number | null = null;
    let loading = false;
    let resultsInput = '';
    let calculatedResults = '';
    let copied = false;
    let fileInput: HTMLInputElement;

    onMount(() => {
        const defaultPool: MapPool = {
            playlistTitle: "Week 2",
            playlistAuthor: "Cube Community",
            playlistDescription: "The Bo7 Week 2 Map Pool for the Beat Saber World Cup 2025",
            syncURL: "https://api.cube.community/rest/pooling/playlist?poolId=cm94fsme0000ty9u9h3d3par0",
            image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
            songs: [
                {"hash":"bce7949bd6b9432782b543c77014fddc756a6894","difficulties":[{"characteristic":"Standard","name":"expert"}]},
                {"hash":"e2e71212e6468506b35ab08986918f317157cddc","difficulties":[{"characteristic":"Standard","name":"easy"}]},
                {"hash":"40f74ba3c2a4475acabb8e2a1d5eb9219f36e043","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"55710205349cc4b25e09644d797d119ef964bd1d","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"62d66da2dd4ee601b24ee608847fb3657a78e761","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"9109925c3719d232e3eeae8868c0bf1efd660d51","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"93d5adc1756f488ad85484279831f327d94efe64","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"95d9d9e21c381f2e41073ca3257208174e90b322","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"b907db0d67ab965b4b702d242463a44e01c5ecd3","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"d67821c494b38ff51860766d853ba8f5d82ca104","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]},
                {"hash":"a1c6d47059e479ae493d118b4c7e5a1ef1340e99","difficulties":[{"characteristic":"Standard","name":"expertPlus"}]}
            ]
        };
        
        mapPool = defaultPool;
        fetchMapsData(defaultPool);
    });

    async function fetchMapsData(pool: MapPool) {
        loading = true;
        const mapData: MapData[] = [];
        
        for (const song of pool.songs) {
            try {
                const response = await fetch(`https://api.beatsaver.com/maps/hash/${song.hash}`);
                if (response.ok) {
                    const data: BeatSaverMap = await response.json();
                    
                    // Find the selected difficulty
                    const selectedDiff = song.difficulties[0];
                    const version = data.versions.find(v => v.hash.toLowerCase() === song.hash.toLowerCase());
                    
                    if (version) {
                        const diff = version.diffs.find(d => 
                            d.difficulty.toLowerCase() === selectedDiff.name.toLowerCase() && 
                            d.characteristic === selectedDiff.characteristic
                        );
                        
                        if (diff) {
                            const maxScore = diff.notes * 920; // Max score per note in Beat Saber
                            
                            mapData.push({
                                ...data,
                                selectedDifficulty: selectedDiff.name,
                                selectedCharacteristic: selectedDiff.characteristic,
                                maxScore,
                                nps: diff.nps
                            });
                        }
                    }
                }
            } catch (error) {
                console.error(`Error fetching map ${song.hash}:`, error);
            }
        }
        
        maps = mapData;
        loading = false;
    }

    async function handleFileUpload(event: Event) {
        const target = event.target as HTMLInputElement;
        const file = target.files?.[0];
        if (!file) return;

        const text = await file.text();
        try {
            const pool: MapPool = JSON.parse(text);
            mapPool = pool;
            fetchMapsData(pool);
        } catch (error) {
            console.error('Error parsing map pool file:', error);
        }
    }

    function calculateResults() {
        if (selectedMapIndex === null || selectedMapIndex < 0 || !maps[selectedMapIndex]) return;

        const selectedMap = maps[selectedMapIndex];
        const maxScore = selectedMap.maxScore;

        // Parse results input
        const lines = resultsInput.trim().split('\n');
        const scores: Array<{ country: string; score: number; accuracy: number }> = [];
        let winner = '';

        lines.forEach(line => {
            const scoreMatch = line.match(/(.+?)\s+Score:\s*([\d,]+)/);
            const winnerMatch = line.match(/Winner:\s*(.+)/);
            
            if (scoreMatch) {
                const country = scoreMatch[1].trim();
                const score = parseInt(scoreMatch[2].replace(/,/g, ''));
                const accuracy = (score / maxScore) * 100 / 3; // Divide by 3 for average accuracy
                scores.push({ country, score, accuracy });
            } else if (winnerMatch) {
                winner = winnerMatch[1].trim();
            }
        });

        // Format results
        let result = '';
        scores.forEach(({ country, score, accuracy }) => {
            result += `${country} Score: ${score.toLocaleString()} (${accuracy.toFixed(3)}%)\n`;
        });
        
        if (winner) {
            result += `Winner: ${winner}`;
        }

        calculatedResults = result;
    }

    async function copyResults() {
        if (calculatedResults) {
            await navigator.clipboard.writeText(calculatedResults);
            copied = true;
            setTimeout(() => copied = false, 2000);
        }
    }

    function getDifficultyColor(difficulty: string): string {
        switch (difficulty.toLowerCase()) {
            case 'easy': return 'text-green-400';
            case 'normal': return 'text-blue-400';
            case 'hard': return 'text-orange-400';
            case 'expert': return 'text-red-400';
            case 'expertplus': return 'text-purple-400';
            default: return 'text-gray-400';
        }
    }

    function selectMap(index: number) {
        selectedMapIndex = index;
        calculateResults();
    }

    // Reactive statement to recalculate when inputs change
    $: if (resultsInput && selectedMapIndex !== null) {
        calculateResults();
    }
</script>

<body>
    <div class="container">
        <!-- Header -->
        <div class="header">
            <div class="header-controls">
                <label class="file-upload-label">
                    <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
                    </svg>
                    Load Map Pool
                    <input
                        bind:this={fileInput}
                        type="file"
                        accept=".bplist,.json"
                        on:change={handleFileUpload}
                        class="file-upload-input"
                    />
                </label>
                {#if loading}
                    <div class="loading-text">Loading maps...</div>
                {/if}
            </div>

            {#if mapPool}
                <div class="map-pool-info">
                    <img 
                        src={mapPool.image} 
                        alt={mapPool.playlistTitle}
                        class="map-pool-image"
                    />
                    <div>
                        <h1 class="map-pool-title">{mapPool.playlistTitle}</h1>
                        <p class="map-pool-author">by {mapPool.playlistAuthor}</p>
                        <p class="map-pool-description">{mapPool.playlistDescription}</p>
                    </div>
                </div>
            {/if}
        </div>

        <!-- Maps Grid -->
        <div class="maps-grid">
            {#each maps as map, index}
                <div
                    class="map-card {selectedMapIndex === index ? 'selected' : ''}"
                    on:click={() => selectMap(index)}
                    role="button"
                    tabindex="0"
                    on:keydown={(e) => e.key === 'Enter' && selectMap(index)}
                >
                    <div class="map-content">
                        <h3 class="map-title">
                            {map.metadata.songName}
                        </h3>
                        <p class="map-author">by {map.metadata.songAuthorName}</p>
                        <p class="map-mapper">mapped by {map.metadata.levelAuthorName}</p>
                        
                        <div class="map-details">
                            <div class="map-difficulty-row">
                                <span class="map-difficulty difficulty-{map.selectedDifficulty.toLowerCase()}">
                                    {map.selectedDifficulty.charAt(0).toUpperCase() + map.selectedDifficulty.slice(1)}
                                </span>
                                <span class="map-nps">{map.nps.toFixed(1)} NPS</span>
                            </div>
                            <div class="map-score">
                                Max Score: {map.maxScore.toLocaleString()}
                            </div>
                        </div>
                    </div>
                </div>
            {/each}
        </div>

        <!-- Results Section -->
        <div class="results-section">
            <div class="results-column">
                <h2>Enter Results</h2>
                <textarea
                    bind:value={resultsInput}
                    placeholder="United Kingdom Score: 1,238,773&#10;Poland Score: 1,233,813&#10;Winner: United Kingdom"
                    class="results-textarea"
                ></textarea>
            </div>

            <div class="results-column">
                <div class="results-header">
                    <h2>Calculated Results</h2>
                    {#if calculatedResults}
                        <button
                            on:click={copyResults}
                            class="copy-button"
                        >
                            {#if copied}
                                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
                                </svg>
                                Copied!
                            {:else}
                                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
                                </svg>
                                Copy
                            {/if}
                        </button>
                    {/if}
                </div>
                <textarea
                    bind:value={calculatedResults}
                    readonly
                    class="results-textarea"
                ></textarea>
            </div>
        </div>

        {#if selectedMapIndex !== null && maps[selectedMapIndex]}
            <div class="selected-map-info">
                <h3>Currently Selected:</h3>
                <p class="selected-map-name">{maps[selectedMapIndex].metadata.songName}</p>
                <p class="selected-map-score">Max Score: {maps[selectedMapIndex].maxScore.toLocaleString()}</p>
            </div>
        {/if}
    </div>
</body>

<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    body {
        min-height: 100vh;
        color: white;
        padding: 24px;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    }

    .container {
        max-width: 1280px;
        margin: 0 auto;
    }

    /* Header */
    .header {
        margin-bottom: 32px;
    }

    .header-controls {
        display: flex;
        align-items: center;
        gap: 16px;
        margin-bottom: 24px;
    }

    .file-upload-label {
        display: flex;
        align-items: center;
        gap: 8px;
        background-color: #2563eb;
        padding: 8px 16px;
        border-radius: 8px;
        cursor: pointer;
        transition: background-color 0.2s;
    }

    .file-upload-label:hover {
        background-color: #1d4ed8;
    }

    .file-upload-label svg {
        width: 20px;
        height: 20px;
    }

    .file-upload-input {
        display: none;
    }

    .loading-text {
        color: #60a5fa;
    }

    .map-pool-info {
        background-color: #1f2937;
        border-radius: 12px;
        padding: 24px;
        display: flex;
        align-items: center;
        gap: 24px;
    }

    .map-pool-image {
        width: 80px;
        height: 80px;
        border-radius: 8px;
        object-fit: cover;
    }

    .map-pool-title {
        font-size: 30px;
        font-weight: bold;
        color: white;
        margin: 0;
    }

    .map-pool-author {
        color: #d1d5db;
        margin: 4px 0;
    }

    .map-pool-description {
        color: #9ca3af;
        margin-top: 8px;
    }

    /* Maps Grid */
    .maps-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 24px;
        margin-bottom: 32px;
    }

    .map-card {
        background-color: #1f2937;
        border-radius: 12px;
        padding: 24px;
        cursor: pointer;
        transition: all 0.3s;
        opacity: 0.8;
        display: flex;
        flex-direction: column;
        height: 100%;
    }

    .map-card:hover {
        opacity: 1;
        transform: scale(1.05);
    }

    .map-card.selected {
        opacity: 1;
        border: 2px solid #3b82f6;
        box-shadow: 0 0 20px rgba(59, 130, 246, 0.2);
    }

    .map-title {
        font-size: 20px;
        font-weight: 600;
        color: white;
        margin-bottom: 8px;
        line-height: 1.4;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    .map-author {
        color: #d1d5db;
        margin-bottom: 4px;
    }

    .map-mapper {
        color: #9ca3af;
        margin-bottom: 12px;
    }

    .map-details {
        margin-top: auto;
    }

    .map-difficulty-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 8px;
    }

    .map-difficulty {
        font-weight: 500;
        text-transform: capitalize;
    }

    .difficulty-easy { color: #10b981; }
    .difficulty-normal { color: #3b82f6; }
    .difficulty-hard { color: #f59e0b; }
    .difficulty-expert { color: #ef4444; }
    .difficulty-expertplus { color: #8b5cf6; }

    .map-nps {
        color: #9ca3af;
    }

    .map-score {
        font-size: 14px;
        color: #6b7280;
    }

    /* Results Section */
    .results-section {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 24px;
    }

    .results-column h2 {
        font-size: 20px;
        font-weight: 600;
        margin-bottom: 16px;
    }

    .results-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 16px;
    }

    .copy-button {
        display: flex;
        align-items: center;
        gap: 8px;
        background-color: #059669;
        padding: 4px 12px;
        border-radius: 8px;
        border: none;
        color: white;
        cursor: pointer;
        transition: background-color 0.2s;
    }

    .copy-button:hover {
        background-color: #047857;
    }

    .copy-button svg {
        width: 16px;
        height: 16px;
    }

    .results-textarea {
        width: 100%;
        height: 192px;
        background-color: #1f2937;
        border: 1px solid #374151;
        border-radius: 8px;
        padding: 16px;
        color: white;
        font-family: inherit;
        resize: none;
        outline: none;
    }

    .results-textarea:focus {
        border-color: #3b82f6;
        box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
    }

    .results-textarea::placeholder {
        color: #6b7280;
    }

    .results-textarea[readonly] {
        background-color: #1f2937;
    }

    /* Selected Map Info */
    .selected-map-info {
        margin-top: 24px;
        padding: 16px;
        background-color: #1f2937;
        border-radius: 8px;
    }

    .selected-map-info h3 {
        font-size: 18px;
        font-weight: 600;
        margin-bottom: 8px;
    }

    .selected-map-name {
        color: #60a5fa;
    }

    .selected-map-score {
        color: #9ca3af;
    }

    @media (max-width: 1024px) {
        .results-section {
            grid-template-columns: 1fr;
        }
        
        .map-pool-info {
            flex-direction: column;
            text-align: center;
        }
    }

    @media (max-width: 768px) {
        body {
            padding: 16px;
        }
        
        .maps-grid {
            grid-template-columns: 1fr;
        }
    }
</style>