import ApiService from './ApiService';
import { MaterielBTP } from './materielBTPService';

/**
 * Service pour la gestion des zones climatiques africaines
 * Système spécialisé pour les contraintes de construction en Afrique
 */

export interface ZoneClimatique {
  id: number;
  code: string;
  nom: string;
  description: string;

  // Paramètres climatiques
  temperatureMin: number;
  temperatureMax: number;
  pluviometrieAnnuelle: number;
  humiditeMin: number;
  humiditeMax: number;
  ventsMaximaux: number;

  // Risques naturels
  risqueSeisme: boolean;
  risqueCyclones: boolean;

  // Contraintes construction
  profondeurFondationsMin: number;
  drainageObligatoire: boolean;
  isolationThermiqueObligatoire: boolean;
  ventilationRenforcee: boolean;
  protectionUVObligatoire: boolean;
  traitementAntiTermites: boolean;
  resistanceCorrosionMarine: boolean;

  // Coefficients techniques
  coefficientVent: number;
  penteToitureMin: number;
  evacuationEPMin: number;

  // Relations
  pays?: string[];
  saisons?: SaisonClimatique[];
  contraintes?: ContrainteConstruction[];

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

export interface SaisonClimatique {
  nom: string;
  moisDebut: number;
  moisFin: number;
  temperatureMoyenne: number;
  pluviometrieMoyenne: number;
  humiditeRelative: number;
  caracteristiques: string[];
}

export interface ContrainteConstruction {
  type: TypeContrainte;
  description: string;
  obligatoire: boolean;
  solution: string;
  cout_supplementaire?: number;
}

export enum TypeContrainte {
  FONDATIONS = 'FONDATIONS',
  DRAINAGE = 'DRAINAGE',
  ISOLATION = 'ISOLATION',
  VENTILATION = 'VENTILATION',
  PROTECTION_UV = 'PROTECTION_UV',
  ANTI_TERMITES = 'ANTI_TERMITES',
  CORROSION_MARINE = 'CORROSION_MARINE',
  RESISTANCE_VENT = 'RESISTANCE_VENT',
  ETANCHEITE = 'ETANCHEITE'
}

export interface CriteresRecherche {
  temperatureMin?: number;
  temperatureMax?: number;
  pluvioMin?: number;
  pluvioMax?: number;
  risqueSeisme?: boolean;
  corrosionMarine?: boolean;
  texte?: string;
}

export interface StatistiquesZones {
  total: number;
  tempMoyenne: number;
  pluvioMoyenne: number;
  nbSeisme: number;
  nbMarine: number;
}

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

  /**
   * Récupère toutes les zones climatiques actives
   */
  static async getZonesClimatiques(): Promise<{
    zones: ZoneClimatique[];
    info: string;
  }> {
    const response = await ApiService.get<{
      zones: ZoneClimatique[];
      info: string;
    }>(`${this.BASE_PATH}/zones-climatiques`);

    return response;
  }

  /**
   * Récupère une zone climatique par son code
   */
  static async getZoneByCode(code: string): Promise<ZoneClimatique> {
    const response = await ApiService.get<ZoneClimatique>(`${this.BASE_PATH}/zones-climatiques/${code}`);
    return response;
  }

  /**
   * Recherche avancée de zones climatiques
   */
  static async rechercherZones(criteres: CriteresRecherche): Promise<ZoneClimatique[]> {
    const response = await ApiService.post<ZoneClimatique[]>(`${this.BASE_PATH}/zones-climatiques/recherche`, criteres);
    return response;
  }

  /**
   * Trouve les zones par plage de température
   */
  static async getZonesParTemperature(tempMin: number, tempMax: number): Promise<ZoneClimatique[]> {
    const criteres: CriteresRecherche = { temperatureMin: tempMin, temperatureMax: tempMax };
    return await this.rechercherZones(criteres);
  }

  /**
   * Trouve les zones par pluviométrie
   */
  static async getZonesParPluviometrie(pluvioMin: number, pluvioMax: number): Promise<ZoneClimatique[]> {
    const criteres: CriteresRecherche = { pluvioMin, pluvioMax };
    return await this.rechercherZones(criteres);
  }

  /**
   * Trouve les zones avec risque sismique
   */
  static async getZonesAvecRisqueSeisme(): Promise<ZoneClimatique[]> {
    const criteres: CriteresRecherche = { risqueSeisme: true };
    return await this.rechercherZones(criteres);
  }

  /**
   * Trouve les zones avec corrosion marine
   */
  static async getZonesAvecCorrosionMarine(): Promise<ZoneClimatique[]> {
    const criteres: CriteresRecherche = { corrosionMarine: true };
    return await this.rechercherZones(criteres);
  }

  /**
   * Recherche textuelle dans nom et description
   */
  static async rechercherTexte(texte: string): Promise<ZoneClimatique[]> {
    const criteres: CriteresRecherche = { texte };
    return await this.rechercherZones(criteres);
  }

  /**
   * Trouve la zone la plus adaptée selon critères météo
   */
  static async getMeilleureAdaptation(temperature: number, humidite: number, vents: number): Promise<ZoneClimatique | null> {
    const response = await ApiService.post<{ zone: ZoneClimatique | null }>(`${this.BASE_PATH}/zones-climatiques/meilleure-adaptation`, {
      temperature,
      humidite,
      vents
    });
    
    return response.zone;
  }

