/**
 * Fixtures Update Manager - Integrates smart polling with homepage fixtures
 * Handles real-time updates with minimal UI disruption
 */
class FixturesUpdateManager {
    constructor(options = {}) {
        this.options = {
            fixturesContentSelector: '#fixtures-content',
            fixturesDateSelector: '#fixtures-date',
            debug: options.debug || false,
            enablePolling: options.enablePolling !== false, // Default to enabled
            ...options
        };

        this.pollingService = null;
        this.currentMatches = new Map(); // Track current match states
        this.isUpdating = false;
        this.lastFullUpdate = null;
        
        this.log('Fixtures Update Manager initialized');
    }

    /**
     * Initialize the update manager with smart polling
     */
    initialize() {
        if (!this.options.enablePolling) {
            this.log('Polling disabled by configuration');
            return;
        }

        const fixturesModule = document.getElementById('fixtures-module');
        if (!fixturesModule) {
            this.log('Fixtures module not found - not on homepage');
            return;
        }

        const currentDate = this.getCurrentDate();
        if (!currentDate) {
            this.log('Could not determine current date');
            return;
        }

        // Initialize smart polling service
        this.pollingService = new SmartPollingService({
            date: currentDate,
            debug: this.options.debug,
            onUpdate: this.handleUpdates.bind(this),
            onStateChange: this.handleStateChange.bind(this)
        });

        // Wait for lazy loading to initialize before starting updates
        this.waitForLazyLoading().then(() => {
            // Store initial match states
            this.captureCurrentMatches();

            // Start polling with a small delay to ensure fixtures are fully rendered
            setTimeout(() => {
                if (this.pollingService) {
                    this.pollingService.start();
                }
            }, 500);
        });

        // Listen for date changes
        this.observeDateChanges();

        this.log(`Started smart polling for date: ${currentDate}`);
    }

    /**
     * Wait for lazy loading system to initialize
     */
    async waitForLazyLoading() {
        if (!window.lazyFixtures) {
            // Wait up to 2 seconds for lazy loading to initialize
            let attempts = 0;
            while (!window.lazyFixtures && attempts < 20) {
                await new Promise(resolve => setTimeout(resolve, 100));
                attempts++;
            }
        }

        if (window.lazyFixtures && !window.lazyFixtures.initialized) {
            // Wait for lazy loading initialization to complete
            let attempts = 0;
            while (!window.lazyFixtures.initialized && attempts < 30) {
                await new Promise(resolve => setTimeout(resolve, 100));
                attempts++;
            }
        }

        this.log('Lazy loading system ready for polling integration');
    }

    /**
     * Handle incoming match updates
     */
    async handleUpdates(data) {
        if (this.isUpdating) {
            return;
        }

        this.isUpdating = true;

        try {
            // Find all live matches and recently finished matches for updates
            const liveMatches = data.matches.filter(match => match.is_live);
            const recentlyFinishedMatches = data.matches.filter(match => 
                ['FT', 'AET', 'PEN'].includes(match.status_short) && this.wasRecentlyLive(match)
            );
            
            if (liveMatches.length > 0) {
                await this.updateLiveMatches(liveMatches);
            }
            
            if (recentlyFinishedMatches.length > 0) {
                await this.updateFinishedMatches(recentlyFinishedMatches);
            }
            
            const totalUpdates = liveMatches.length + recentlyFinishedMatches.length;
            if (totalUpdates > 0) {
                this.showUpdateNotification(totalUpdates);
            }

            // Update our tracking with new data
            this.updateMatchTracking(data.matches);

        } catch (error) {
            // Silent error handling for production
        } finally {
            this.isUpdating = false;
        }
    }

    /**
     * Update all live matches with current time and scores
     */
    async updateLiveMatches(liveMatches) {
        for (const match of liveMatches) {
            try {
                const matchElement = this.findMatchElement(match.match_id);
                if (matchElement) {
                    // Update time
                    this.updateMatchTime(matchElement, match);
                    // Update scores
                    this.updateMatchScores(matchElement, match);
                    // Update events if available
                    this.updateMatchEvents(matchElement, match);
                    // Add visual feedback
                    this.animateUpdate(matchElement);
                } else {
                    this.log(`Could not find DOM element for live match ${match.match_id}`);
                }
            } catch (error) {
                this.log(`Error updating match ${match.match_id}: ${error.message}`);
            }
        }
    }

