/**
 * api.js - API communication module
 * 
 * This module handles all communication with the server API endpoints.
 */

import AppState from './state.js';
import { showLogMessage } from './uiHelpers.js';
import * as DateUtils from './dateUtils.js'; // Import all of DateUtils

/**
 * Load report data from the server (now fetches real_work_hours)
 * @param {boolean} isAutoRefresh - Whether this is an auto-refresh call
 * @returns {Promise<Array>} - Promise resolving to report data
 */
export async function loadReportData(isAutoRefresh = false) {
    const currentPeriod = AppState.getCurrentPeriod();
    const user = AppState.getUserFilterText();
    let apiUrl = '/api/reports/real_work_hours'; // New endpoint
    const params = new URLSearchParams();
    
    if (user) {
        params.append('username', user);
    }
    
    // Add date parameters based on the current period
    let startDate, endDate;

    if (currentPeriod === 'daily') {
        startDate = AppState.getSelectedDate();
        endDate = startDate; // For daily, start and end date are the same
        params.append('start_date', startDate);
        params.append('end_date', endDate);
    } else if (currentPeriod === 'weekly') {
        if (AppState.getSelectedWeekDay()) {
            startDate = AppState.getSelectedWeekDay();
            endDate = startDate; // If a specific day in week is chosen, treat as daily
        } else {
            // Get current week's start (Monday) and end (Sunday)
            // Assuming AppState.getSelectedDate() gives a date within the desired week if not today
            const refDate = AppState.getSelectedDate() ? new Date(AppState.getSelectedDate()) : new Date();
            startDate = DateUtils.getFirstDayOfWeek(refDate);
            endDate = DateUtils.getLastDayOfWeek(refDate);
        }
        params.append('start_date', startDate);
        params.append('end_date', endDate);
    } else if (currentPeriod === 'monthly') {
        // Get current month's start and end dates
        // Assuming AppState.getSelectedDate() is not used for month context, so always current month
        startDate = DateUtils.getFirstDayOfCurrentMonth();
        endDate = DateUtils.getLastDayOfCurrentMonth();
        params.append('start_date', startDate);
        params.append('end_date', endDate);
    }
    // If no specific period logic matched or for a general overview (if API supports it without dates)
    // we might not append dates, or the API endpoint could have defaults.
    // For this implementation, daily, weekly, monthly will always have date params.
    
    if (params.toString()) {
        apiUrl += `?${params.toString()}`;
    }

    try {
        const response = await fetch(apiUrl);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const result = await response.json();

        if (result.success && result.data) {
            // Store the data in app state
            AppState.setReportData(result.data);
            
            if (isAutoRefresh) {
                showLogMessage('Report data refreshed automatically');
            }
            
            return result.data;
        } else {
            throw new Error(result.message || 'Failed to load data.');
        }
    } catch (error) {
        console.error('Error fetching report data:', error);
        throw error;
    }
}

/**
 * Fetch current user states from the server
 * @param {boolean} forceRefresh - Whether to force a refresh even if the cache is valid
 * @returns {Promise<Object>} - Promise resolving to user states object
 */
export async function fetchUserStates(forceRefresh = false) {
    // Only update user states if cache expired or force refresh
    const now = Date.now();
    if (!forceRefresh && 
        now - AppState.getUserStatesLastUpdate() < AppState.getStateCacheDuration() && 
        Object.keys(AppState.getUserStates()).length > 0) {
        return AppState.getUserStates();
    }
    
    try {
        const response = await fetch('/api/user-states');
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const result = await response.json();
        if (result.success && result.data) {
            const prevStates = {...AppState.getUserStates()};
            AppState.setUserStates(result.data);
            
            // If forcing a refresh, log the change statistics
            if (forceRefresh) {
                const totalUsers = Object.keys(result.data).length;
                const workingUsers = Object.values(result.data).filter(state => state === 'working').length;
                const changedStates = countChangedStates(prevStates, result.data);
                
                // Only show message if it's a manual refresh or if there were changes
                // Also check if AppState.isAutoRefreshEnabled is a function before calling
                const autoRefreshEnabled = (AppState && typeof AppState.isAutoRefreshEnabled === 'function') ? AppState.isAutoRefreshEnabled() : true;
                if (!autoRefreshEnabled || changedStates > 0) {
                    showLogMessage(`States refreshed: ${totalUsers} users (${workingUsers} working). ${changedStates} state changes detected.`);
                }
            }
            
            return result.data;
        } else {
            // If result.success is false, throw an error with the message from the API
            throw new Error(result.message || 'Failed to fetch user states: API indicated failure.');
        }
    } catch (error) {
        console.error('Error fetching user states:', error);
        // Optionally, clear cached states on error or handle more gracefully
        // For now, re-throw to let the caller handle it or display a general error.
        throw error;
    }
}

/**
 * Load user activity data for a specific user
 * @param {string} username - Username to fetch activity for
 * @param {string} startDate - Start date in YYYY-MM-DD format
 * @param {string} endDate - End date in YYYY-MM-DD format
 * @returns {Promise<Array>} - Promise resolving to user activity data
 */
export async function loadUserActivityData(username, startDate, endDate) {
    try {
        const response = await fetch(`/api/user-activity/${encodeURIComponent(username)}?start_date=${startDate}&end_date=${endDate}`);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const result = await response.json();
        if (result.success && result.data) {
            return result.data.activities;
        } else {
            throw new Error(result.message || 'Failed to load activity data');
        }
    } catch (error) {
        console.error('Error fetching user activity data:', error);
        throw error;
    }
}

/**
 * Helper function to count changed states between refreshes
 * @param {Object} prevStates - Previous state object
 * @param {Object} newStates - New state object
 * @returns {number} - Number of state changes
 */
function countChangedStates(prevStates, newStates) {
    let count = 0;
    
    // Check for changes in existing users
    Object.keys(newStates).forEach(user => {
        if (prevStates[user] && prevStates[user] !== newStates[user]) {
            count++;
            console.log(`State change detected: ${user} changed from ${prevStates[user]} to ${newStates[user]}`);
        }
    });
    
    // Check for new users
    const newUsers = Object.keys(newStates).filter(user => !prevStates[user]);
    if (newUsers.length > 0) {
        count += newUsers.length;
        console.log(`New users detected: ${newUsers.join(', ')}`);
    }
    
    return count;
} 