/* eslint-disable sql/no-unsafe-query */
import { restCall, restNewPutCall } from '../../../tests/_utils/index'
import { dbManager } from '../../../tests/db-manager'
import { test, describe, afterAll, beforeAll, vi, expect } from 'vitest'
import type { Pool } from 'pg'
import { toCaminoDate } from 'camino-common/src/date'
import { insertTitreGraph, ITitreInsert } from '../../../tests/integration-test-helper'
import { ETAPE_IS_NOT_BROUILLON } from 'camino-common/src/etape'
import { newTitreId, newDemarcheId, newEtapeId, idGenerate } from '../../database/models/_format/id-create'
import { TITRES_TYPES_IDS } from 'camino-common/src/static/titresTypes'
import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes'
import { DemarchesStatutsIds } from 'camino-common/src/static/demarchesStatuts'
import { TitresStatutIds } from 'camino-common/src/static/titresStatuts'
import { Knex } from 'knex'
import { ACTIVITES_TYPES_IDS } from 'camino-common/src/static/activitesTypes'
import { ACTIVITES_STATUTS_IDS } from 'camino-common/src/static/activitesStatuts'
import { ETAPES_TYPES } from 'camino-common/src/static/etapesTypes'
import { ETAPES_STATUTS } from 'camino-common/src/static/etapesStatuts'
import { Activite, activiteDocumentIdValidator, activiteIdValidator } from 'camino-common/src/activite'
import { userSuper } from '../../database/user-super'
import { DOCUMENTS_TYPES_IDS } from 'camino-common/src/static/documentsTypes'
import { copyFileSync, mkdirSync } from 'node:fs'
import { tempDocumentNameValidator } from 'camino-common/src/document'
import { SectionWithValue } from 'camino-common/src/sections'
import { newEntrepriseId } from 'camino-common/src/entreprise'
import { testBlankUser } from 'camino-common/src/tests-utils'
import { entrepriseUpsert } from '../../database/queries/entreprises'

const dir = `${process.cwd()}/files/tmp/`

console.info = vi.fn()
console.error = vi.fn()
let dbPool: Pool
let knex: Knex
beforeAll(async () => {
  const { knex: knexInstance, pool } = await dbManager.populateDb()
  dbPool = pool
  knex = knexInstance
})

afterAll(async () => {
  await dbManager.closeKnex()
})

