import axios from 'axios';
import { API_CONFIG } from '../config/api';
import { 
    PhaseChantier, 
    PhaseChantierFormData, 
    PhaseFilters,
    JalonPhase,
    PointagePhase,
    StatutPhase,
    ApiResponse 
} from '../types/btp-extended';
import { MaterielBTPService, MaterielBTP, CategorieMateriel } from './materielBTPService';
import { CalculsTechniquesService, ParametresCalculBriques, ResultatCalculBriques } from './calculsTechniquesService';
import { ZoneClimatiqueService, ZoneClimatique } from './zoneClimatiqueService';

class PhaseService {
    private readonly basePath = '/api/v1/phases-chantier';
    private api = axios.create({
        baseURL: API_CONFIG.baseURL,
        timeout: API_CONFIG.timeout,
        headers: API_CONFIG.headers,
    });

    constructor() {
        // Interceptor pour ajouter le token Keycloak
        this.api.interceptors.request.use(
            async (config) => {
                // Vérifier si Keycloak est initialisé et l'utilisateur authentifié
                if (typeof window !== 'undefined') {
                    const { keycloak, KEYCLOAK_TIMEOUTS } = await import('../config/keycloak');

                    if (keycloak.authenticated) {
                        try {
                            // Rafraîchir le token si nécessaire
                            await keycloak.updateToken(KEYCLOAK_TIMEOUTS.TOKEN_REFRESH_BEFORE_EXPIRY);

                            // Ajouter le token Bearer à l'en-tête Authorization
                            if (keycloak.token) {
                                config.headers['Authorization'] = `Bearer ${keycloak.token}`;
                            }
                        } catch (error) {
                            console.error('Erreur lors de la mise à jour du token Keycloak:', error);
                            keycloak.login();
                            throw error;
                        }
                    } else {
                        // Fallback vers l'ancien système pour la rétrocompatibilité
                        let token = null;
                        try {
                            const authTokenItem = sessionStorage.getItem('auth_token') || localStorage.getItem('auth_token');
                            if (authTokenItem) {
                                const parsed = JSON.parse(authTokenItem);
                                token = parsed.value;
                            }
                        } catch (e) {
                            token = localStorage.getItem('token');
                        }

                        if (token) {
                            config.headers['Authorization'] = `Bearer ${token}`;
                        }
                    }
                }
                return config;
            },
            (error) => Promise.reject(error)
        );

        // Interceptor pour les réponses
        this.api.interceptors.response.use(
            (response) => response,
            (error) => {
                if (error.response?.status === 401) {
                    localStorage.removeItem('token');
                    localStorage.removeItem('user');
                    window.location.href = '/auth/login';
                }
                return Promise.reject(error);
            }
        );
    }

    /**
     * Récupérer les phases d'un chantier
     */
    async getByChantier(chantierId: string): Promise<PhaseChantier[]> {
        // Vérifier si l'ID est valide
        if (!chantierId || chantierId === 'undefined' || chantierId === 'null' || chantierId === 'NaN') {
            console.warn(`ID de chantier invalide: ${chantierId}`);
            return [];
        }

        try {
            console.log(`🔍 Recherche des phases pour chantier: ${chantierId}`);
            // Ajouter un timestamp pour éviter le cache
            const response = await this.api.get(`${this.basePath}/chantier/${chantierId}`, {
                params: {
                    _t: Date.now() // Forcer le rafraîchissement
                }
            });
            console.log(`✅ ${response.data.length} phases récupérées pour chantier ${chantierId}:`, response.data);
            return response.data;
        } catch (error) {
            // Pour l'instant, retourner des données vides si l'endpoint n'existe pas
            console.warn(`❌ Endpoint ${this.basePath}/chantier/${chantierId} non disponible:`, error);
            return [];
        }
    }

    /**
     * Récupérer toutes les phases
     */
    async getAll(): Promise<PhaseChantier[]> {
        try {
            const response = await this.api.get(this.basePath);
            console.log('Toutes les phases récupérées:', response.data);
            return response.data;
        } catch (error) {
            console.warn('Erreur lors de la récupération de toutes les phases:', error);
            return [];
        }
    }

    /**
     * Récupérer une phase par ID
     */
    async getById(id: string): Promise<PhaseChantier> {
        const response = await this.api.get(`${this.basePath}/${id}`);
        return response.data;
    }

