/**
 * Service pour gérer la cohérence des budgets entre chantiers et phases
 * Assure que le montant_prevu du chantier correspond à la somme des budget_prevu des phases
 */

import { API_CONFIG } from '../config/api';
import axios from 'axios';

interface BudgetCoherence {
    chantierId: string;
    chantierNom: string;
    budgetChantier: number;
    budgetPhasesTotal: number;
    ecartAbsolu: number;
    ecartPourcentage: number;
    coherent: boolean;
    nombrePhases: number;
}

interface ValidationBudget {
    valide: boolean;
    message: string;
    recommandation?: 'METTRE_A_JOUR_CHANTIER' | 'AJUSTER_PHASES' | 'AUCUNE_ACTION';
    nouveauBudgetSuggere?: number;
}

class BudgetCoherenceService {
    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)
        );
    }

    /**
     * Vérifier la cohérence budgétaire pour un chantier donné
     */
    async verifierCoherence(chantierId: string): Promise<BudgetCoherence> {
        try {
            // Pour l'instant, on fait toujours le calcul côté client
            // L'endpoint backend sera implémenté plus tard
            const [chantierResponse, phasesResponse] = await Promise.all([
                this.api.get(`/api/v1/chantiers/${chantierId}`),
                this.api.get(`/api/v1/phases-chantier/chantier/${chantierId}`)
            ]);

            const chantier = chantierResponse.data;
            const phases = phasesResponse.data || [];

            const budgetChantier = parseFloat(chantier.montantPrevu || 0);
            const budgetPhasesTotal = phases.reduce((sum: number, phase: any) => 
                sum + parseFloat(phase.budgetPrevu || 0), 0);

            const ecartAbsolu = Math.abs(budgetChantier - budgetPhasesTotal);
            const ecartPourcentage = budgetChantier > 0 ? (ecartAbsolu / budgetChantier) * 100 : 0;

            return {
                chantierId,
                chantierNom: chantier.nom,
                budgetChantier,
                budgetPhasesTotal,
                ecartAbsolu,
                ecartPourcentage,
                coherent: ecartPourcentage <= 5, // Tolérance de 5%
                nombrePhases: phases.length
            };
        } catch (error) {
            console.warn('Erreur lors de la vérification de cohérence:', error);
            // Retourner des valeurs par défaut en cas d'erreur
            return {
                chantierId,
                chantierNom: 'Chantier inconnu',
                budgetChantier: 0,
                budgetPhasesTotal: 0,
                ecartAbsolu: 0,
                ecartPourcentage: 0,
                coherent: true, // Considérer comme cohérent en cas d'erreur
                nombrePhases: 0
            };
        }
    }

    /**
     * Valider un budget de phases avant génération
     */
    async validerBudgetPhases(chantierId: string, budgetPhasesPrevu: number): Promise<ValidationBudget> {
        try {
            const coherence = await this.verifierCoherence(chantierId);
            const nouveauTotal = budgetPhasesPrevu;
            const ecart = Math.abs(coherence.budgetChantier - nouveauTotal);
            const ecartPourcentage = coherence.budgetChantier > 0 ? (ecart / coherence.budgetChantier) * 100 : 0;

            if (ecartPourcentage <= 5) {
                return {
                    valide: true,
                    message: 'Le budget des phases est cohérent avec le budget du chantier',
                    recommandation: 'AUCUNE_ACTION'
                };
            } else if (nouveauTotal > coherence.budgetChantier) {
                return {
                    valide: false,
                    message: `Le budget des phases (${this.formatCurrency(nouveauTotal)}) dépasse le budget du chantier (${this.formatCurrency(coherence.budgetChantier)}) de ${ecartPourcentage.toFixed(1)}%`,
                    recommandation: 'METTRE_A_JOUR_CHANTIER',
                    nouveauBudgetSuggere: Math.ceil(nouveauTotal * 1.1) // +10% de marge
                };
            } else {
                return {
                    valide: false,
                    message: `Le budget des phases (${this.formatCurrency(nouveauTotal)}) est inférieur au budget du chantier (${this.formatCurrency(coherence.budgetChantier)}) de ${ecartPourcentage.toFixed(1)}%`,
                    recommandation: 'AJUSTER_PHASES',
                    nouveauBudgetSuggere: coherence.budgetChantier
                };
            }
        } catch (error) {
            console.error('Erreur lors de la validation budgétaire:', error);
            return {
                valide: true, // En cas d'erreur, on laisse passer
                message: 'Impossible de valider la cohérence budgétaire'
            };
        }
    }

    /**
     * Mettre à jour le budget du chantier pour le faire correspondre aux phases
     */
    async synchroniserBudgetChantier(chantierId: string, nouveauBudget: number): Promise<boolean> {
        try {
            await this.api.put(`/api/v1/chantiers/${chantierId}`, {
                montantPrevu: nouveauBudget
            });
            console.log(`Budget du chantier mis à jour: ${this.formatCurrency(nouveauBudget)}`);
            return true;
        } catch (error) {
            console.error('Erreur lors de la mise à jour du budget:', error);
            return false;
        }
    }

    /**
     * Suggérer une répartition équilibrée du budget sur les phases
     */
    suggererRepartitionBudget(budgetTotal: number, phases: any[]): any[] {
        if (!phases.length) return [];

        // Répartition basée sur la complexité/durée des phases
        const phasesAvecPoids = phases.map(phase => ({
            ...phase,
            poids: this.calculerPoidsPhase(phase)
        }));

        const poidsTotal = phasesAvecPoids.reduce((sum, p) => sum + p.poids, 0);

        return phasesAvecPoids.map(phase => ({
            ...phase,
            budgetSuggere: Math.round((phase.poids / poidsTotal) * budgetTotal)
        }));
    }

    /**
     * Calculer le poids d'une phase pour la répartition budgétaire
     */
    private calculerPoidsPhase(phase: any): number {
        let poids = 1;
        
        // Basé sur la durée
        if (phase.dureeEstimee) {
            poids *= Math.max(1, phase.dureeEstimee / 5); // Phases plus longues = plus de poids
        }

        // Basé sur le type de phase
        const typesPoids: Record<string, number> = {
            'GROS_OEUVRE': 2.0,
            'FONDATIONS': 1.8,
            'CHARPENTE': 1.5,
            'SECOND_OEUVRE': 1.2,
            'FINITIONS': 1.0,
            'EQUIPEMENTS': 1.3
        };

        if (phase.categorieMetier && typesPoids[phase.categorieMetier]) {
            poids *= typesPoids[phase.categorieMetier];
        }

        // Phase critique = plus de poids
        if (phase.obligatoire || phase.critique) {
            poids *= 1.2;
        }

        return poids;
    }

    /**
     * Formater un montant en devise
     */
    private formatCurrency(amount: number): string {
        return new Intl.NumberFormat('fr-FR', {
            style: 'currency',
            currency: 'EUR',
            minimumFractionDigits: 0
        }).format(amount);
    }

    /**
     * Obtenir des recommandations budgétaires pour un chantier
     */
    async obtenirRecommandations(chantierId: string): Promise<string[]> {
        const coherence = await this.verifierCoherence(chantierId);
        const recommandations: string[] = [];

        if (!coherence.coherent) {
            if (coherence.budgetPhasesTotal > coherence.budgetChantier) {
                recommandations.push(
                    `💰 Le budget des phases dépasse celui du chantier de ${this.formatCurrency(coherence.ecartAbsolu)}`
                );
                recommandations.push(
                    `🔧 Recommandation : Augmenter le budget du chantier à ${this.formatCurrency(coherence.budgetPhasesTotal * 1.1)}`
                );
            } else {
                recommandations.push(
                    `📉 Le budget des phases est inférieur à celui du chantier de ${this.formatCurrency(coherence.ecartAbsolu)}`
                );
                recommandations.push(
                    `🔧 Recommandation : Réajuster les budgets des phases ou prévoir des phases supplémentaires`
                );
            }
        }

        if (coherence.nombrePhases === 0) {
            recommandations.push(
                `⚠️ Aucune phase définie pour ce chantier. Utilisez l'assistant de génération de phases.`
            );
        }

        return recommandations;
    }
}

export default new BudgetCoherenceService();