import { getEntriesHardcore, NonEmptyArray } from '../typescript-tools'
import { EtapesStatuts, EtapeStatut, EtapeStatutId, ETAPES_STATUTS } from './etapesStatuts'
import { ETAPES_TYPES, EtapeTypeId } from './etapesTypes'

export interface EtapeTypeEtapeStatut<T extends EtapeTypeId, R extends EtapeStatutId> {
  etapeStatutId: R
  etapeTypeId: T
}

export const EtapesTypesEtapesStatuts = {
  avisDesServicesEtCommissionsConsultatives: {
    FAIT: { etapeTypeId: 'asc', etapeStatutId: 'fai' },
  },

  abrogationDeLaDecision: { FAIT: { etapeTypeId: 'abd', etapeStatutId: 'fai' } },

  avisDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_: {
    FAVORABLE: { etapeTypeId: 'aca', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'aca', etapeStatutId: 'def' },
    AJOURNE: { etapeTypeId: 'aca', etapeStatutId: 'ajo' },
  },

  avisDesCollectivites: {
    FAIT: { etapeStatutId: 'fai', etapeTypeId: 'adc' },
  },
  avenantALautorisationDeRechercheMiniere: { FAIT: { etapeTypeId: 'aco', etapeStatutId: 'fai' } },
  decisionDuJugeAdministratif: {
    FAIT: { etapeTypeId: 'and', etapeStatutId: 'fai' },
    ACCEPTE: { etapeTypeId: 'and', etapeStatutId: 'acc' },
    REJETE: { etapeTypeId: 'and', etapeStatutId: 'rej' },
  },
  avisDeMiseEnConcurrenceAuJORF: {
    PROGRAMME: { etapeTypeId: 'anf', etapeStatutId: 'pro' },
    EN_COURS: { etapeTypeId: 'anf', etapeStatutId: 'enc' },
    TERMINE: { etapeTypeId: 'anf', etapeStatutId: 'ter' },
  },
  resultatMiseEnConcurrence: {
    ACCEPTE: { etapeTypeId: 'rmc', etapeStatutId: 'acc' },
    REJETE: { etapeTypeId: 'rmc', etapeStatutId: 'rej' },
  },

  rapportEtAvisDeLaDREAL: {
    FAVORABLE: { etapeTypeId: 'apd', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'apd', etapeStatutId: 'def' },
    FAVORABLE_AVEC_RESERVE: { etapeTypeId: 'apd', etapeStatutId: 'fre' },
    DEFAVORABLE_AVEC_RESERVES: { etapeTypeId: 'apd', etapeStatutId: 'dre' },
  },
  avisDuConseilDEtat: {
    FAVORABLE: { etapeTypeId: 'ape', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'ape', etapeStatutId: 'def' },
    FAVORABLE_AVEC_RESERVE: { etapeTypeId: 'ape', etapeStatutId: 'fre' },
    DEFAVORABLE_AVEC_RESERVES: { etapeTypeId: 'ape', etapeStatutId: 'dre' },
  },

  avisDeLaCommissionDepartementaleDesMines_CDM_: {
    FAIT: { etapeStatutId: 'fai', etapeTypeId: 'apo' },
    AJOURNE: { etapeTypeId: 'apo', etapeStatutId: 'ajo' },
    FAVORABLE: { etapeTypeId: 'apo', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'apo', etapeStatutId: 'def' },
    FAVORABLE_AVEC_RESERVE: { etapeTypeId: 'apo', etapeStatutId: 'fre' },
    DEFAVORABLE_AVEC_RESERVES: { etapeTypeId: 'apo', etapeStatutId: 'dre' },
  },
  avisDuPrefet: {
    FAVORABLE: { etapeTypeId: 'app', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'app', etapeStatutId: 'def' },
    FAVORABLE_AVEC_RESERVE: { etapeTypeId: 'app', etapeStatutId: 'fre' },
    DEFAVORABLE_AVEC_RESERVES: { etapeTypeId: 'app', etapeStatutId: 'dre' },
  },
  publicationDeLavisDeDecisionImplicite: {
    FAIT: { etapeTypeId: 'apu', etapeStatutId: 'fai' },
    ACCEPTE: { etapeTypeId: 'apu', etapeStatutId: 'acc' },
    REJETE: { etapeTypeId: 'apu', etapeStatutId: 'rej' },
  },
  consultationDesAdministrationsCentrales: { FAIT: { etapeTypeId: 'cac', etapeStatutId: 'fai' } },
  classementSansSuite: { FAIT: { etapeTypeId: 'css', etapeStatutId: 'fai' } },
  decisionDeLaMissionAutoriteEnvironnementale_ExamenAuCasParCasDuProjet_: {
    EXEMPTE: { etapeTypeId: 'dae', etapeStatutId: 'exe' },
    REQUIS: { etapeTypeId: 'dae', etapeStatutId: 'req' },
  },
  decisionDeLOfficeNationalDesForets: {
    ACCEPTE: { etapeTypeId: 'def', etapeStatutId: 'acc' },
    REJETE: { etapeTypeId: 'def', etapeStatutId: 'rej' },
  },
  desistementDuDemandeur: { FAIT: { etapeTypeId: 'des', etapeStatutId: 'fai' } },
  decisionDeLAutoriteAdministrative: {
    ACCEPTE_DECISION_IMPLICITE: { etapeTypeId: 'dex', etapeStatutId: 'aci' },
    ACCEPTE: { etapeTypeId: 'dex', etapeStatutId: 'acc' },
    REJETE: { etapeTypeId: 'dex', etapeStatutId: 'rej' },
    REJETE_DECISION_IMPLICITE: { etapeTypeId: 'dex', etapeStatutId: 'rei' },
  },
  publicationDeDecisionAuJORF: {
    ACCEPTE: { etapeTypeId: 'dpu', etapeStatutId: 'acc' },
    REJETE: { etapeTypeId: 'dpu', etapeStatutId: 'rej' },
    FAIT: { etapeTypeId: 'dpu', etapeStatutId: 'fai' },
  },
  expertises: {
    FAVORABLE: { etapeTypeId: 'exp', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'exp', etapeStatutId: 'def' },
  },
  enquetePublique: {
    PROGRAMME: { etapeTypeId: 'epu', etapeStatutId: 'pro' },
    EN_COURS: { etapeTypeId: 'epu', etapeStatutId: 'enc' },
    TERMINE: { etapeTypeId: 'epu', etapeStatutId: 'ter' },
  },
  informationsHistoriquesIncompletes: { FAIT: { etapeTypeId: 'ihi', etapeStatutId: 'fai' } },
  demandeDeComplements_RecevabiliteDeLaDemande_: { FAIT: { etapeTypeId: 'mca', etapeStatutId: 'fai' } },
  demandeDeComplements_RecepisseDeDeclarationLoiSurLeau_: { FAIT: { etapeTypeId: 'mcb', etapeStatutId: 'fai' } },
  demandeDeComplements_DecisionDeLaMissionAutoriteEnvironnementale_ExamenAuCasParCasDuProjet_: { FAIT: { etapeTypeId: 'mcd', etapeStatutId: 'fai' } },
  demandeDeComplements_CompletudeDeLaDemande_: { FAIT: { etapeTypeId: 'mcm', etapeStatutId: 'fai' } },
  demandeDeComplements: { FAIT: { etapeTypeId: 'mco', etapeStatutId: 'fai' } },
  completudeDeLaDemande: {
    COMPLETE: { etapeTypeId: 'mcp', etapeStatutId: 'com' },
    INCOMPLETE: { etapeTypeId: 'mcp', etapeStatutId: 'inc' },
  },
  recevabiliteDeLaDemande: {
    FAVORABLE: { etapeTypeId: 'mcr', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'mcr', etapeStatutId: 'def' },
  },
  declarationDIrrecevabilite: {
    FAIT: { etapeTypeId: 'mci', etapeStatutId: 'fai' },
  },
  demandeDeComplements_SaisineDeLaCARM_: { FAIT: { etapeTypeId: 'mcs', etapeStatutId: 'fai' } },
  avisDeDemandeConcurrente: { FAIT: { etapeTypeId: 'mec', etapeStatutId: 'fai' } },
  enregistrementDeLaDemande: { FAIT: { etapeTypeId: 'men', etapeStatutId: 'fai' } },
  priseEnChargeParLOfficeNationalDesForets: { FAIT: { etapeTypeId: 'meo', etapeStatutId: 'fai' } },
  demande: {
    FAIT: { etapeTypeId: 'mfr', etapeStatutId: 'fai' },
  },
  demandeDinformations_AvisDuDREALDEALOuDGTM_: { FAIT: { etapeTypeId: 'mie', etapeStatutId: 'fai' } },
  demandeDinformations: { FAIT: { etapeTypeId: 'mif', etapeStatutId: 'fai' } },
  demandeDinformations_RecevabiliteDeLaDemande_: { FAIT: { etapeTypeId: 'mim', etapeStatutId: 'fai' } },
  notificationAuDemandeur_AjournementDeLaCARM_: { FAIT: { etapeTypeId: 'mna', etapeStatutId: 'fai' } },
  notificationAuDemandeur_AvisFavorableDeLaCARM_: { FAIT: { etapeTypeId: 'mnb', etapeStatutId: 'fai' } },
  notificationAuDemandeur_ClassementSansSuite_: { FAIT: { etapeTypeId: 'mnc', etapeStatutId: 'fai' } },
  notificationAuDemandeur_AvisDefavorable_: { FAIT: { etapeTypeId: 'mnd', etapeStatutId: 'fai' } },
  notificationAuDemandeur_InitiationDeLaDemarcheDeRetrait_: { FAIT: { etapeTypeId: 'mni', etapeStatutId: 'fai' } },
  notificationAuDemandeur: { FAIT: { etapeTypeId: 'mno', etapeStatutId: 'fai' } },
  notificationAuDemandeur_SignatureDeLautorisationDeRechercheMiniere_: { FAIT: { etapeTypeId: 'mns', etapeStatutId: 'fai' } },
  notificationAuDemandeur_SignatureDeLavenantALautorisationDeRechercheMiniere_: { FAIT: { etapeTypeId: 'mnv', etapeStatutId: 'fai' } },
  modificationDeLaDemande: { FAIT: { etapeTypeId: 'mod', etapeStatutId: 'fai' } },
  notificationDesCollectivitesLocales: { FAIT: { etapeTypeId: 'ncl', etapeStatutId: 'fai' } },
  paiementDesFraisDeDossierComplementaires: { FAIT: { etapeTypeId: 'pfc', etapeStatutId: 'fai' } },
  paiementDesFraisDeDossier: { FAIT: { etapeTypeId: 'pfd', etapeStatutId: 'fai' } },
  consultationDuPublic: {
    PROGRAMME: { etapeTypeId: 'ppu', etapeStatutId: 'pro' },
    EN_COURS: { etapeTypeId: 'ppu', etapeStatutId: 'enc' },
    TERMINE: { etapeTypeId: 'ppu', etapeStatutId: 'ter' },
  },
  publicationDansUnJournalLocalOuNational: { FAIT: { etapeTypeId: 'pqr', etapeStatutId: 'fai' } },
  receptionDeComplements_RecevabiliteDeLaDemande_: { FAIT: { etapeTypeId: 'rca', etapeStatutId: 'fai' } },
  receptionDeComplements_RecepisseDeDeclarationLoiSurLeau_: { FAIT: { etapeTypeId: 'rcb', etapeStatutId: 'fai' } },
  receptionDeComplements_DecisionDeLaMissionAutoriteEnvironnementale_ExamenAuCasParCasDuProjet__: { FAIT: { etapeTypeId: 'rcd', etapeStatutId: 'fai' } },
  receptionDeComplements_CompletudeDeLaDemande_: { FAIT: { etapeTypeId: 'rcm', etapeStatutId: 'fai' } },
  receptionDeComplements: { FAIT: { etapeTypeId: 'rco', etapeStatutId: 'fai' } },
  receptionDeComplements_SaisineDeLaCARM_: { FAIT: { etapeTypeId: 'rcs', etapeStatutId: 'fai' } },
  recepisseDeDeclarationLoiSurLeau: {
    FAVORABLE: { etapeTypeId: 'rde', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'rde', etapeStatutId: 'def' },
  },
  receptionDinformation: { FAIT: { etapeTypeId: 'rif', etapeStatutId: 'fai' } },
  rapportDuConseilDEtat: {
    FAVORABLE: { etapeTypeId: 'rpe', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'rpe', etapeStatutId: 'def' },
  },
  publicationDeDecisionAuRecueilDesActesAdministratifs: { FAIT: { etapeTypeId: 'rpu', etapeStatutId: 'fai' } },
  mesuresDePublicite: { FAIT: { etapeTypeId: 'mpb', etapeStatutId: 'fai' } },
  saisineDeLautoriteSignataire: { FAIT: { etapeTypeId: 'sas', etapeStatutId: 'fai' } },
  saisineDeLaCommissionDesAutorisationsDeRecherchesMinieres_CARM_: { FAIT: { etapeTypeId: 'sca', etapeStatutId: 'fai' } },
  saisinesEtAvisCGE_AE: { FAIT: { etapeTypeId: 'scg', etapeStatutId: 'fai' } },
  signatureDeLautorisationDeRechercheMiniere: { FAIT: { etapeTypeId: 'sco', etapeStatutId: 'fai' } },
  saisineDuConseilDEtat: { FAIT: { etapeTypeId: 'spe', etapeStatutId: 'fai' } },
  saisineDeLaCommissionDepartementaleDesMines_CDM_: { FAIT: { etapeTypeId: 'spo', etapeStatutId: 'fai' } },
  saisineDuPrefet: { FAIT: { etapeTypeId: 'spp', etapeStatutId: 'fai' } },
  validationDuPaiementDesFraisDeDossierComplementaires: { FAIT: { etapeTypeId: 'vfc', etapeStatutId: 'fai' } },
  validationDuPaiementDesFraisDeDossier: { FAIT: { etapeTypeId: 'vfd', etapeStatutId: 'fai' } },
  avisDeLautoriteEnvironnementale: {
    FAVORABLE: { etapeTypeId: 'wae', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'wae', etapeStatutId: 'def' },
  },
  arreteDouvertureDesTravauxMiniers: { FAIT: { etapeTypeId: 'wao', etapeStatutId: 'fai' } },
  avisDeReception: { FAIT: { etapeTypeId: 'war', etapeStatutId: 'fai' } },
  avisDuDemandeurSurLesPrescriptionsProposees: {
    FAVORABLE: { etapeTypeId: 'wau', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'wau', etapeStatutId: 'def' },
  },
  donneActeDeLaDeclaration_DOTM_: { FAIT: { etapeTypeId: 'wda', etapeStatutId: 'fai' } },
  demandeDeComplements_AOTMOuDOTM_: { FAIT: { etapeTypeId: 'wdc', etapeStatutId: 'fai' } },
  depotDeLaDemande_wdd: { FAIT: { etapeTypeId: 'wdd', etapeStatutId: 'fai' } },
  demandeDeComplements_DADT_: { FAIT: { etapeTypeId: 'wde', etapeStatutId: 'fai' } },
  demandeDautorisationDouvertureDeTravauxMiniers_AOTM_: { FAIT: { etapeTypeId: 'wfa', etapeStatutId: 'fai' } },
  declarationDarretDefinitifDeTravaux_DADT_: { FAIT: { etapeTypeId: 'wfd', etapeStatutId: 'fai' } },
  declarationDouvertureDeTravauxMiniers_DOTM_: { FAIT: { etapeTypeId: 'wfo', etapeStatutId: 'fai' } },
  memoireDeFinDeTravaux: { FAIT: { etapeTypeId: 'wmt', etapeStatutId: 'fai' } },
  porterAConnaissance: { FAIT: { etapeTypeId: 'wpb', etapeStatutId: 'fai' } },
  arreteDePrescriptionsComplementaires: { FAIT: { etapeTypeId: 'wpc', etapeStatutId: 'fai' } },
  arreteDeSecondDonnerActe: { ACCEPTE: { etapeTypeId: 'wpo', etapeStatutId: 'acc' } },
  arretePrefectoralDePremierDonnerActe_DADT_: { FAIT: { etapeTypeId: 'wpp', etapeStatutId: 'fai' } },
  arretePrefectoralDeSursisAStatuer: { FAIT: { etapeTypeId: 'wps', etapeStatutId: 'fai' } },
  receptionDeComplements_wrc: { FAIT: { etapeTypeId: 'wrc', etapeStatutId: 'fai' } },
  recolement: {
    FAVORABLE: { etapeTypeId: 'wrt', etapeStatutId: 'fav' },
    DEFAVORABLE: { etapeTypeId: 'wrt', etapeStatutId: 'def' },
  },
  saisineDeLautoriteEnvironnementale: { FAIT: { etapeTypeId: 'wse', etapeStatutId: 'fai' } },
  transmissionDuProjetDePrescriptionsAuDemandeur: { FAIT: { etapeTypeId: 'wtp', etapeStatutId: 'fai' } },
  attestationDeConstitutionDeGarantiesFinancieres: { FAIT: { etapeTypeId: 'acf', etapeStatutId: 'fai' } },
  reponseDuDemandeur: { FAIT: { etapeTypeId: 'rno', etapeStatutId: 'fai' } },
  demandeDeModificationAES: { FAIT: { etapeStatutId: 'fai', etapeTypeId: 'dma' } },
  demandeDeConsentement: { FAIT: { etapeTypeId: 'ddc', etapeStatutId: 'fai' } },
  informationDuPrefetEtDesCollectivites: { FAIT: { etapeTypeId: 'ipc', etapeStatutId: 'fai' } },
} as const satisfies { [key in keyof typeof ETAPES_TYPES]: { [other in keyof typeof ETAPES_STATUTS]?: EtapeTypeEtapeStatut<(typeof ETAPES_TYPES)[key], (typeof ETAPES_STATUTS)[other]> } }

type GetStuff<T> = T extends { [key in keyof typeof ETAPES_TYPES]: { [other in keyof typeof ETAPES_STATUTS]?: infer A } } ? A : never

export type EtapeTypeEtapeStatutValidPair = GetStuff<typeof EtapesTypesEtapesStatuts>

const etapesTypeEntries = getEntriesHardcore(ETAPES_TYPES)
export const getEtapesStatuts = (etapeTypeIdToFind: EtapeTypeId): NonEmptyArray<EtapeStatut> => {
  const entry = etapesTypeEntries.find(([_key, value]) => value === etapeTypeIdToFind)
  if (!entry) {
    throw new Error("Cas impossible, cet etapeTypeId n'existe pas")
  }
  const etapesTypesEtapesStatutsKey = entry[0]
  const tuple = EtapesTypesEtapesStatuts[etapesTypesEtapesStatutsKey]

  return Object.values(tuple).map(({ etapeStatutId }: { etapeStatutId: EtapeStatutId }) => EtapesStatuts[etapeStatutId]) as NonEmptyArray<EtapeStatut>
}