describe('updateActivite', () => {
  test('met à jour une activité', async () => {
    const titreId = newTitreId('titre-id')
    const titre: ITitreInsert = {
      id: titreId,
      nom: 'mon titre',
      typeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX,
      titreStatutId: TitresStatutIds.Valide,
      publicLecture: true,
      propsTitreEtapesIds: { points: 'titre-id-demarche-id-dpu' },
      demarches: [
        {
          id: newDemarcheId('titre-id-demarche-id'),
          titreId: titreId,
          typeId: DEMARCHES_TYPES_IDS.Octroi,
          statutId: DemarchesStatutsIds.Accepte,
          publicLecture: true,
          machineId: null,
          etapes: [
            {
              id: newEtapeId('titre-id-demarche-id-dpu'),
              typeId: ETAPES_TYPES.publicationDeDecisionAuJORF,
              ordre: 0,
              titreDemarcheId: newDemarcheId('titre-id-demarche-id'),
              statutId: ETAPES_STATUTS.ACCEPTE,
              date: toCaminoDate('2020-02-02'),
              administrationsLocales: ['dea-guyane-01'],
              isBrouillon: ETAPE_IS_NOT_BROUILLON,
            },
          ],
        },
      ],
    }

    await insertTitreGraph(titre)

    const activiteId = activiteIdValidator.parse('activite1Id')
    await knex.raw(
      `INSERT INTO titres_activites (  id, titre_id, utilisateur_id, "date", date_saisie, contenu, type_id, activite_statut_id, annee, periode_id, sections, suppression, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?,?)`,
      [
        activiteId,
        titreId,
        null,
        toCaminoDate('2021-01-01'),
        null,
        null,
        ACTIVITES_TYPES_IDS["rapport trimestriel d'exploitation d'or en Guyane"],
        ACTIVITES_STATUTS_IDS.ABSENT,
        2023,
        1,
        [JSON.stringify({ id: 'id', elements: [{ id: 'element', type: 'number', optionnel: true }] })],
        false,
        'slug',
      ]
    )

    const activite1DocumentId = activiteDocumentIdValidator.parse('activiteDocumentId1')
    const activite2DocumentId = activiteDocumentIdValidator.parse('activiteDocumentId2')
    await knex.raw('INSERT INTO activites_documents(id,activite_document_type_id,"date",activite_id,description,largeobject_id) VALUES (?, ?,?,?,?,?), (?, ?,?,?,?,?)', [
      activite1DocumentId,
      DOCUMENTS_TYPES_IDS.rapportAnnuelDExploitation,
      toCaminoDate('2021-01-01'),
      activiteId,
      '',
      54300,
      activite2DocumentId,
      DOCUMENTS_TYPES_IDS.rapportAnnuelDExploitation,
      toCaminoDate('2023-01-01'),
      activiteId,
      '',
      54300,
    ])

    let tested = await restNewPutCall(dbPool, '/rest/activites/:activiteId', { activiteId: activiteId }, undefined, { sectionsWithValue: [], activiteDocumentIds: [], newTempDocuments: [] })

    expect(tested.body).toMatchInlineSnapshot(`
      {
        "message": "Accès interdit",
        "status": 403,
      }
    `)
    const fileName = `existing_temp_file_${idGenerate()}`
    mkdirSync(dir, { recursive: true })
    copyFileSync(`./src/tools/small.pdf`, `${dir}/${fileName}`)

    const sectionWithValue: SectionWithValue[] = [{ id: 'id', elements: [{ id: 'element', type: 'number', value: 12, optionnel: true }] }]
    tested = await restNewPutCall(dbPool, '/rest/activites/:activiteId', { activiteId: activiteId }, userSuper, {
      sectionsWithValue: sectionWithValue,
      activiteDocumentIds: [activite1DocumentId],
      newTempDocuments: [
        { activite_document_type_id: DOCUMENTS_TYPES_IDS.rapportEnvironnementalDExploration, description: 'Une jolie description', tempDocumentName: tempDocumentNameValidator.parse(fileName) },
      ],
    })

    expect(tested.body).toMatchInlineSnapshot(`
      {
        "id": "activite1Id",
      }
    `)

    tested = await restCall(dbPool, '/rest/activites/:activiteId', { activiteId }, userSuper)
    const activite: Activite = tested.body
    expect(activite.activite_statut_id).toStrictEqual(ACTIVITES_STATUTS_IDS.EN_CONSTRUCTION)
    expect(activite.sections_with_value).toStrictEqual(sectionWithValue)
    const newDocumentIds = activite.activite_documents.map(document => document.id)
    expect(newDocumentIds).not.toContain(activite2DocumentId)
    expect(newDocumentIds).toContain(activite1DocumentId)
    expect(activite.activite_documents).toHaveLength(2)
  })

  test('réinitialise une activité', async () => {
    const titreId = newTitreId('titre-id-reset-activite')
    const entrepriseId = newEntrepriseId('entrepriseid-reset-activite')
    await entrepriseUpsert({
      id: entrepriseId,
      nom: 'Mon Entreprise',
      archive: false,
    })
    const titre: ITitreInsert = {
      id: titreId,
      nom: 'mon titre',
      typeId: TITRES_TYPES_IDS.AUTORISATION_DE_RECHERCHE_METAUX,
      titreStatutId: TitresStatutIds.Valide,
      publicLecture: true,
      propsTitreEtapesIds: { points: 'titre-id-demarche-id-dpu-reset-activite', titulaires: 'titre-id-demarche-id-dpu-reset-activite' },
      demarches: [
        {
          id: newDemarcheId('titre-id-demarche-id-reset-activite'),
          titreId: titreId,
          typeId: DEMARCHES_TYPES_IDS.Octroi,
          statutId: DemarchesStatutsIds.Accepte,
          publicLecture: true,
          machineId: null,
          etapes: [
            {
              id: newEtapeId('titre-id-demarche-id-dpu-reset-activite'),
              typeId: ETAPES_TYPES.publicationDeDecisionAuJORF,
              ordre: 0,
              titreDemarcheId: newDemarcheId('titre-id-demarche-id-reset-activite'),
              statutId: ETAPES_STATUTS.ACCEPTE,
              date: toCaminoDate('2020-02-02'),
              titulaireIds: [entrepriseId],
              administrationsLocales: ['dea-guyane-01'],
              isBrouillon: ETAPE_IS_NOT_BROUILLON,
            },
          ],
        },
      ],
    }

    await insertTitreGraph(titre)

    const activiteId = activiteIdValidator.parse('activite1Id-reset')
    await knex.raw(
      `INSERT INTO titres_activites (  id, titre_id, utilisateur_id, "date", date_saisie, contenu, type_id, activite_statut_id, annee, periode_id, sections, suppression, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?,?)`,
      [
        activiteId,
        titreId,
        null,
        toCaminoDate('2021-01-01'),
        null,
        null,
        ACTIVITES_TYPES_IDS["rapport trimestriel d'exploitation d'or en Guyane"],
        ACTIVITES_STATUTS_IDS.DEPOSE,
        2023,
        1,
        [JSON.stringify({ id: 'id', elements: [{ id: 'element', type: 'number', optionnel: true }] })],
        false,
        'slug',
      ]
    )

    let tested = await restNewPutCall(dbPool, '/rest/activites/:activiteId/reset-depot', { activiteId: activiteId }, undefined, {})

    expect(tested.body).toMatchInlineSnapshot(`
        {
          "message": "Accès interdit",
          "status": 403,
        }
      `)

    tested = await restNewPutCall(dbPool, '/rest/activites/:activiteId/reset-depot', { activiteId: activiteId }, { ...testBlankUser, role: 'entreprise', entrepriseIds: [entrepriseId] }, {})

    expect(tested.body).toMatchInlineSnapshot(`
         {
           "message": "Droit insuffisants pour éditer l'activité",
           "status": 403,
         }
       `)
    tested = await restNewPutCall(dbPool, '/rest/activites/:activiteId/reset-depot', { activiteId: activiteId }, userSuper, {})
    expect(tested.body).toMatchInlineSnapshot(`
  {
    "id": "activite1Id-reset",
  }
`)
    tested = await restCall(dbPool, '/rest/activites/:activiteId', { activiteId }, userSuper)
    const activite: Activite = tested.body
    expect(activite.activite_statut_id).toStrictEqual(ACTIVITES_STATUTS_IDS.EN_CONSTRUCTION)
  })
})