    /**
     * Créer une nouvelle phase
     */
    async create(phase: PhaseChantierFormData): Promise<PhaseChantier> {
        // D'abord récupérer les phases existantes pour calculer l'ordre d'exécution
        const chantierId = phase.chantier?.id || phase.chantierId;
        if (!chantierId) {
            throw new Error('ID du chantier requis');
        }

        // Récupérer les phases existantes pour calculer le prochain ordre
        const existingPhases = await this.getByChantier(chantierId);
        const nextOrder = existingPhases.length > 0 
            ? Math.max(...existingPhases.map(p => p.ordreExecution || 0)) + 1 
            : 1;

        // S'assurer que chantierId est inclus dans la requête
        // et mapper phaseParent vers phaseParentId pour le backend
        const requestData = {
            ...phase,
            chantierId: chantierId,
            ordreExecution: phase.ordreExecution || nextOrder,
            phaseParentId: phase.phaseParent || phase.phaseParentId
        };
        // Supprimer phaseParent si il existe pour éviter la confusion
        delete requestData.phaseParent;
        
        console.log('🚀 Création de phase avec données:', requestData);
        const response = await this.api.post(this.basePath, requestData);
        console.log('✅ Phase créée avec succès:', response.data);
        return response.data;
    }

    /**
     * Modifier une phase existante
     */
    async update(id: string, phase: PhaseChantierFormData): Promise<PhaseChantier> {
        const response = await this.api.put(`${this.basePath}/${id}`, phase);
        return response.data;
    }

    /**
     * Supprimer une phase
     */
    async delete(id: string): Promise<void> {
        await this.api.delete(`${this.basePath}/${id}`);
    }

    /**
     * Générer des phases à partir d'un template
     */
    async generateFromTemplate(
        chantierId: number, 
        templateId: string, 
        configuration: {
            phasesSelectionnees: any[];
            configurationsPersonnalisees?: any;
            optionsAvancees?: any;
            dateDebutSouhaitee?: string;
            dureeGlobale?: number;
        }
    ): Promise<PhaseChantier[]> {
        try {
            console.log('Génération de phases depuis template:', { chantierId, templateId, configuration });
            
            // Pour l'instant, on utilise la génération locale basée sur les templates
            // Cette méthode peut être remplacée par un appel API backend plus tard
            const phasesGenerees: PhaseChantier[] = [];
            
            // Récupérer le template et générer les phases
            const typeChantierService = await import('./typeChantierService');
            const templates = await typeChantierService.default.getAllTemplates();
            const template = templates.find(t => t.id === templateId);
            
            if (!template) {
                throw new Error(`Template ${templateId} non trouvé`);
            }
            
            // Générer les phases sélectionnées depuis la configuration (avec données utilisateur)
            for (let i = 0; i < configuration.phasesSelectionnees.length; i++) {
                const phaseSelectionnee = configuration.phasesSelectionnees[i];
                
                // Utiliser les données personnalisées (saisies par l'utilisateur)
                const phaseData: any = {
                    nom: phaseSelectionnee.nom,
                    description: phaseSelectionnee.description,
                    chantierId: chantierId.toString(),
                    statut: 'PLANIFIEE' as StatutPhase,
                    ordreExecution: phaseSelectionnee.ordre,
                    dureeEstimeeHeures: (phaseSelectionnee.dureeEstimee || 1) * 8, // Convertir jours en heures (défaut 1 jour)
                    budgetPrevu: phaseSelectionnee.budgetEstime || 0,
                    coutReel: 0,
                    priorite: phaseSelectionnee.categorieMetier === 'GROS_OEUVRE' ? 'CRITIQUE' : 'MOYENNE',
                    critique: phaseSelectionnee.obligatoire,
                    dateDebutPrevue: configuration.dateDebutSouhaitee,
                    competencesRequises: phaseSelectionnee.competencesRequises || [],
                    materielsNecessaires: [],
                    fournisseursRecommandes: []
                };
                    
                // Créer la phase via l'API
                const phaseCreee = await this.create(phaseData);
                phasesGenerees.push(phaseCreee);
                
                // Créer les sous-phases si elles existent
                if (phaseSelectionnee.sousPhases && phaseSelectionnee.sousPhases.length > 0) {
                    for (let j = 0; j < phaseSelectionnee.sousPhases.length; j++) {
                        const sousPhaseTemplate = phaseSelectionnee.sousPhases[j];
                        
                        const sousPhaseData: any = {
                            nom: sousPhaseTemplate.nom,
                            description: sousPhaseTemplate.description,
                            chantierId: chantierId.toString(),
                            statut: 'PLANIFIEE' as StatutPhase,
                            phaseParentId: phaseCreee.id,
                            ordreExecution: sousPhaseTemplate.ordre,
                            dureeEstimeeHeures: (sousPhaseTemplate.dureeEstimee || 1) * 8,
                            budgetPrevu: sousPhaseTemplate.budgetEstime || 0,
                            coutReel: 0,
                            priorite: 'MOYENNE',
                            critique: sousPhaseTemplate.obligatoire,
                            competencesRequises: sousPhaseTemplate.competencesRequises || [],
                            materielsNecessaires: [],
                            fournisseursRecommandes: []
                        };
                        
                        const sousPhaseCreee = await this.create(sousPhaseData);
                        phasesGenerees.push(sousPhaseCreee);
                    }
                }
            }
            
            console.log('Phases générées avec succès:', phasesGenerees);
            return phasesGenerees;
            
        } catch (error) {
            console.error('Erreur lors de la génération depuis template:', error);
            throw error;
        }
    }

