import ApiService from './ApiService';

/**
 * Service pour la gestion des matériaux BTP ultra-détaillés
 * Connecté aux APIs backend du système le plus ambitieux d'Afrique
 */

export interface MaterielBTP {
  id: number;
  code: string;
  nom: string;
  description: string;
  categorie: CategorieMateriel;
  sousCategorie: string;
  
  // Dimensions techniques
  dimensions: {
    longueur: number;
    largeur: number;
    hauteur: number;
    diametre?: number;
    tolerance: number;
    surface?: number;
    volume?: number;
    perimetre?: number;
  };

  // Propriétés physiques
  densite: number;
  resistanceCompression: number;
  resistanceTraction: number;
  resistanceFlexion: number;
  moduleElasticite: number;
  coefficientDilatation: number;
  absorptionEau: number;
  porosite: number;
  conductiviteThermique: number;
  resistanceGel: boolean;
  resistanceIntemperies: NiveauResistance;

  // Spécifications climatiques
  temperatureMin: number;
  temperatureMax: number;
  humiditeMax: number;
  resistanceUV: NiveauResistance;
  resistancePluie: NiveauResistance;
  resistanceVentFort: boolean;

  // Normes et certifications
  normePrincipale: string;
  classification: string;
  certificationRequise: boolean;
  marquageCE: boolean;
  conformiteECOWAS: boolean;
  conformiteSADC?: boolean;

  // Quantification
  uniteBase: string;
  facteurPerte: number;
  facteurSurapprovisionnement: number;
  modeFourniture: ModeFourniture;
  quantiteParUnite: number;
  poidsUnitaire: number;

  // Calcul automatique
  formuleCalcul?: string;
  parametresCalcul?: string;

  // Mise en œuvre
  tempsUnitaire: number;
  temperatureOptimaleMin: number;
  temperatureOptimaleMax: number;

  // Contrôle qualité
  frequenceControle: string;
  dureeVieEstimee: number;
  maintenanceRequise: boolean;

  // Métadonnées
  actif: boolean;
  creePar: string;
  dateCreation: string;
  modifiePar?: string;
  dateModification?: string;
}

export enum CategorieMateriel {
  GROS_OEUVRE = 'GROS_OEUVRE',
  SECOND_OEUVRE = 'SECOND_OEUVRE',
  FINITION = 'FINITION',
  PLOMBERIE = 'PLOMBERIE',
  ELECTRICITE = 'ELECTRICITE',
  MENUISERIE = 'MENUISERIE',
  COUVERTURE = 'COUVERTURE',
  ISOLATION = 'ISOLATION',
  OUTILLAGE = 'OUTILLAGE',
  EQUIPEMENT = 'EQUIPEMENT'
}

export enum NiveauResistance {
  EXCELLENT = 'EXCELLENT',
  BON = 'BON',
  MOYEN = 'MOYEN',
  FAIBLE = 'FAIBLE'
}

export enum ModeFourniture {
  VRAC = 'VRAC',
  SACS = 'SACS',
  PALETTE = 'PALETTE',
  UNITE = 'UNITE',
  KIT = 'KIT'
}

export interface RechercheMaterielParams {
  categorie?: CategorieMateriel;
  sousCategorie?: string;
  texte?: string;
  temperatureMin?: number;
  temperatureMax?: number;
  certifie?: boolean;
  zoneClimatique?: string;
  actif?: boolean;
}

export interface StatistiquesMateriel {
  total: number;
  parCategorie: Array<{ categorie: string; nombre: number; densiteMoyenne: number }>;
  certifies: number;
  marquageCE: number;
  conformesECOWAS: number;
}

export class MaterielBTPService {
  private static readonly BASE_PATH = '/calculs-techniques';

