import { describe, expect, test } from 'vitest'
import { dateAddDays, firstEtapeDateValidator } from './date'
import { DATE_DEBUT_PROCEDURE_SPECIFIQUE, isMachineWithConsentement, isDemarcheIdException, MachineInfo, DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM } from './machines'
import { demarcheIdValidator } from './demarche'
import { DEMARCHES_TYPES_IDS } from './static/demarchesTypes'
import { TITRES_TYPES_IDS } from './static/titresTypes'

describe('MachineInfo', () => {
  test('MachineInfo.withDate() retourne une machine', () => {
    expect(
      MachineInfo.withDate(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('demarcheId'), firstEtapeDateValidator.parse('2023-06-07'))
        .machineId
    ).toStrictEqual('AncienLogigrammeOctroiPRM')
  })

  test('MachineInfo.withDate() ne retourne pas de machine quand la démarche fait partie des exceptions', () => {
    expect(
      MachineInfo.withDate(
        TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX,
        DEMARCHES_TYPES_IDS.Octroi,
        demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'),
        firstEtapeDateValidator.parse('2023-06-07')
      ).machineId
    ).toBe(undefined)
  })

  test('MachineInfo.withDate() fallback sur une autre machine quand elle est exclue', () => {
    expect(
      MachineInfo.withDate(
        TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX,
        DEMARCHES_TYPES_IDS.Octroi,
        demarcheIdValidator.parse('demarcheIdForUnitTests'),
        firstEtapeDateValidator.parse(dateAddDays(DATE_DEBUT_PROCEDURE_SPECIFIQUE_AXM_ARM, 20))
      ).machineId
    ).toBe('AncienLogigrammeOctroiARM')
  })

  test('MachineInfo.withDate() ne retourne pas de machine quand les étapes sont trop anciennes', () => {
    expect(
      MachineInfo.withDate(
        TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX,
        DEMARCHES_TYPES_IDS.Octroi,
        demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'),
        firstEtapeDateValidator.parse('2010-06-07')
      ).machineId
    ).toBe(undefined)
  })

  test(`MachineInfo.withDate() ne retourne pas de machine pour une prolongation d'Autorisation Recherche Métaux`, () => {
    expect(
      MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Prolongation, demarcheIdValidator.parse('Anything'), firstEtapeDateValidator.parse('2018-10-22'))
        .machineId
    ).toBe(undefined)
  })

  test('MachineInfo.withDate() retourne ProcedureSpecifique dès sa date de début', () => {
    const demarcheId = demarcheIdValidator.parse('Anything')
    const value = MachineInfo.withDate(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheId, firstEtapeDateValidator.parse(DATE_DEBUT_PROCEDURE_SPECIFIQUE))
    expect(value.machineId).toBe('ProcedureSpecifique')
    expect(value.demarcheId).toBe(demarcheId)
  })

  test('MachineInfo.withMachineId() retourne une machine', () => {
    const demarcheId = demarcheIdValidator.parse('Anything')
    const machineInfo = MachineInfo.withMachineId(TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Mutation, demarcheId, 'ProcedureSimplifiee')
    expect(machineInfo).toMatchInlineSnapshot(`
      {
        "valid": true,
        "value": MachineInfo {
          "_demarcheId": "Anything",
          "_demarcheTypeId": "mut",
          "_machineId": "ProcedureSimplifiee",
          "_titreTypeId": "cxg",
        },
      }
    `)
  })

  test('MachineInfo.withMachineId() ne retourne pas de machine si le machineId est null', () => {
    const machineInfo = MachineInfo.withMachineId(TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX, DEMARCHES_TYPES_IDS.AutorisationDOuvertureDeTravaux, demarcheIdValidator.parse('Anything'), null)
    expect(machineInfo).toMatchInlineSnapshot(`
      {
        "valid": true,
        "value": MachineInfo {
          "_demarcheId": "Anything",
          "_demarcheTypeId": "aom",
          "_machineId": undefined,
          "_titreTypeId": "arm",
        },
      }
    `)
  })
  test("MachineInfo.withMachineId() retourne une erreur en cas d'inconsistence", () => {
    expect(MachineInfo.withMachineId(TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Mutation, demarcheIdValidator.parse('Anything'), null)).toMatchInlineSnapshot(
      `
      {
        "error": "la machine n'est pas renseignée alors qu'il existe un logigramme potentiel : ProcedureSimplifiee",
        "valid": false,
      }
    `
    )

    expect(MachineInfo.withMachineId(TITRES_TYPES_IDS.CONCESSION_GEOTHERMIE, DEMARCHES_TYPES_IDS.Mutation, demarcheIdValidator.parse('Anything'), 'AncienLogigrammeOctroiPRM')).toMatchInlineSnapshot(`
      {
        "error": "INCONSISTENCE, aurait du être ProcedureSimplifiee mais est AncienLogigrammeOctroiPRM",
        "valid": false,
      }
    `)
  })
  test('MachineInfo.withMachineId() prend en compte les exceptions', () => {
    expect(MachineInfo.withMachineId(TITRES_TYPES_IDS.PERMIS_EXCLUSIF_DE_RECHERCHES_METAUX, DEMARCHES_TYPES_IDS.Octroi, demarcheIdValidator.parse('FfJTtP9EEfvf3VZy81hpF7ms'), null))
      .toMatchInlineSnapshot(`
      {
        "valid": true,
        "value": MachineInfo {
          "_demarcheId": "FfJTtP9EEfvf3VZy81hpF7ms",
          "_demarcheTypeId": "oct",
          "_machineId": undefined,
          "_titreTypeId": "prm",
        },
      }
    `)
  })
})
describe('isMachineWithConsentement', () => {
  test('procedure specifique', () => {
    expect(isMachineWithConsentement('ProcedureSpecifique')).toBe(true)
  })
  test('autre machines', () => {
    expect(isMachineWithConsentement('AncienLogigrammeOctroiARM')).toBe(false)
  })
})

test('isDemarcheIdException', () => {
  expect(isDemarcheIdException(demarcheIdValidator.parse('plop'))).toStrictEqual(false)
  expect(isDemarcheIdException(demarcheIdValidator.parse('VWBvpOx3n4dN7WCQoYUEC6vM'))).toStrictEqual(true)
})
