import { Pool } from 'pg'
import { CaminoRequest, CustomResponse } from '../express-type'
import { StatistiquesDataGouv, indicateurByAdministrationId } from 'camino-common/src/statistiques'
import { getUtilisateursStats } from './datagouv.queries'
import { isEntrepriseOrBureauDetudeRole } from 'camino-common/src/roles'
import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools'
import { Administrations } from 'camino-common/src/static/administrations'
import { CaminoStatistiquesDataGouv, CaminoStatistiquesDataGouvId } from 'camino-common/src/static/statistiques'
import { getCurrent } from 'camino-common/src/date'
import xlsx from 'xlsx'
import { contentTypes } from 'camino-common/src/rest'

const commonIndicateurValues: Pick<
  StatistiquesDataGouv,
  'administration_rattachement' | 'nom_service_public_numerique' | 'est_cible' | 'est_periode' | 'est_automatise' | 'source_collecte' | 'code_insee'
> = {
  administration_rattachement: 'DGALN',
  nom_service_public_numerique: 'CAMINO',
  est_cible: false,
  est_periode: true,
  est_automatise: true,
  source_collecte: 'script',
  code_insee: '',
}

export const getDataGouvStats =
  (pool: Pool) =>
  async (req: CaminoRequest, res: CustomResponse<StatistiquesDataGouv[]>): Promise<void> => {
    try {
      const result: StatistiquesDataGouv[] = []

      const utilisateursInDb = await getUtilisateursStats(pool)

      const utilisateurs: Record<CaminoStatistiquesDataGouvId, number> = utilisateursInDb.reduce<Record<CaminoStatistiquesDataGouvId, number>>(
        (previousValue, user) => {
          if (isNotNullNorUndefined(user.administration_id)) {
            const administrationTypeId = Administrations[user.administration_id].typeId
            if (administrationTypeId !== 'ope') {
              previousValue[indicateurByAdministrationId[administrationTypeId]]++
            } else {
              previousValue["Nombre d'utilisateurs sur la plateforme"]++
            }
          } else if (isEntrepriseOrBureauDetudeRole(user.role)) {
            previousValue["Nombre d'utilisateurs affiliés à une entreprise"]++
          } else {
            previousValue["Nombre d'utilisateurs sur la plateforme"]++
          }

          return previousValue
        },
        {
          "Nombre d'utilisateurs rattachés à une Autorité": 0,
          "Nombre d'utilisateurs rattachés à une Dréal": 0,
          "Nombre d'utilisateurs rattachés à un ministère": 0,
          "Nombre d'utilisateurs rattachés à une préfecture": 0,
          "Nombre d'utilisateurs affiliés à une entreprise": 0,
          "Nombre d'utilisateurs sur la plateforme": 0,
        }
      )

      for (const stat of Object.values(CaminoStatistiquesDataGouv)) {
        const indicateur = stat.indicateur

        result.push({ ...stat, ...commonIndicateurValues, valeur: utilisateurs[indicateur], date: getCurrent() })
      }

      if (req.query.format === 'csv') {
        const sheet = xlsx.utils.json_to_sheet(result)
        const response = xlsx.utils.sheet_to_csv(sheet)

        res.header('Content-disposition', `inline; filename=camino_statistiques.csv`)
        res.header('Content-Type', contentTypes.csv)
        res.send(response)
      } else {
        res.json(result)
      }
    } catch (e) {
      console.error(e)

      throw e
    }
  }
