import axios from 'axios';
import { API_CONFIG } from '../config/api';
import { 
    AnalysePrixPhase, 
    ApiResponse 
} from '../types/btp-extended';
import materielPhaseService from './materielPhaseService';
import fournisseurPhaseService from './fournisseurPhaseService';

class AnalysePrixService {
    private readonly basePath = '/analyses-prix';
    private api = axios.create({
        baseURL: API_CONFIG.baseURL,
        timeout: API_CONFIG.timeout,
        headers: API_CONFIG.headers,
    });

    constructor() {
        // Interceptor pour ajouter le token JWT
        this.api.interceptors.request.use(
            (config) => {
                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 = '/api/auth/login';
                }
                return Promise.reject(error);
            }
        );
    }

    /**
     * Récupérer l'analyse de prix d'une phase
     */
    async getByPhase(phaseId: string): Promise<AnalysePrixPhase | null> {
        if (!phaseId || phaseId === 'undefined' || phaseId === 'null' || phaseId === 'NaN') {
            console.warn(`ID de phase invalide: ${phaseId}`);
            return null;
        }

        try {
            const response = await this.api.get(`${this.basePath}/phase/${phaseId}`);
            return response.data;
        } catch (error) {
            console.warn(`Endpoint ${this.basePath}/phase/${phaseId} non disponible:`, error);
            return null;
        }
    }

    /**
     * Créer ou mettre à jour une analyse de prix
     */
    async createOrUpdate(analyse: Omit<AnalysePrixPhase, 'id'>): Promise<AnalysePrixPhase> {
        try {
            const response = await this.api.post(`${this.basePath}`, analyse);
            return response.data;
        } catch (error) {
            console.warn('Endpoint createOrUpdate non disponible, calcul local:', error);
            return {
                ...analyse,
                id: Date.now(), // ID temporaire
                dateAnalyse: new Date()
            };
        }
    }

    /**
     * Calculer automatiquement l'analyse de prix d'une phase
     */
    async calculerAnalyseComplete(phaseId: string): Promise<AnalysePrixPhase> {
        try {
            // Récupération des données de base
            const [materiels, fournisseurs] = await Promise.all([
                materielPhaseService.getByPhase(phaseId),
                fournisseurPhaseService.getByPhase(phaseId)
            ]);

            // Calcul du coût des matériaux
            const coutMateriauxTotal = materiels.reduce((total, materiel) => {
                const prix = materiel.prixUnitaireNegocie || materiel.prixUnitaireCatalogue || 0;
                const quantite = materiel.quantiteUtilisee || materiel.quantitePrevue || 0;
                return total + (prix * quantite);
            }, 0);

            // Calcul du coût de main d'œuvre (estimation basée sur les matériaux)
            const coutMainOeuvreTotal = this.estimerCoutMainOeuvre(coutMateriauxTotal);

            // Calcul du coût de sous-traitance
            const coutSousTraitanceTotal = fournisseurs
                .filter(f => f.typeContribution === 'SOUS_TRAITANCE')
                .reduce((total, f) => total + (f.prixNegocie || f.prixCatalogue || 0), 0);

            // Calcul du coût des services et autres
            const coutAutresTotal = fournisseurs
                .filter(f => ['SERVICE', 'LOCATION', 'TRANSPORT'].includes(f.typeContribution))
                .reduce((total, f) => total + (f.prixNegocie || f.prixCatalogue || 0), 0);

            // Coût total direct
            const coutTotalDirect = coutMateriauxTotal + coutMainOeuvreTotal + coutSousTraitanceTotal + coutAutresTotal;

            // Frais généraux (15% par défaut)
            const tauxFraisGeneraux = 0.15;
            const fraisGeneraux = coutTotalDirect * tauxFraisGeneraux;
            const coutTotalAvecFrais = coutTotalDirect + fraisGeneraux;

            // Marge objectif (20% par défaut)
            const tauxMargeObjectif = 0.20;
            const margeObjectif = coutTotalAvecFrais * tauxMargeObjectif;
            const prixVenteCalcule = coutTotalAvecFrais + margeObjectif;

            // Calcul de la rentabilité prévisionnelle
            const rentabilitePrevisionnelle = (margeObjectif / prixVenteCalcule) * 100;

            const analyse: AnalysePrixPhase = {
                phase: { id: parseInt(phaseId) } as any,
                coutMateriauxTotal,
                coutMainOeuvreTotal,
                coutSousTraitanceTotal,
                coutAutresTotal,
                coutTotalDirect,
                fraisGeneraux,
                tauxFraisGeneraux: tauxFraisGeneraux * 100,
                coutTotalAvecFrais,
                margeObjectif,
                tauxMargeObjectif: tauxMargeObjectif * 100,
                prixVenteCalcule,
                rentabilitePrevisionnelle,
                dateAnalyse: new Date()
            };

            return await this.createOrUpdate(analyse);
        } catch (error) {
            console.error('Erreur lors du calcul de l\'analyse de prix:', error);
            throw error;
        }
    }

    /**
     * Comparer plusieurs scénarios de prix
     */
    async comparerScenarios(
        phaseId: string, 
        scenarios: Array<{
            nom: string;
            tauxMarge: number;
            tauxFraisGeneraux?: number;
        }>
    ): Promise<Array<AnalysePrixPhase & { nomScenario: string }>> {
        const analyseBase = await this.calculerAnalyseComplete(phaseId);
        
        return scenarios.map(scenario => {
            const tauxFraisGeneraux = scenario.tauxFraisGeneraux || 0.15;
            const fraisGeneraux = analyseBase.coutTotalDirect * tauxFraisGeneraux;
            const coutTotalAvecFrais = analyseBase.coutTotalDirect + fraisGeneraux;
            const margeObjectif = coutTotalAvecFrais * (scenario.tauxMarge / 100);
            const prixVenteCalcule = coutTotalAvecFrais + margeObjectif;
            const rentabilitePrevisionnelle = (margeObjectif / prixVenteCalcule) * 100;

            return {
                ...analyseBase,
                nomScenario: scenario.nom,
                tauxFraisGeneraux: tauxFraisGeneraux * 100,
                fraisGeneraux,
                coutTotalAvecFrais,
                tauxMargeObjectif: scenario.tauxMarge,
                margeObjectif,
                prixVenteCalcule,
                rentabilitePrevisionnelle
            };
        });
    }

    /**
     * Valider une analyse de prix
     */
    async validerAnalyse(id: number, validePar: string): Promise<AnalysePrixPhase> {
        try {
            const response = await this.api.post(`${this.basePath}/${id}/valider`, {
                validePar,
                dateValidation: new Date(),
                validee: true
            });
            return response.data;
        } catch (error) {
            console.warn('Validation non disponible côté serveur');
            throw error;
        }
    }

    /**
     * Calculer la rentabilité réelle après réalisation
     */
    async calculerRentabiliteReelle(phaseId: string, coutReel: number, prixVenteReel: number): Promise<number> {
        const margeReelle = prixVenteReel - coutReel;
        return (margeReelle / prixVenteReel) * 100;
    }

    /**
     * Obtenir l'historique des analyses d'une phase
     */
    async getHistorique(phaseId: string): Promise<AnalysePrixPhase[]> {
        try {
            const response = await this.api.get(`${this.basePath}/phase/${phaseId}/historique`);
            return response.data;
        } catch (error) {
            console.warn('Historique non disponible');
            return [];
        }
    }

    /**
     * Estimation du coût de main d'œuvre basée sur les matériaux
     * (règle métier: environ 40-60% du coût des matériaux selon la complexité)
     */
    private estimerCoutMainOeuvre(coutMateriaux: number): number {
        // Facteur de complexité moyen: 0.5 (50% des matériaux)
        return coutMateriaux * 0.5;
    }

    /**
     * Analyser la compétitivité d'un prix
     */
    analyserCompetitivite(analyse: AnalysePrixPhase, prixMarche?: number): {
        niveau: 'TRÈS_COMPÉTITIF' | 'COMPÉTITIF' | 'MOYEN' | 'ÉLEVÉ' | 'TRÈS_ÉLEVÉ';
        commentaire: string;
        recommandation: string;
    } {
        const tauxMarge = analyse.tauxMargeObjectif || 0;
        
        if (tauxMarge < 10) {
            return {
                niveau: 'TRÈS_COMPÉTITIF',
                commentaire: 'Prix très agressif avec marge faible',
                recommandation: 'Attention aux risques financiers, vérifier la viabilité'
            };
        } else if (tauxMarge < 20) {
            return {
                niveau: 'COMPÉTITIF',
                commentaire: 'Prix compétitif avec marge raisonnable',
                recommandation: 'Bon équilibre entre compétitivité et rentabilité'
            };
        } else if (tauxMarge < 30) {
            return {
                niveau: 'MOYEN',
                commentaire: 'Prix dans la moyenne du marché',
                recommandation: 'Position standard, opportunités d\'optimisation possibles'
            };
        } else if (tauxMarge < 40) {
            return {
                niveau: 'ÉLEVÉ',
                commentaire: 'Prix élevé avec forte marge',
                recommandation: 'Risque de perte de compétitivité, justifier la valeur ajoutée'
            };
        } else {
            return {
                niveau: 'TRÈS_ÉLEVÉ',
                commentaire: 'Prix très élevé',
                recommandation: 'Revoir la stratégie tarifaire, optimiser les coûts'
            };
        }
    }
}

export default new AnalysePrixService();