    /**
     * Update recently finished matches to show final status
     */
    async updateFinishedMatches(finishedMatches) {
        for (const match of finishedMatches) {
            try {
                const matchElement = this.findMatchElement(match.match_id);
                if (matchElement) {
                    // Update status to show FT/AET/PEN
                    this.updateMatchStatus(matchElement, match);
                    // Update final scores if they changed
                    this.updateMatchScores(matchElement, match);
                    // Update events if available
                    this.updateMatchEvents(matchElement, match);
                    // Add visual feedback for status change
                    this.animateStatusChange(matchElement, 'LIVE', match.status_short);
                } else {
                    this.log(`Could not find DOM element for finished match ${match.match_id}`);
                }
            } catch (error) {
                this.log(`Error updating finished match ${match.match_id}: ${error.message}`);
            }
        }
    }

    /**
     * Check if a match was recently live (to detect live->finished transitions)
     */
    wasRecentlyLive(match) {
        const trackedMatch = this.currentMatches.get(match.match_id);
        if (!trackedMatch) {
            // If we don't have tracking data, assume it might have been live recently
            return true;
        }
        
        // Check if the tracked match was live but now is finished
        const wasLive = trackedMatch.is_live || 
                       ['1H', '2H', 'HT', 'ET', 'BT', 'P', 'LIVE'].includes(trackedMatch.status_short);
        const isNowFinished = ['FT', 'AET', 'PEN'].includes(match.status_short);
        
        return wasLive && isNowFinished;
    }

    /**
     * Update match tracking with new data
     */
    updateMatchTracking(matches) {
        this.currentMatches.clear();
        matches.forEach(match => {
            this.currentMatches.set(match.match_id, { ...match });
        });
    }    /**
     * Check if match scores have changed
     */
    hasScoreChanged(oldMatch, newMatch) {
        return (oldMatch.home_score !== newMatch.home_score) ||
               (oldMatch.away_score !== newMatch.away_score) ||
               (oldMatch.penalty_home !== newMatch.penalty_home) ||
               (oldMatch.penalty_away !== newMatch.penalty_away);
    }

    /**
     * Check if elapsed time has changed
     */
    hasTimeChanged(oldTime, newTime) {
        // Normalize null/undefined values
        const normalizeTime = (time) => {
            if (!time || time === null || time === undefined) return null;
            return time.toString().trim();
        };

        const oldNormalized = normalizeTime(oldTime);
        const newNormalized = normalizeTime(newTime);

        return oldNormalized !== newNormalized;
    }

    /**
     * Apply updates to the DOM efficiently
     */
    async applyUpdates(updates) {
        for (const update of updates) {
            try {
                await this.applyUpdate(update);
            } catch (error) {
                this.log(`Error applying individual update: ${error.message}`);
            }
        }
    }

    /**
     * Apply a single update to the DOM
     */
    async applyUpdate(update) {
        const matchElement = this.findMatchElement(update.match.match_id);
        if (!matchElement) {
            // If we can't find the match element, do a full refresh
            this.log(`Match element not found for ${update.match.match_id}, triggering full refresh`);
            return this.refreshFixtures();
        }

        switch (update.type) {
            case 'score':
                this.updateMatchScores(matchElement, update.match);
                this.animateScoreChange(matchElement);
                break;

            case 'status':
                this.updateMatchStatus(matchElement, update.match);
                this.animateStatusChange(matchElement, update.oldStatus, update.newStatus);
                break;

            case 'time':
                this.updateMatchTime(matchElement, update.match);
                break;

            case 'kickoff_time':
                this.updateKickoffTime(matchElement, update.match);
                this.animateTimeChange(matchElement);
                break;

            case 'new':
                // For new matches, refresh the entire fixtures
                return this.refreshFixtures();
        }
    }

    /**
     * Update match scores in the DOM
     */
    updateMatchScores(matchElement, match) {
        const homeScoreElement = matchElement.querySelector('.home-team .team-score');
        const awayScoreElement = matchElement.querySelector('.away-team .team-score');

        if (homeScoreElement && match.home_score !== undefined) {
            homeScoreElement.textContent = match.home_score;
        }

        if (awayScoreElement && match.away_score !== undefined) {
            awayScoreElement.textContent = match.away_score;
        }

        // Update penalty scores if present
        if (match.penalty_home !== undefined && match.penalty_away !== undefined) {
            this.updatePenaltyScores(matchElement, match);
        }
    }

    /**
     * Update match events in the DOM
     */
    updateMatchEvents(matchElement, match) {
        if (!match.events || !Array.isArray(match.events)) {
            return;
        }

        // Group events by team
        const homeEvents = match.events.filter(event => 
            parseInt(event.team_id) === parseInt(matchElement.dataset.homeTeamId)
        );
        const awayEvents = match.events.filter(event => 
            parseInt(event.team_id) === parseInt(matchElement.dataset.awayTeamId)
        );

        // Update home team events
        this.updateTeamEvents(matchElement, 'home', homeEvents, matchElement.dataset.homeTeamId);
        
        // Update away team events
        this.updateTeamEvents(matchElement, 'away', awayEvents, matchElement.dataset.awayTeamId);
        
        // Restart event rotators for updated teams
        this.restartEventRotators(matchElement);
    }

