/**
 * Service pour la gestion de l'exécution granulaire des chantiers
 * Gère les tâches, leur completion et le calcul d'avancement basé sur les tâches
 */

import { apiClient } from './api-client';

export interface TacheExecution {
    id: string;
    tacheTemplateId: string;
    chantierID: string;
    nom: string;
    description?: string;
    ordreExecution: number;
    dureeEstimeeMinutes?: number;
    critique: boolean;
    bloquante: boolean;
    priorite: 'BASSE' | 'NORMALE' | 'HAUTE';
    niveauQualification?: string;
    nombreOperateursRequis: number;
    conditionsMeteo: string;
    outilsRequis?: string[];
    materiauxRequis?: string[];
    
    // État d'exécution
    terminee: boolean;
    dateCompletion?: Date;
    completeepar?: string;
    commentaires?: string;
    tempsRealise?: number;
    difficulteRencontree?: 'AUCUNE' | 'FAIBLE' | 'MOYENNE' | 'ELEVEE';
}

export interface AvancementGranulaire {
    chantierID: string;
    pourcentage: number;
    totalTaches: number;
    tachesTerminees: number;
    phasesAvancement: {
        phaseId: string;
        nom: string;
        pourcentage: number;
        sousPhases: {
            sousPhaseId: string;
            nom: string;
            pourcentage: number;
            tachesTerminees: number;
            totalTaches: number;
        }[];
    }[];
    derniereMAJ: Date;
}

export interface StatistiquesExecution {
    totalTachesTerminees: number;
    totalTaches: number;
    pourcentageGlobal: number;
    moyenneTempsByTache: number;
    tachesEnRetard: number;
    tachesCritiquesRestantes: number;
    estimationFinChantier?: Date;
    efficaciteEquipe: number; // % temps réalisé vs estimé
}

class ExecutionGranulaireService {
    private readonly basePath = '/chantiers';

    /**
     * Récupère l'avancement granulaire d'un chantier
     */
    async getAvancementGranulaire(chantierID: string): Promise<AvancementGranulaire> {
        try {
            const response = await apiClient.get(`${this.basePath}/${chantierID}/avancement-granulaire`);
            return {
                ...response.data,
                derniereMAJ: new Date(response.data.derniereMAJ)
            };
        } catch (error) {
            console.error('Erreur lors de la récupération de l\'avancement granulaire:', error);
            throw error;
        }
    }

    /**
     * Récupère toutes les tâches d'exécution pour un chantier
     */
    async getTachesExecution(chantierID: string): Promise<TacheExecution[]> {
        try {
            const response = await apiClient.get(`${this.basePath}/${chantierID}/taches-execution`);
            return response.data.map((tache: any) => ({
                ...tache,
                dateCompletion: tache.dateCompletion ? new Date(tache.dateCompletion) : undefined
            }));
        } catch (error) {
            console.error('Erreur lors de la récupération des tâches:', error);
            throw error;
        }
    }

    /**
     * Récupère les tâches d'exécution pour une sous-phase spécifique
     */
    async getTachesExecutionBySousPhase(chantierID: string, sousPhaseId: string): Promise<TacheExecution[]> {
        try {
            const response = await apiClient.get(`${this.basePath}/${chantierID}/taches-execution/${sousPhaseId}`);
            return response.data.map((tache: any) => ({
                ...tache,
                dateCompletion: tache.dateCompletion ? new Date(tache.dateCompletion) : undefined
            }));
        } catch (error) {
            console.error('Erreur lors de la récupération des tâches de la sous-phase:', error);
            throw error;
        }
    }

    /**
     * Marque une tâche comme terminée
     */
    async marquerTacheTerminee(
        chantierID: string, 
        tacheTemplateId: string, 
        details: {
            commentaires?: string;
            tempsRealise?: number;
            difficulteRencontree?: 'AUCUNE' | 'FAIBLE' | 'MOYENNE' | 'ELEVEE';
            completeepar?: string;
        }
    ): Promise<void> {
        try {
            await apiClient.post(`${this.basePath}/${chantierID}/taches-execution`, {
                tacheTemplateId,
                terminee: true,
                dateCompletion: new Date().toISOString(),
                ...details
            });
        } catch (error) {
            console.error('Erreur lors du marquage de la tâche comme terminée:', error);
            throw error;
        }
    }

    /**
     * Marque une tâche comme non terminée
     */
    async marquerTacheNonTerminee(chantierID: string, tacheTemplateId: string): Promise<void> {
        try {
            await apiClient.post(`${this.basePath}/${chantierID}/taches-execution`, {
                tacheTemplateId,
                terminee: false,
                dateCompletion: null,
                commentaires: '',
                tempsRealise: null,
                difficulteRencontree: 'AUCUNE'
            });
        } catch (error) {
            console.error('Erreur lors du marquage de la tâche comme non terminée:', error);
            throw error;
        }
    }

