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

class MaterielPhaseService {
    private readonly basePath = '/materiels-phases';
    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 les matériels d'une phase
     */
    async getByPhase(phaseId: string): Promise<MaterielPhase[]> {
        if (!phaseId || phaseId === 'undefined' || phaseId === 'null' || phaseId === 'NaN') {
            console.warn(`ID de phase invalide: ${phaseId}`);
            return [];
        }

        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 [];
        }
    }

    /**
     * Récupérer un matériel de phase par ID
     */
    async getById(id: number): Promise<MaterielPhase> {
        const response = await this.api.get(`${this.basePath}/${id}`);
        return response.data;
    }

    /**
     * Créer un nouveau matériel de phase
     */
    async create(materielPhase: Omit<MaterielPhase, 'id'>): Promise<MaterielPhase> {
        console.log('Creating materiel phase with data:', materielPhase);
        const response = await this.api.post(this.basePath, materielPhase);
        return response.data;
    }

    /**
     * Modifier un matériel de phase existant
     */
    async update(id: number, materielPhase: Partial<MaterielPhase>): Promise<MaterielPhase> {
        const response = await this.api.put(`${this.basePath}/${id}`, materielPhase);
        return response.data;
    }

    /**
     * Supprimer un matériel de phase
     */
    async delete(id: number): Promise<void> {
        await this.api.delete(`${this.basePath}/${id}`);
    }

    /**
     * Calculer le coût total des matériels d'une phase
     */
    async calculerCoutTotal(phaseId: string): Promise<number> {
        try {
            const materiels = await this.getByPhase(phaseId);
            return materiels.reduce((total, materiel) => {
                const prix = materiel.prixUnitaireNegocie || materiel.prixUnitaireCatalogue || 0;
                const quantite = materiel.quantiteUtilisee || materiel.quantitePrevue || 0;
                return total + (prix * quantite);
            }, 0);
        } catch (error) {
            console.error('Erreur lors du calcul du coût total:', error);
            return 0;
        }
    }

    /**
     * Obtenir les matériels en rupture de stock pour une phase
     */
    async getMaterielsEnRupture(phaseId: string): Promise<MaterielPhase[]> {
        try {
            const materiels = await this.getByPhase(phaseId);
            return materiels.filter(materiel => 
                materiel.enStock === false || 
                (materiel.quantiteStock || 0) < (materiel.quantitePrevue || 0)
            );
        } catch (error) {
            console.error('Erreur lors de la vérification du stock:', error);
            return [];
        }
    }

    /**
     * Obtenir les alternatives de fournisseurs pour un matériel
     */
    async getFournisseursAlternatifs(materielPhaseId: number): Promise<FournisseurPhase[]> {
        try {
            const response = await this.api.get(`${this.basePath}/${materielPhaseId}/fournisseurs-alternatifs`);
            return response.data;
        } catch (error) {
            console.warn('Fournisseurs alternatifs non disponibles:', error);
            return [];
        }
    }

    /**
     * Négocier un prix avec un fournisseur
     */
    async negocierPrix(materielPhaseId: number, fournisseurId: number, prixNegocie: number): Promise<MaterielPhase> {
        const response = await this.api.post(`${this.basePath}/${materielPhaseId}/negocier-prix`, {
            fournisseurId,
            prixNegocie
        });
        return response.data;
    }

    /**
     * Valider la sélection d'un fournisseur
     */
    async validerFournisseur(materielPhaseId: number, fournisseurPhaseId: number): Promise<MaterielPhase> {
        const response = await this.api.post(`${this.basePath}/${materielPhaseId}/valider-fournisseur`, {
            fournisseurPhaseId
        });
        return response.data;
    }

    /**
     * Calculer l'analyse de prix pour une phase
     */
    async calculerAnalysePrix(phaseId: string): Promise<AnalysePrixPhase> {
        try {
            const response = await this.api.post(`/analyses-prix/calculer/${phaseId}`);
            return response.data;
        } catch (error) {
            // Calcul côté client si l'endpoint n'existe pas
            const materiels = await this.getByPhase(phaseId);
            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);

            return {
                phase: { id: parseInt(phaseId) } as any,
                coutMateriauxTotal,
                coutMainOeuvreTotal: 0,
                coutSousTraitanceTotal: 0,
                coutAutresTotal: 0,
                coutTotalDirect: coutMateriauxTotal,
                coutTotalAvecFrais: coutMateriauxTotal,
                prixVenteCalcule: coutMateriauxTotal * 1.2, // Marge de 20% par défaut
                dateAnalyse: new Date()
            };
        }
    }
}

export default new MaterielPhaseService();