    /**
     * Update events for a specific team
     */
    updateTeamEvents(matchElement, teamSide, events, teamId) {
        const teamElement = matchElement.querySelector(`.team.${teamSide}-team`);
        if (!teamElement) return;

        // Find or create events container
        let eventsContainer = teamElement.querySelector('.team-events');
        
        if (events.length === 0) {
            // Remove events container if no events
            if (eventsContainer) {
                eventsContainer.remove();
            }
            return;
        }

        if (!eventsContainer) {
            // Create events container if it doesn't exist
            eventsContainer = document.createElement('div');
            eventsContainer.className = 'team-events';
            eventsContainer.dataset.teamId = teamId;
            teamElement.appendChild(eventsContainer);
        } else {
            // Clear existing events
            eventsContainer.innerHTML = '';
        }

        // Add new events
        events.forEach((event, index) => {
            const eventElement = document.createElement('div');
            eventElement.className = `event-item${index === 0 ? ' active' : ''}`;
            eventElement.dataset.eventType = event.type;
            
            eventElement.innerHTML = `
                <span class="event-icon">${event.icon}</span>
                <span class="event-text">${event.text}</span>
            `;
            
            eventsContainer.appendChild(eventElement);
        });
    }

    /**
     * Restart event rotators for a specific match
     */
    restartEventRotators(matchElement) {
        // Stop existing rotators for this match's teams
        const homeTeamId = matchElement.dataset.homeTeamId;
        const awayTeamId = matchElement.dataset.awayTeamId;
        
        if (window.matchEventsRotator) {
            if (homeTeamId) {
                window.matchEventsRotator.stopRotation(homeTeamId);
            }
            if (awayTeamId) {
                window.matchEventsRotator.stopRotation(awayTeamId);
            }
            
            // Start new rotators
            setTimeout(() => {
                const teamEventsContainers = matchElement.querySelectorAll('.team-events');
                teamEventsContainers.forEach(container => {
                    const teamId = container.dataset.teamId;
                    const events = container.querySelectorAll('.event-item');
                    
                    if (events.length > 1 && window.matchEventsRotator) {
                        window.matchEventsRotator.startRotation(teamId, container, events);
                    }
                });
            }, 100);
        }
    }

    /**
     * Update match status in the DOM
     */
    updateMatchStatus(matchElement, match) {
        const statusElement = matchElement.querySelector('.match-status');
        if (!statusElement) return;

        const status = match.status_short;
        const wasLive = matchElement.classList.contains('live');

        if (['1H', '2H', 'HT', 'ET', 'BT', 'P', 'LIVE'].includes(status)) {
            // For halftime, always show 'HT' status
            if (status === 'HT') {
                statusElement.textContent = 'HT';
            }
            // Live match - show elapsed time (already formatted from API with extra time)
            else if (match.status_elapsed) {
                // The API already formats this as "45+2" or "90+4" for extra time
                const timeDisplay = match.status_elapsed.toString().includes("'") 
                    ? match.status_elapsed 
                    : `${match.status_elapsed}'`;
                statusElement.textContent = timeDisplay;
            } else {
                statusElement.textContent = status;
            }
        } else if (['FT', 'AET', 'PEN'].includes(status)) {
            // Finished match
            statusElement.textContent = status;
        } else if (status === 'NS') {
            // Not started - show time
            const datetime = new Date(match.datetime);
            statusElement.textContent = datetime.toLocaleTimeString('en-US', {
                hour: '2-digit',
                minute: '2-digit',
                hour12: false
            });
        }

        // Update match item class for styling
        matchElement.className = matchElement.className.replace(/\b(live|finished|upcoming)\b/g, '');
        
        const isNowLive = ['1H', '2H', 'HT', 'ET', 'BT', 'P', 'LIVE'].includes(status);
        
        if (isNowLive) {
            matchElement.classList.add('live');
        } else if (['FT', 'AET', 'PEN'].includes(status)) {
            matchElement.classList.add('finished');
        } else {
            matchElement.classList.add('upcoming');
        }

        // Dispatch event if live status changed (for filter re-evaluation)
        if (wasLive !== isNowLive) {
            document.dispatchEvent(new CustomEvent('matchLiveStatusChanged', {
                detail: {
                    matchId: match.match_id,
                    matchElement: matchElement,
                    wasLive: wasLive,
                    isNowLive: isNowLive
                }
            }));
        }
    }