    /**
     * Met à jour l'état d'exécution d'une tâche
     */
    async updateTacheExecution(
        chantierID: string,
        tacheTemplateId: string,
        updates: Partial<TacheExecution>
    ): Promise<void> {
        try {
            await apiClient.put(`${this.basePath}/${chantierID}/taches-execution/${tacheTemplateId}`, updates);
        } catch (error) {
            console.error('Erreur lors de la mise à jour de la tâche:', error);
            throw error;
        }
    }

    /**
     * Récupère les statistiques d'exécution d'un chantier
     */
    async getStatistiquesExecution(chantierID: string): Promise<StatistiquesExecution> {
        try {
            const response = await apiClient.get(`${this.basePath}/${chantierID}/statistiques-execution`);
            return {
                ...response.data,
                estimationFinChantier: response.data.estimationFinChantier 
                    ? new Date(response.data.estimationFinChantier) 
                    : undefined
            };
        } catch (error) {
            console.error('Erreur lors de la récupération des statistiques:', error);
            throw error;
        }
    }

    /**
     * Récupère les tâches critiques en retard
     */
    async getTachesCritiquesEnRetard(chantierID: string): Promise<TacheExecution[]> {
        try {
            const response = await apiClient.get(`${this.basePath}/${chantierID}/taches-critiques-retard`);
            return response.data.map((tache: any) => ({
                ...tache,
                dateCompletion: tache.dateCompletion ? new Date(tache.dateCompletion) : undefined
            }));
        } catch (error) {
            console.error('Erreur lors de la récupération des tâches critiques:', error);
            throw error;
        }
    }

    /**
     * Génère un rapport d'avancement granulaire
     */
    async genererRapportAvancement(chantierID: string, format: 'PDF' | 'EXCEL' = 'PDF'): Promise<Blob> {
        try {
            const response = await apiClient.get(
                `${this.basePath}/${chantierID}/rapport-avancement-granulaire`,
                {
                    params: { format },
                    responseType: 'blob'
                }
            );
            return response.data;
        } catch (error) {
            console.error('Erreur lors de la génération du rapport:', error);
            throw error;
        }
    }

    /**
     * Initialise l'exécution granulaire pour un chantier
     * Crée les entrées de tâches basées sur les templates
     */
    async initialiserExecutionGranulaire(chantierID: string): Promise<void> {
        try {
            await apiClient.post(`${this.basePath}/${chantierID}/initialiser-execution-granulaire`);
        } catch (error) {
            console.error('Erreur lors de l\'initialisation de l\'exécution granulaire:', error);
            throw error;
        }
    }

    /**
     * Calcule l'avancement projeté basé sur la vitesse actuelle
     */
    async calculerAvancementProjetee(chantierID: string, dateTarget: Date): Promise<number> {
        try {
            const response = await apiClient.post(
                `${this.basePath}/${chantierID}/avancement-projete`,
                { dateTarget: dateTarget.toISOString() }
            );
            return response.data.pourcentageProjecte;
        } catch (error) {
            console.error('Erreur lors du calcul de l\'avancement projeté:', error);
            throw error;
        }
    }

    /**
     * Récupère l'historique d'avancement du chantier
     */
    async getHistoriqueAvancement(chantierID: string, periode: 'SEMAINE' | 'MOIS' = 'SEMAINE'): Promise<{
        date: Date;
        pourcentage: number;
        tachesTermineesJour: number;
        efficaciteJour: number;
    }[]> {
        try {
            const response = await apiClient.get(`${this.basePath}/${chantierID}/historique-avancement`, {
                params: { periode }
            });
            return response.data.map((entry: any) => ({
                ...entry,
                date: new Date(entry.date)
            }));
        } catch (error) {
            console.error('Erreur lors de la récupération de l\'historique:', error);
            throw error;
        }
    }

    /**
     * Valide la completion d'une sous-phase
     * Toutes les tâches critiques doivent être terminées
     */
    async validerCompletionSousPhase(chantierID: string, sousPhaseId: string): Promise<{
        valide: boolean;
        tachesCritiquesRestantes: string[];
        pourcentageCompletion: number;
    }> {
        try {
            const response = await apiClient.post(`${this.basePath}/${chantierID}/valider-sous-phase/${sousPhaseId}`);
            return response.data;
        } catch (error) {
            console.error('Erreur lors de la validation de la sous-phase:', error);
            throw error;
        }
    }
}

export const executionGranulaireService = new ExecutionGranulaireService();