/**
 * dashboard.js - Main dashboard controller
 * 
 * This module serves as the main entry point and orchestrator for the dashboard,
 * importing and initializing all the specialized modules.
 */

// Import all the modules
import AppState from './state.js';
import * as DateUtils from './dateUtils.js';
import * as Filters from './filters.js';
import * as TableManager from './tableManager.js';
import * as UserStates from './userStates.js';
import * as AutoRefresh from './autoRefresh.js';
import * as UserActivity from './userActivity.js';
import * as Api from './api.js';

// Main initialization function
document.addEventListener('DOMContentLoaded', function() {
    // DOM element references
    const filterButtons = document.querySelectorAll('.btn-filter');
    const userFilterInput = document.getElementById('userFilter');
    const clearUserFilterBtn = document.getElementById('clearUserFilter');
    const loadingSpinner = document.getElementById('loadingSpinner');
    const errorMessage = document.getElementById('errorMessage');
    const weekDaySelector = document.getElementById('weekDaySelector');
    const weekDaySelect = document.getElementById('weekDaySelect');
    const refreshStatesBtn = document.getElementById('refreshStates');
    const dateNavControls = document.getElementById('dateNavControls');
    const prevDateBtn = document.getElementById('prevDateBtn');
    const nextDateBtn = document.getElementById('nextDateBtn');
    const calendarBtn = document.getElementById('calendarBtn');
    const dateSelector = document.getElementById('dateSelector');
    
    // Set initial value for date selector if AppState and getSelectedDate are defined
    if (AppState && typeof AppState.getSelectedDate === 'function') {
        const selectedDate = AppState.getSelectedDate();
        if (selectedDate) {
            dateSelector.value = selectedDate;
        }
    }
    
    // Initialize all components
    initializeNavigation();
    initializeFilters();
    initializeWeekDaySelector();
    
    // Initialize sorting, state filters, and auto-refresh
    Filters.initializeSortingHeaders();
    Filters.initializeStateFilters();
    AutoRefresh.initializeAutoRefresh();
    
    // Set initial sort indicator based on AppState default sort settings
    setInitialSortIndicator();
    
    // Initialize user activity modal
    UserActivity.initializeUserActivityModal();
    
    // First load user states, then load report data
    UserStates.refreshUserStates(true).then(() => {
        // Load initial report data
        loadReportData();
    }).catch(error => {
        console.error('Error loading initial user states:', error);
        // Still load report data even if states fail.
        loadReportData();
    });
    
    /**
     * Set the initial sort indicator on the table header based on AppState default values
     */
    function setInitialSortIndicator() {
        const sortColumn = AppState.getCurrentSortColumn();
        const sortDirection = AppState.getCurrentSortDirection();
        if (sortColumn && sortDirection) {
            const header = document.querySelector(`.sortable[data-sort="${sortColumn}"]`);
            if (header) {
                header.setAttribute('data-dir', sortDirection);
            }
        }
    }
    
    /**
     * Updates the visibility of UI controls based on the selected reporting period.
     * @param {string} period - The current reporting period ('daily', 'weekly', 'monthly').
     */
    function updatePeriodControlsVisibility(period) {
        if (period === 'weekly') {
            weekDaySelector.classList.remove('d-none');
            populateWeekDaySelector(); // Populate selector when shown
            dateNavControls.classList.add('d-none');
        } else if (period === 'daily') {
            weekDaySelector.classList.add('d-none');
            dateNavControls.classList.remove('d-none');
            updateDateDisplay(); // Update date display for daily view
        } else { // monthly or any other period
            weekDaySelector.classList.add('d-none');
            dateNavControls.classList.add('d-none');
        }
    }
    
    /**
     * Initialize date navigation controls.
     * Sets up event listeners and initial visibility.
     */
    function initializeNavigation() {
        // Update the date display
        updateDateDisplay();
        
        // Show date navigation controls if daily view is active
        if (AppState.getCurrentPeriod() === 'daily') {
            dateNavControls.classList.remove('d-none');
        }
        
        // Add event listeners for date navigation
        prevDateBtn.addEventListener('click', goToPreviousDay);
        nextDateBtn.addEventListener('click', goToNextDay);
        calendarBtn.addEventListener('click', toggleCalendar);
        dateSelector.addEventListener('change', handleDateSelection);
    }
    
    /**
     * Initialize filter buttons (Daily, Weekly, Monthly) and the user text filter.
     * Sets up event listeners for period changes and user input.
     */
    function initializeFilters() {
        // Add event listeners to filter buttons
        filterButtons.forEach(button => {
            button.addEventListener('click', function() {
                filterButtons.forEach(btn => btn.classList.remove('active'));
                this.classList.add('active');
                
                const period = this.getAttribute('data-period');
                AppState.setCurrentPeriod(period);
                
                // Update visibility of period-specific controls
                updatePeriodControlsVisibility(period);
                
                loadReportData(); // Reload data when period changes
            });
        });
        
        // User filter input (with debounce)
        let userFilterTimeout = null;
        userFilterInput.addEventListener('input', function() {
            // Clear any existing timeout
            if (userFilterTimeout) {
                clearTimeout(userFilterTimeout);
            }
            
            // Set a new timeout to delay the filter application (300ms debounce)
            userFilterTimeout = setTimeout(function() {
                AppState.setUserFilterText(userFilterInput.value.trim());
                loadReportData();
            }, 300);
        });
        
        // Clear user filter button
        clearUserFilterBtn.addEventListener('click', function() {
            userFilterInput.value = '';
            AppState.setUserFilterText('');
            loadReportData();
        });
        
        // Refresh states button
        refreshStatesBtn.addEventListener('click', function() {
            UserStates.refreshUserStates(true); // Force refresh
        });
    }
    
    /**
     * Initialize the week day selector for the weekly view.
     * Sets up event listener for day selection changes.
     */
    function initializeWeekDaySelector() {
        // Add event listener for week day selector
        weekDaySelect.addEventListener('change', function() {
            AppState.setSelectedWeekDay(this.value);
            loadReportData(); // Reload data when day selection changes
        });
    }
    
    /**
     * Populate the week day selector dropdown with days of the current week.
     * Fetches days from DateUtils.
     */
    function populateWeekDaySelector() {
        weekDaySelect.innerHTML = '<option value="">All Week</option>';
        const days = DateUtils.getDaysOfWeek();
        
        days.forEach(day => {
            const option = document.createElement('option');
            option.value = day.date;
            option.textContent = `${day.dayName} (${day.displayDate})`;
            weekDaySelect.appendChild(option);
        });
    }
    
    /**
     * Update the current date display in the UI (e.g., "May 10, 2024").
     * Uses the selected date from AppState.
     */
    function updateDateDisplay() {
        const currentDateDisplay = document.getElementById('currentDateDisplay');
        currentDateDisplay.textContent = DateUtils.formatDateForDisplay(AppState.getSelectedDate());
    }
    
    /**
     * Navigate to the previous day and reload report data.
     * Updates AppState and the UI display.
     */
    function goToPreviousDay() {
        const newDate = DateUtils.getPreviousDay(AppState.getCurrentDate());
        AppState.setCurrentDate(newDate);
        updateDateDisplay();
        loadReportData();
    }
    
    /**
     * Navigate to the next day and reload report data.
     * Updates AppState and the UI display.
     */
    function goToNextDay() {
        const newDate = DateUtils.getNextDay(AppState.getCurrentDate());
        AppState.setCurrentDate(newDate);
        updateDateDisplay();
        loadReportData();
    }
    
    /**
     * Handle date selection from the calendar input.
     * Updates AppState, UI display, and reloads report data.
     */
    function handleDateSelection() {
        if (dateSelector.value) {
            AppState.setSelectedDate(dateSelector.value);
            updateDateDisplay();
            dateSelector.style.display = 'none';
            loadReportData();
        }
    }
    
    /**
     * Toggle the visibility of the calendar date input.
     */
    function toggleCalendar() {
        if (dateSelector.style.display === 'none') {
            dateSelector.style.display = 'inline-block';
            dateSelector.value = AppState.getSelectedDate();
            dateSelector.focus();
        } else {
            dateSelector.style.display = 'none';
        }
    }
    
    /**
     * Load report data from the API and update the table.
     * Manages loading spinner and error messages.
     * @param {boolean} [isAutoRefresh=false] - Indicates if the load is triggered by auto-refresh.
     *                                         If true, loading spinner is not shown.
     * @async
     */
    async function loadReportData(isAutoRefresh = false) {
        if (isAutoRefresh) {
            // For auto-refresh, don't show spinner to avoid UI flicker
            // Just update the last refresh time
            if (AppState && typeof AppState.setLastRefreshTime === 'function') {
                AppState.setLastRefreshTime(Date.now());
            }
        } else {
            loadingSpinner.classList.remove('d-none'); // Show spinner for manual refresh
        }
        
        errorMessage.classList.add('d-none'); // Hide error message

        try {
            // Use the API module to load the report data
            const data = await Api.loadReportData(isAutoRefresh);
            
            // Apply default sorting if needed
            const sortedData = AppState.getCurrentSortColumn() && AppState.getCurrentSortDirection() 
                ? Filters.sortReportTable(data) 
                : data;
            
            // Use the TableManager module to populate the table
            TableManager.populateTable(sortedData, isAutoRefresh);
            
            // If there's an active state filter, reapply it
            if (AppState && typeof AppState.getCurrentStateFilter === 'function' && AppState.getCurrentStateFilter() !== 'all') {
                Filters.filterTableByState(AppState.getCurrentStateFilter());
            }
            
        } catch (error) {
            console.error('Error fetching report data:', error);
            errorMessage.textContent = `Error: ${error.message || 'Network error or failed to fetch data.'}`;
            errorMessage.classList.remove('d-none');
            // Use TableManager to display the error in the table area
            TableManager.showReportTableMessage('Failed to load data. See console for details.', true);
        } finally {
            loadingSpinner.classList.add('d-none'); // Hide spinner
        }
    }
}); 