import { isProcedureOuverte, MachineInfo } from './machines'
import { AvisTypeId, AVIS_TYPES, isAvisTypeId } from './static/avisTypes'
import { CommuneId } from './static/communes'
import { toDepartementId, DEPARTEMENT_IDS } from './static/departement'
import { ETAPES_TYPES, EtapeTypeId } from './static/etapesTypes'
import { IsArmMecanise, IS_ARM_NON_MECANISE } from './static/mecanise'
import { TITRES_TYPES_IDS, TitresTypes } from './static/titresTypes'
import { TITRES_TYPES_TYPES_IDS } from './static/titresTypesTypes'
import { isNotNullNorUndefined } from './typescript-tools'

type GetAvisType = Partial<{ [key in AvisTypeId]: { id: key; optionnel: boolean } }>
export const getAvisTypes = (etapeTypeId: EtapeTypeId, machineInfo: MachineInfo, communeIds: CommuneId[], isArmMecanise: IsArmMecanise): GetAvisType => {
  const avis: GetAvisType = {}

  if (etapeTypeId === ETAPES_TYPES.demande) {
    if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_D_EXPLOITATION_METAUX) {
      avis[AVIS_TYPES.avisProprietaireDuSol] = { id: AVIS_TYPES.avisProprietaireDuSol, optionnel: false }
      avis[AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale] = { id: AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale, optionnel: false }
    } else if (machineInfo.titreTypeId === TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX && machineInfo.machineId === 'ProcedureSpecifique') {
      avis[AVIS_TYPES.avisCasParCas] = { id: AVIS_TYPES.avisCasParCas, optionnel: isArmMecanise === IS_ARM_NON_MECANISE }
      avis[AVIS_TYPES.avisProprietaireDuSol] = { id: AVIS_TYPES.avisProprietaireDuSol, optionnel: false }
    }
  }

  if (etapeTypeId === ETAPES_TYPES.avisDesCollectivites) {
    avis[AVIS_TYPES.avisDUneCollectivite] = { id: AVIS_TYPES.avisDUneCollectivite, optionnel: true }
  } else if (etapeTypeId === ETAPES_TYPES.avisDesServicesEtCommissionsConsultatives) {
    avis[AVIS_TYPES.avisDirectionRegionaleDesAffairesCulturelles] = { id: AVIS_TYPES.avisDirectionRegionaleDesAffairesCulturelles, optionnel: true }
    avis[AVIS_TYPES.avisConseilDepartementalEnvironnementRisquesSanitairesTechnologiques] = { id: AVIS_TYPES.avisConseilDepartementalEnvironnementRisquesSanitairesTechnologiques, optionnel: true }
    avis[AVIS_TYPES.avisDirectionsRégionalesEconomieEmploiTravailSolidarités] = { id: AVIS_TYPES.avisDirectionsRégionalesEconomieEmploiTravailSolidarités, optionnel: true }
    avis[AVIS_TYPES.avisDirectionRegionaleFinancesPubliques] = { id: AVIS_TYPES.avisDirectionRegionaleFinancesPubliques, optionnel: true }
    avis[AVIS_TYPES.avisGendarmerieNationale] = { id: AVIS_TYPES.avisGendarmerieNationale, optionnel: true }
    avis[AVIS_TYPES.avisIFREMER] = { id: AVIS_TYPES.avisIFREMER, optionnel: true }
    avis[AVIS_TYPES.avisInstitutNationalOrigineQualite] = { id: AVIS_TYPES.avisInstitutNationalOrigineQualite, optionnel: true }
    avis[AVIS_TYPES.avisServiceAdministratifLocal] = { id: AVIS_TYPES.avisServiceAdministratifLocal, optionnel: true }
    avis[AVIS_TYPES.avisAutoriteMilitaire] = { id: AVIS_TYPES.avisAutoriteMilitaire, optionnel: true }
    avis[AVIS_TYPES.avisParcNational] = { id: AVIS_TYPES.avisParcNational, optionnel: true }
    avis[AVIS_TYPES.avisDirectionDepartementaleTerritoiresMer] = { id: AVIS_TYPES.avisDirectionDepartementaleTerritoiresMer, optionnel: true }
    avis[AVIS_TYPES.avisAgenceRegionaleSante] = { id: AVIS_TYPES.avisAgenceRegionaleSante, optionnel: true }
    avis[AVIS_TYPES.avisCaisseGeneraleSecuriteSociale] = { id: AVIS_TYPES.avisCaisseGeneraleSecuriteSociale, optionnel: true }
    avis[AVIS_TYPES.autreAvis] = { id: AVIS_TYPES.autreAvis, optionnel: true }
    // L'avis de l'onf est obligatoire que pour les ARM
    avis[AVIS_TYPES.avisOfficeNationalDesForets] = { id: AVIS_TYPES.avisOfficeNationalDesForets, optionnel: machineInfo.machineId === 'ProcedureSpecifique' || machineInfo.titreTypeId !== 'arm' }
    avis[AVIS_TYPES.expertiseOfficeNationalDesForets] = { id: AVIS_TYPES.expertiseOfficeNationalDesForets, optionnel: true }
    // TODO 2024-05-14: rendre obligatoire pour les PNMs quand ces derniers seront implémentés
    avis[AVIS_TYPES.avisParcNaturelMarin] = { id: AVIS_TYPES.avisParcNaturelMarin, optionnel: true }

    if (communeIds.some(id => toDepartementId(id) === DEPARTEMENT_IDS.Guyane)) {
      avis[AVIS_TYPES.avisDirectionAlimentationAgricultureForet] = { id: AVIS_TYPES.avisDirectionAlimentationAgricultureForet, optionnel: true }
      avis[AVIS_TYPES.avisEtatMajorOrpaillagePecheIllicite] = { id: AVIS_TYPES.avisEtatMajorOrpaillagePecheIllicite, optionnel: true }
    }

    // TODO 2024-06-18 Normalement c'est obligatoire si avis propriétaire du sol est favorable avec réserve,  optionnel pour le moment
    if (TitresTypes[machineInfo.titreTypeId].typeId === TITRES_TYPES_TYPES_IDS.AUTORISATION_D_EXPLOITATION) {
      avis[AVIS_TYPES.confirmationAccordProprietaireDuSol] = { id: AVIS_TYPES.confirmationAccordProprietaireDuSol, optionnel: true }
    }
  } else if (etapeTypeId === ETAPES_TYPES.saisinesEtAvisCGE_AE) {
    avis[AVIS_TYPES.avisDuConseilGeneralDeLEconomie] = { id: AVIS_TYPES.avisDuConseilGeneralDeLEconomie, optionnel: machineInfo.machineId !== 'ProcedureSpecifique' }
    avis[AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale] = { id: AVIS_TYPES.avisDeLaMissionAutoriteEnvironnementale, optionnel: machineInfo.machineId !== 'ProcedureSpecifique' }
    avis[AVIS_TYPES.autreAvis] = { id: AVIS_TYPES.autreAvis, optionnel: true }
  } else if ([ETAPES_TYPES.consultationDesAdministrationsCentrales, ETAPES_TYPES.expertises].includes(etapeTypeId)) {
    avis[AVIS_TYPES.autreAvis] = { id: AVIS_TYPES.autreAvis, optionnel: true }
  }

  if (isProcedureOuverte(machineInfo.machineId)) {
    for (const avisType in avis) {
      if (isAvisTypeId(avisType) && isNotNullNorUndefined(avis[avisType])) {
        avis[avisType].optionnel = true
      }
    }
  }

  return avis
}