    /**
     * Update match elapsed time
     */
    updateMatchTime(matchElement, match) {
        const statusElement = matchElement.querySelector('.match-status');
        if (!statusElement) return;

        // For halftime, always show 'HT' status regardless of elapsed time
        if (match.status_short === 'HT') {
            statusElement.textContent = 'HT';
        }
        else if (match.status_elapsed) {
            // The elapsed time is already formatted from the API with extra time (45+2, 90+4, etc.)
            // Just add apostrophe if not present
            const timeDisplay = match.status_elapsed.toString().includes("'") 
                ? match.status_elapsed 
                : `${match.status_elapsed}'`;
            statusElement.textContent = timeDisplay;
        } else if (match.is_live) {
            // Fallback for live matches without specific elapsed time
            statusElement.textContent = match.status_short || 'LIVE';
        }

        // Add visual feedback for time updates
        matchElement.classList.add('time-updated');
        setTimeout(() => {
            matchElement.classList.remove('time-updated');
        }, 2000);
    }

    /**
     * Update kickoff time for upcoming matches
     */
    updateKickoffTime(matchElement, match) {
        const statusElement = matchElement.querySelector('.match-status');
        if (!statusElement) return;

        if (match.status_short === 'NS') {
            // Format and display the new kickoff time
            const datetime = new Date(match.datetime);
            const timeString = datetime.toLocaleTimeString('en-US', {
                hour: '2-digit',
                minute: '2-digit',
                hour12: false
            });
            statusElement.textContent = timeString;
        }
    }

    /**
     * Add visual feedback for time changes
     */
    animateTimeChange(matchElement) {
        matchElement.classList.add('time-updated');
        setTimeout(() => {
            matchElement.classList.remove('time-updated');
        }, 3000);
    }

    /**
     * Add visual feedback for score changes
     */
    animateScoreChange(matchElement) {
        matchElement.classList.add('score-updated');
        setTimeout(() => {
            matchElement.classList.remove('score-updated');
        }, 3000);
    }

    /**
     * Add visual feedback for status changes
     */
    animateStatusChange(matchElement, oldStatus, newStatus) {
        // Add appropriate animation class based on status change
        if (oldStatus === 'NS' && ['1H', 'LIVE'].includes(newStatus)) {
            matchElement.classList.add('match-started');
        } else if (['1H', '2H', 'HT', 'ET', 'BT', 'P', 'LIVE'].includes(oldStatus) && 
                   ['FT', 'AET', 'PEN'].includes(newStatus)) {
            matchElement.classList.add('match-finished');
        } else {
            matchElement.classList.add('status-updated');
        }

        // Remove animation class after animation completes
        setTimeout(() => {
            matchElement.classList.remove('match-started', 'match-finished', 'status-updated');
        }, 3000);
    }

    /**
     * General visual feedback for any match update
     */
    animateUpdate(matchElement) {
        matchElement.classList.add('match-updated');
        setTimeout(() => {
            matchElement.classList.remove('match-updated');
        }, 2000);
    }

    /**
     * Find a match element in the DOM by match ID
     */
    findMatchElement(matchId) {
        return document.querySelector(`[data-match-id="${matchId}"]`);
    }

    /**
     * Show a subtle notification about updates
     */
    showUpdateNotification(updateCount) {
        // Disabled - notification box removed to prevent covering content
        return;
    }

    /**
     * Refresh entire fixtures display
     */
    async refreshFixtures() {
        const currentDate = this.getCurrentDate();
        if (!currentDate) return;

        try {
            const response = await fetch(`/public/ajax/fixtures.php?date=${currentDate}&timezone=user`, {
                headers: {
                    'X-AJAX-TOKEN': window.ajaxToken || ''
                }
            });
            const data = await response.json();

            if (data.success) {
                const fixturesContent = document.querySelector(this.options.fixturesContentSelector);
                if (fixturesContent) {
                    fixturesContent.innerHTML = data.html;
                    
                    // Re-initialize filters and other functionality
                    if (typeof initializeFixturesFilters === 'function') {
                        initializeFixturesFilters();
                    }
                    
                    // Re-initialize match event rotators
                    if (typeof initializeMatchEventRotators === 'function') {
                        setTimeout(() => {
                            initializeMatchEventRotators();
                        }, 100);
                    }
                    
                    // Re-capture match states
                    this.captureCurrentMatches();
                    
                    this.log('Full fixtures refresh completed');
                }
            }
        } catch (error) {
            this.log(`Error refreshing fixtures: ${error.message}`);
        }
    }

