// Seasons Filter Utility
// Parses and manages season/week data from the seasons constant file

class SeasonsFilter {
    constructor() {
        this.seasons = [];
        this.loaded = false;
    }

    // Parse seasons text content into structured data
    parseSeasons(content) {
        const seasons = [];
        const lines = content.split('\n');
        let currentSeason = null;
        
        for (let i = 0; i < lines.length; i++) {
            const line = lines[i].trim();
            
            if (!line) continue;
            
            // Check if it's a season header (e.g., "2025-V")
            const seasonMatch = line.match(/^(\d{4}-[IVX]+)$/);
            if (seasonMatch) {
                if (currentSeason) {
                    seasons.push(currentSeason);
                }
                currentSeason = {
                    name: seasonMatch[1],
                    weeks: []
                };
                continue;
            }
            
            // Check if it's a week line
            // Format: "week 1 (01.09 – 07.09) <t:1756735246:R>: max BR 14.0"
            // or: "until eos (27.10 – 31.10) <t:1761487200:R>: max BR 5.0"
            const weekMatch = line.match(/(?:week\s+(\d+)|until eos)\s+\((\d{2})\.(\d{2})\s*[–—]\s*(\d{2})\.(\d{2})\)\s*<t:(\d+):R>/);
            if (weekMatch && currentSeason) {
                const weekNum = weekMatch[1] ? parseInt(weekMatch[1]) : null;
                const startDay = parseInt(weekMatch[2]);
                const startMonth = parseInt(weekMatch[3]);
                const endDay = parseInt(weekMatch[4]);
                const endMonth = parseInt(weekMatch[5]);
                const timestamp = parseInt(weekMatch[6]);
                
                // Extract max BR if present (preserve .0 formatting)
                const brMatch = line.match(/max BR ([\d.]+)/);
                const maxBR = brMatch ? brMatch[1] : null; // Keep as string to preserve ".0"
                
                // Use the Unix timestamp directly from the file (it's already correct!)
                // The timestamp is the START of the week
                const startDate = new Date(timestamp * 1000); // Convert to milliseconds
                
                // Calculate end date: 7 days from start (or until end of season for "until eos")
                // For "until eos" entries, we'll need to calculate based on the actual end day
                let endDate;
                
                // Determine year from season name (e.g., "2025-V" -> 2025)
                const yearMatch = currentSeason.name.match(/^(\d{4})/);
                const year = yearMatch ? parseInt(yearMatch[1]) : new Date().getFullYear();
                
                // Build end date from the parsed end day/month
                // Need to handle year rollover (e.g., December -> January)
                let endYear = year;
                if (endMonth < startMonth) {
                    endYear = year + 1; // Crossed into next year
                }
                endDate = new Date(endYear, endMonth - 1, endDay, 23, 59, 59, 999);
                
                // Build display name with max BR (preserve decimal formatting like 14.0)
                let displayName;
                if (weekNum) {
                    displayName = `Week ${weekNum} (${weekMatch[2]}.${weekMatch[3]} – ${weekMatch[4]}.${weekMatch[5]})`;
                    if (maxBR) displayName += ` - BR ${maxBR}`;
                } else {
                    displayName = `Until EOS (${weekMatch[2]}.${weekMatch[3]} – ${weekMatch[4]}.${weekMatch[5]})`;
                    if (maxBR) displayName += ` - BR ${maxBR}`;
                }
                
                currentSeason.weeks.push({
                    weekNumber: weekNum,
                    name: weekNum ? `Week ${weekNum}` : 'Until EOS',
                    startDate: startDate,
                    endDate: endDate,
                    startTimestamp: timestamp, // Store original Unix timestamp (seconds)
                    maxBR: maxBR,
                    displayName: displayName
                });
            }
        }
        
        // Add the last season
        if (currentSeason) {
            seasons.push(currentSeason);
        }

        // Post-process: set each week's endDate to the next week's startDate - 1ms
        // This uses the exact Unix timestamps instead of the approximate text-parsed dates
        seasons.forEach(season => {
            season.weeks.forEach((week, i) => {
                if (i + 1 < season.weeks.length) {
                    week.endDate = new Date(season.weeks[i + 1].startDate.getTime() - 1);
                }
                // Last week of each season keeps its text-parsed endDate
            });
        });

        return seasons;
    }

    // Load seasons data from the constant file
    async loadSeasons() {
        if (this.loaded) {
            return this.seasons;
        }

        try {
            const response = await fetch('/constants/seasons');
            if (!response.ok) {
                throw new Error(`Failed to load seasons: ${response.status}`);
            }
            
            const content = await response.text();
            this.seasons = this.parseSeasons(content);
            this.loaded = true;
            
            console.log('[Seasons Filter] Loaded seasons:', this.seasons);
            return this.seasons;
        } catch (error) {
            console.error('[Seasons Filter] Error loading seasons:', error);
            this.seasons = [];
            this.loaded = false;
            return [];
        }
    }

    // Get all seasons
    getSeasons() {
        return this.seasons;
    }