    /**
     * Démarrer une phase
     */
    async start(id: string): Promise<void> {
        await this.api.post(`${this.basePath}/${id}/demarrer`);
    }

    /**
     * Terminer une phase
     */
    async complete(id: string): Promise<void> {
        await this.api.post(`${this.basePath}/${id}/terminer`);
    }

    /**
     * Suspendre une phase
     */
    async suspend(id: string): Promise<void> {
        await this.api.post(`${this.basePath}/${id}/suspendre`);
    }

    /**
     * Reprendre une phase suspendue
     */
    async resume(id: string): Promise<void> {
        await this.api.post(`${this.basePath}/${id}/reprendre`);
    }

    /**
     * Mettre à jour l'avancement d'une phase
     */
    async updateProgress(id: string, pourcentage: number): Promise<void> {
        await this.api.put(`${this.basePath}/${id}/avancement?pourcentage=${pourcentage}`);
    }

    /**
     * Alias français pour start()
     */
    async demarrer(id: string): Promise<void> {
        return this.start(id);
    }

    /**
     * Alias français pour complete()
     */
    async terminer(id: string): Promise<void> {
        return this.complete(id);
    }

    /**
     * Alias français pour suspend()
     */
    async suspendre(id: string, motif?: string): Promise<void> {
        return this.suspend(id);
    }

    /**
     * Alias français pour resume()
     */
    async reprendre(id: string): Promise<void> {
        return this.resume(id);
    }

    /**
     * Alias français pour updateProgress()
     */
    async updateAvancement(id: string, pourcentage: number): Promise<void> {
        return this.updateProgress(id, pourcentage);
    }

    /**
     * Récupérer les statuts disponibles
     */
    async getStatuts(): Promise<StatutPhase[]> {
        const response = await this.api.get(`${this.basePath}/statuts`);
        return response.data;
    }

    /**
     * Récupérer les phases en retard
     */
    async getEnRetard(): Promise<PhaseChantier[]> {
        const response = await this.api.get(`${this.basePath}/en-retard`);
        return response.data;
    }

    /**
     * Récupérer les phases d'un responsable
     */
    async getByResponsable(employeId: number): Promise<PhaseChantier[]> {
        const response = await this.api.get(`${this.basePath}/responsable/${employeId}`);
        return response.data;
    }

    /**
     * Récupérer les jalons d'une phase
     */
    async getJalons(phaseId: number): Promise<JalonPhase[]> {
        const response = await this.api.get(`${this.basePath}/${phaseId}/jalons`);
        return response.data;
    }

    /**
     * Récupérer les pointages d'une phase
     */
    async getPointages(phaseId: number): Promise<PointagePhase[]> {
        const response = await this.api.get(`${this.basePath}/${phaseId}/pointages`);
        return response.data;
    }

    /**
     * Obtenir le libellé d'un statut
     */
    getStatutLabel(statut: StatutPhase): string {
        const labels: Record<StatutPhase, string> = {
            PLANIFIEE: 'Planifiée',
            EN_ATTENTE: 'En attente',
            EN_COURS: 'En cours',
            EN_PAUSE: 'En pause',
            TERMINEE: 'Terminée',
            ANNULEE: 'Annulée',
            EN_RETARD: 'En retard'
        };
        return labels[statut] || statut;
    }

    /**
     * Obtenir la couleur d'un statut
     */
    getStatutColor(statut: StatutPhase): string {
        const colors: Record<StatutPhase, string> = {
            PLANIFIEE: '#6c757d',
            EN_ATTENTE: '#ffc107',
            EN_COURS: '#0d6efd',
            EN_PAUSE: '#fd7e14',
            TERMINEE: '#198754',
            ANNULEE: '#dc3545',
            EN_RETARD: '#dc3545'
        };
        return colors[statut] || '#6c757d';
    }

    /**
     * Vérifier si une phase est en retard
     */
    isEnRetard(phase: PhaseChantier): boolean {
        if (phase.statut === 'TERMINEE') return false;
        if (!phase.dateFinPrevue) return false;
        
        return new Date() > new Date(phase.dateFinPrevue);
    }


}

export default new PhaseService();