  /**
   * Récupère les statistiques des zones climatiques
   */
  static async getStatistiquesZones(): Promise<StatistiquesZones> {
    const response = await ApiService.get<StatistiquesZones>(`${this.BASE_PATH}/zones-climatiques/statistiques`);
    return response;
  }

  /**
   * Zones ordonnées par sévérité climatique
   */
  static async getZonesParSeverite(): Promise<ZoneClimatique[]> {
    const response = await ApiService.get<ZoneClimatique[]>(`${this.BASE_PATH}/zones-climatiques/par-severite`);
    return response;
  }

  /**
   * Valide si un matériau est adapté à une zone
   */
  static async validerMaterielPourZone(zoneCode: string, materiel: MaterielBTP): Promise<{
    adapte: boolean;
    score: number;
    avertissements: string[];
    recommandations: string[];
  }> {
    const response = await ApiService.post<{
      adapte: boolean;
      score: number;
      avertissements: string[];
      recommandations: string[];
    }>(`${this.BASE_PATH}/zones-climatiques/${zoneCode}/valider-materiel`, {
      materielCode: materiel.code
    });
    
    return response;
  }

  /**
   * Récupère les recommandations de construction pour une zone
   */
  static async getRecommandationsConstruction(zoneCode: string): Promise<{
    fondations: string[];
    structure: string[];
    enveloppe: string[];
    finitions: string[];
    equipements: string[];
  }> {
    const response = await ApiService.get<{
      fondations: string[];
      structure: string[];
      enveloppe: string[];
      finitions: string[];
      equipements: string[];
    }>(`${this.BASE_PATH}/zones-climatiques/${zoneCode}/recommandations`);
    
    return response;
  }

  /**
   * Calcule les coefficients de majoration pour une zone
   */
  static async getCoefficientsZone(zoneCode: string): Promise<{
    coefficient_vent: number;
    coefficient_seisme: number;
    coefficient_humidite: number;
    coefficient_temperature: number;
    coefficient_global: number;
  }> {
    const response = await ApiService.get<{
      coefficient_vent: number;
      coefficient_seisme: number;
      coefficient_humidite: number;
      coefficient_temperature: number;
      coefficient_global: number;
    }>(`${this.BASE_PATH}/zones-climatiques/${zoneCode}/coefficients`);
    
    return response;
  }

  /**
   * Récupère les contraintes spécifiques d'une zone
   */
  static async getContraintesZone(zoneCode: string): Promise<ContrainteConstruction[]> {
    const response = await ApiService.get<{ contraintes: ContrainteConstruction[] }>(`${this.BASE_PATH}/zones-climatiques/${zoneCode}/contraintes`);
    return response.contraintes;
  }

  /**
   * Récupère les saisons climatiques d'une zone
   */
  static async getSaisonsZone(zoneCode: string): Promise<SaisonClimatique[]> {
    const response = await ApiService.get<{ saisons: SaisonClimatique[] }>(`${this.BASE_PATH}/zones-climatiques/${zoneCode}/saisons`);
    return response.saisons;
  }

  /**
   * Simulation impact climatique sur construction
   */
  static async simulerImpactClimatique(zoneCode: string, parametres: {
    typeConstruction: string;
    materiauxPrincipaux: string[];
    dureeVie: number;
  }): Promise<{
    risqueGlobal: 'FAIBLE' | 'MOYEN' | 'ELEVE' | 'CRITIQUE';
    impactTemperature: number;
    impactHumidite: number;
    impactVent: number;
    impactSeisme: number;
    recommandationsUrgentes: string[];
    coutSupplementaire: number;
  }> {
    const response = await ApiService.post<{
      risqueGlobal: 'FAIBLE' | 'MOYEN' | 'ELEVE' | 'CRITIQUE';
      impactTemperature: number;
      impactHumidite: number;
      impactVent: number;
      impactSeisme: number;
      recommandationsUrgentes: string[];
      coutSupplementaire: number;
    }>(`${this.BASE_PATH}/zones-climatiques/${zoneCode}/simulation-impact`, parametres);
    
    return response;
  }

  /**
   * Comparaison entre zones climatiques
   */
  static async comparerZones(codes: string[]): Promise<{
    zones: ZoneClimatique[];
    comparaison: {
      plus_chaude: string;
      plus_humide: string;
      plus_ventee: string;
      plus_contraignante: string;
      recommandation: string;
    };
  }> {
    const response = await ApiService.post<{
      zones: ZoneClimatique[];
      comparaison: {
        plus_chaude: string;
        plus_humide: string;
        plus_ventee: string;
        plus_contraignante: string;
        recommandation: string;
      };
    }>(`${this.BASE_PATH}/zones-climatiques/comparer`, { codes });
    
    return response;
  }

  /**
   * Export des zones climatiques
   */
  static async exporterZones(format: 'CSV' | 'EXCEL' | 'PDF'): Promise<Blob> {
    const response = await ApiService.post<Blob>(
      `${this.BASE_PATH}/zones-climatiques/export`, 
      { format },
      { responseType: 'blob' }
    );
    
    return response;
  }
}