    // Get a specific season by name
    getSeason(seasonName) {
        return this.seasons.find(s => s.name === seasonName);
    }

    // Get current season (based on current date)
    getCurrentSeason() {
        const now = new Date();
        
        for (const season of this.seasons) {
            for (const week of season.weeks) {
                if (now >= week.startDate && now <= week.endDate) {
                    return season;
                }
            }
        }
        
        // If no current season found, return the most recent one
        return this.seasons.length > 0 ? this.seasons[this.seasons.length - 1] : null;
    }

    // Get current week (based on current date)
    getCurrentWeek() {
        const now = new Date();
        
        for (const season of this.seasons) {
            for (const week of season.weeks) {
                if (now >= week.startDate && now <= week.endDate) {
                    return { season, week };
                }
            }
        }
        
        return null;
    }

    // Get date range for a specific season
    getSeasonDateRange(seasonName) {
        const season = this.getSeason(seasonName);
        if (!season || season.weeks.length === 0) {
            return null;
        }
        
        return {
            startDate: season.weeks[0].startDate,
            endDate: season.weeks[season.weeks.length - 1].endDate,
            season: season
        };
    }

    // Get date range for a specific week in a season
    getWeekDateRange(seasonName, weekNumber) {
        const season = this.getSeason(seasonName);
        if (!season) {
            return null;
        }
        
        const week = season.weeks.find(w => w.weekNumber === weekNumber);
        if (!week) {
            return null;
        }
        
        return {
            startDate: week.startDate,
            endDate: week.endDate,
            week: week
        };
    }

    // Get all unique BR values across all seasons (returns array of strings, preserving ".0")
    getAllBRValues() {
        const brSet = new Set();
        
        this.seasons.forEach(season => {
            season.weeks.forEach(week => {
                if (week.maxBR) {
                    brSet.add(week.maxBR);
                }
            });
        });
        
        // Sort descending (convert to float for comparison, but keep as strings)
        return Array.from(brSet).sort((a, b) => parseFloat(b) - parseFloat(a));
    }

    // Get all weeks that match a specific BR
    getWeeksByBR(maxBR) {
        const matchingWeeks = [];
        
        this.seasons.forEach(season => {
            season.weeks.forEach(week => {
                if (week.maxBR === maxBR) {
                    matchingWeeks.push({
                        season: season,
                        week: week,
                        displayName: `${season.name} - ${week.name}`
                    });
                }
            });
        });
        
        return matchingWeeks;
    }

    // Get combined date range for all weeks with a specific BR (for filtering multiple weeks)
    getDateRangeForBR(maxBR) {
        const weeks = this.getWeeksByBR(maxBR);
        
        if (weeks.length === 0) {
            return null;
        }
        
        // Return array of date ranges (one for each week with this BR)
        return weeks.map(({ season, week }) => ({
            startDate: week.startDate,
            endDate: week.endDate,
            seasonName: season.name,
            weekName: week.name,
            displayName: `${season.name} - ${week.displayName}`
        }));
    }

    // Populate a select element with season options
    populateSeasonSelect(selectElement, includeAllOption = true) {
        selectElement.innerHTML = '';
        
        if (includeAllOption) {
            const allOption = document.createElement('option');
            allOption.value = 'all';
            allOption.textContent = window.__t ? window.__t('leaderboard.allSeasons') : 'All Seasons';
            selectElement.appendChild(allOption);
        }
        
        // Add seasons in reverse order (most recent first)
        for (let i = this.seasons.length - 1; i >= 0; i--) {
            const season = this.seasons[i];
            const option = document.createElement('option');
            option.value = season.name;
            option.textContent = season.name;
            selectElement.appendChild(option);
        }
    }

    // Populate a select element with BR options
    populateBRSelect(selectElement, includeAllOption = true) {
        selectElement.innerHTML = '';
        
        if (includeAllOption) {
            const allOption = document.createElement('option');
            allOption.value = '';
            allOption.textContent = window.__t ? window.__t('leaderboard.allBR') : 'All BR';
            selectElement.appendChild(allOption);
        }
        
        const brValues = this.getAllBRValues();
        brValues.forEach(br => {
            const option = document.createElement('option');
            option.value = br;
            option.textContent = `BR ${br}`;
            selectElement.appendChild(option);
        });
    }

    // Populate a select element with week options for a given season
    populateWeekSelect(selectElement, seasonName, includeAllOption = true) {
        selectElement.innerHTML = '';
        
        if (includeAllOption) {
            const allOption = document.createElement('option');
            allOption.value = 'all';
            allOption.textContent = window.__t ? window.__t('leaderboard.allWeeks') : 'All Weeks';
            selectElement.appendChild(allOption);
        }
        
        const season = this.getSeason(seasonName);
        if (!season) {
            return;
        }
        
        season.weeks.forEach(week => {
            const option = document.createElement('option');
            option.value = week.weekNumber !== null ? week.weekNumber.toString() : 'final';
            option.textContent = week.displayName;
            selectElement.appendChild(option);
        });
    }
}

// Global instance
window.seasonsFilter = window.seasonsFilter || new SeasonsFilter();