  /**
   * Récupère tous les matériaux ou par critères
   */
  static async getMateriaux(params?: RechercheMaterielParams): Promise<{
    materiaux: MaterielBTP[];
    total: number;
    filtres: any;
  }> {
    const queryParams = new URLSearchParams();
    
    if (params?.categorie) queryParams.append('categorie', params.categorie);
    if (params?.zoneClimatique) queryParams.append('zone', params.zoneClimatique);
    
    const url = `${this.BASE_PATH}/materiaux${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
    
    const response = await ApiService.get<{
      materiaux: MaterielBTP[];
      total: number;
      filtres: any;
    }>(url);

    return response;
  }

  /**
   * Recherche avancée de matériaux
   */
  static async rechercherMateriaux(params: RechercheMaterielParams): Promise<MaterielBTP[]> {
    const response = await ApiService.post<MaterielBTP[]>(`${this.BASE_PATH}/materiaux/recherche`, params);
    return response;
  }

  /**
   * Récupère un matériau par son code
   */
  static async getMaterielByCode(code: string): Promise<MaterielBTP> {
    const response = await ApiService.get<MaterielBTP>(`${this.BASE_PATH}/materiaux/${code}`);
    return response;
  }

  /**
   * Récupère les matériaux par catégorie
   */
  static async getMateriauxByCategorie(categorie: CategorieMateriel): Promise<MaterielBTP[]> {
    const response = await this.getMateriaux({ categorie });
    return response.materiaux;
  }

  /**
   * Récupère les matériaux adaptés à une zone climatique
   */
  static async getMateriauxAdaptesZone(zoneClimatique: string): Promise<MaterielBTP[]> {
    const response = await this.getMateriaux({ zoneClimatique });
    return response.materiaux;
  }

  /**
   * Récupère les matériaux par sous-catégorie
   */
  static async getMateriauxBySousCategorie(sousCategorie: string): Promise<MaterielBTP[]> {
    const response = await this.getMateriaux({ sousCategorie });
    return response.materiaux;
  }

  /**
   * Recherche textuelle de matériaux
   */
  static async rechercherTexte(texte: string): Promise<MaterielBTP[]> {
    const response = await this.getMateriaux({ texte });
    return response.materiaux;
  }

  /**
   * Récupère les matériaux certifiés
   */
  static async getMateriauxCertifies(): Promise<MaterielBTP[]> {
    const response = await this.getMateriaux({ certifie: true });
    return response.materiaux;
  }

  /**
   * Récupère les matériaux pour une plage de température
   */
  static async getMateriauxParTemperature(tempMin: number, tempMax: number): Promise<MaterielBTP[]> {
    const response = await this.getMateriaux({ temperatureMin: tempMin, temperatureMax: tempMax });
    return response.materiaux;
  }

  /**
   * Récupère les statistiques des matériaux
   */
  static async getStatistiquesMateriaux(): Promise<StatistiquesMateriel> {
    const response = await ApiService.get<StatistiquesMateriel>(`${this.BASE_PATH}/materiaux/statistiques`);
    return response;
  }

  /**
   * Récupère les sous-catégories d'une catégorie
   */
  static async getSousCategories(categorie: CategorieMateriel): Promise<string[]> {
    const materiaux = await this.getMateriauxByCategorie(categorie);
    const sousCategories = [...new Set(materiaux.map(m => m.sousCategorie))];
    return sousCategories.sort();
  }

  /**
   * Récupère les types d'unités utilisées
   */
  static async getUnitesBase(): Promise<string[]> {
    const response = await this.getMateriaux();
    const unites = [...new Set(response.materiaux.map(m => m.uniteBase))];
    return unites.sort();
  }

  /**
   * Récupère les normes utilisées
   */
  static async getNormesPrincipales(): Promise<string[]> {
    const response = await this.getMateriaux();
    const normes = [...new Set(response.materiaux.map(m => m.normePrincipale))];
    return normes.sort();
  }

  /**
   * Validation d'un matériau pour une zone climatique
   */
  static async validerMaterielPourZone(codeMateriel: string, zoneClimatique: string): Promise<{
    adapte: boolean;
    warnings: string[];
    recommendations: string[];
  }> {
    const response = await ApiService.post<{
      adapte: boolean;
      warnings: string[];
      recommendations: string[];
    }>(`${this.BASE_PATH}/materiaux/${codeMateriel}/validation-zone`, { zoneClimatique });
    
    return response;
  }

  /**
   * Récupère les alternatives à un matériau
   */
  static async getAlternativesMateriel(codeMateriel: string, zoneClimatique?: string): Promise<MaterielBTP[]> {
    const queryParams = new URLSearchParams();
    if (zoneClimatique) queryParams.append('zone', zoneClimatique);
    
    const url = `${this.BASE_PATH}/materiaux/${codeMateriel}/alternatives${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
    const response = await ApiService.get<{ alternatives: MaterielBTP[] }>(url);
    
    return response.alternatives;
  }

  /**
   * Calcule les quantités nécessaires selon formule matériau
   */
  static async calculerQuantite(codeMateriel: string, parametres: Record<string, number>): Promise<{
    quantiteBase: number;
    quantiteAvecPerte: number;
    quantiteAvecSurapprovisionnement: number;
    uniteQuantite: string;
    details: any;
  }> {
    const response = await ApiService.post<{
      quantiteBase: number;
      quantiteAvecPerte: number;
      quantiteAvecSurapprovisionnement: number;
      uniteQuantite: string;
      details: any;
    }>(`${this.BASE_PATH}/materiaux/${codeMateriel}/calcul-quantite`, parametres);
    
    return response;
  }

  /**
   * Export des matériaux en différents formats
   */
  static async exporterMateriaux(format: 'CSV' | 'EXCEL' | 'PDF', filtres?: RechercheMaterielParams): Promise<Blob> {
    const response = await ApiService.post<Blob>(
      `${this.BASE_PATH}/materiaux/export`, 
      { format, filtres },
      { responseType: 'blob' }
    );
    
    return response;
  }
}