    /**
     * Get current date from the fixtures interface
     */
    getCurrentDate() {
        const fixturesDate = document.querySelector(this.options.fixturesDateSelector);
        return fixturesDate ? fixturesDate.dataset.date : null;
    }

    /**
     * Capture current match states for change detection
     */
    captureCurrentMatches() {
        this.currentMatches.clear();
        
        const matchElements = document.querySelectorAll('.match-item[data-match-id]');
        
        matchElements.forEach(element => {
            const matchId = element.dataset.matchId;
            if (!matchId) return;

            // Extract current match data from DOM
            const homeScoreElement = element.querySelector('.home-team .team-score');
            const awayScoreElement = element.querySelector('.away-team .team-score');
            const statusElement = element.querySelector('.match-status');

            // Extract elapsed time for live matches
            let statusElapsed = null;
            if (statusElement) {
                const statusText = statusElement.textContent.trim();
                // Check if this is an elapsed time format (e.g., "90'", "45+2'")
                const timeMatch = statusText.match(/^(\d+)(?:\+(\d+))?'$/);
                if (timeMatch) {
                    statusElapsed = timeMatch[1]; // Main time
                    if (timeMatch[2]) {
                        statusElapsed += '+' + timeMatch[2]; // Added time
                    }
                }
            }

            const matchData = {
                match_id: matchId,
                home_score: homeScoreElement ? homeScoreElement.textContent : null,
                away_score: awayScoreElement ? awayScoreElement.textContent : null,
                status_short: statusElement ? statusElement.textContent : null,
                status_elapsed: statusElapsed,
                datetime: element.dataset.datetime || null // Capture datetime for comparison
            };

            this.currentMatches.set(matchId, matchData);
        });

        this.log(`Captured ${this.currentMatches.size} match states`);
    }

    /**
     * Update internal match tracking with new data
     */
    updateMatchTracking(newMatches) {
        for (const match of newMatches) {
            this.currentMatches.set(match.match_id, match);
        }
    }

    /**
     * Handle polling state changes
     */
    handleStateChange(state) {
        this.log(`Polling state changed: ${state.state} (${state.interval / 1000}s interval)`);
    }

    /**
     * Observe changes to the fixtures date
     */
    observeDateChanges() {
        const fixturesDate = document.querySelector(this.options.fixturesDateSelector);
        if (!fixturesDate) return;

        // Use MutationObserver to watch for date changes
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.type === 'attributes' && mutation.attributeName === 'data-date') {
                    const newDate = fixturesDate.dataset.date;
                    if (newDate && this.pollingService) {
                        this.log(`Date changed to: ${newDate}`);
                        this.pollingService.updateDate(newDate);
                        this.captureCurrentMatches(); // Reset tracking for new date
                    }
                }
            });
        });

        observer.observe(fixturesDate, {
            attributes: true,
            attributeFilter: ['data-date']
        });
    }

    /**
     * Stop polling and clean up
     */
    stop() {
        if (this.pollingService) {
            this.pollingService.stop();
            this.pollingService = null;
        }
        
        this.log('Fixtures Update Manager stopped');
    }

    /**
     * Log debug messages
     */
    log(message) {
        if (this.options.debug) {
            console.log('[FixturesUpdateManager]', message);
        }
    }
}

// Initialize on DOM content loaded
document.addEventListener('DOMContentLoaded', function() {
    
    // Function to try initialization
    function tryInitialize() {
        console.log('[FixturesUpdateManager] Checking initialization requirements:', {
            SmartPollingService: typeof SmartPollingService !== 'undefined',
            smartPollingConfig: !!window.smartPollingConfig,
            fixturesModule: !!document.getElementById('fixtures-module')
        });
        
        if (typeof SmartPollingService !== 'undefined' && window.smartPollingConfig) {
            const config = window.smartPollingConfig.getConfig();
            console.log('[FixturesUpdateManager] Config loaded:', config);
            
            window.fixturesUpdateManager = new FixturesUpdateManager({
                enablePolling: config.enabled,
                debug: config.debug
            });
            
            console.log('[FixturesUpdateManager] Attempting to initialize...');
            window.fixturesUpdateManager.initialize();
            return true;
        } else {
            console.log('[FixturesUpdateManager] Requirements not met, retrying later');
            return false;
        }
    }
    
    // Try immediately first
    if (!tryInitialize()) {
        // Wait a bit for scripts to load
        setTimeout(() => {
            if (!tryInitialize()) {
                // Try one more time with longer delay
                setTimeout(() => {
                    tryInitialize();
                }, 500);
            }
        }, 100);
    }
});