import { sql } from '@pgtyped/runtime'
import { EffectDbQueryAndValidateErrors, Redefine, effectDbQueryAndValidate } from '../../pg-database.js'
import { z } from 'zod'
import { Pool } from 'pg'
import { titreIdValidator } from 'camino-common/src/validators/titres.js'
import { Effect } from 'effect'
import { CaminoError } from 'camino-common/src/zod-tools.js'
import { IGetTitresByNomDbQuery, IGetTitresByReferenceDbQuery } from './quick-access.queries.types.js'
import { titreTypeIdValidator } from 'camino-common/src/static/titresTypes.js'
import { caminoDateValidator } from 'camino-common/src/date.js'

const titresByNomDbValidator = z.object({
  id: titreIdValidator,
  type_id: titreTypeIdValidator,
  nom: z.string(),
  public_lecture: z.boolean(),
  demarche_date_debut: caminoDateValidator.nullable(),
})
type TitreByNomDb = z.infer<typeof titresByNomDbValidator>

type GetTitresByNomErrors = EffectDbQueryAndValidateErrors
export const getTitresByReference = (pool: Pool, reference: string): Effect.Effect<TitreByNomDb[], CaminoError<GetTitresByNomErrors>> =>
  effectDbQueryAndValidate(getTitresByReferenceDb, { reference: `%${reference}%` }, pool, titresByNomDbValidator)

const getTitresByReferenceDb = sql<Redefine<IGetTitresByReferenceDbQuery, { reference: string }, TitreByNomDb>>`
SELECT
  t.id,
  t.type_id,
  t.nom,
  t.public_lecture,
  td.demarche_date_debut
FROM titres t
LEFT JOIN titres_demarches td ON td.titre_id = t.id AND td.ordre = 1 AND td.archive IS FALSE
WHERE t.archive IS FALSE AND EXISTS (SELECT 1 FROM jsonb_array_elements(t.references) titreRefs WHERE LOWER(titreRefs->>'nom') LIKE LOWER($reference!)) LIMIT 10
`

export const getTitresByNom = (pool: Pool, nom: string): Effect.Effect<TitreByNomDb[], CaminoError<GetTitresByNomErrors>> =>
  effectDbQueryAndValidate(getTitresByNomDb, { nom: `%${nom}%` }, pool, titresByNomDbValidator)

const getTitresByNomDb = sql<Redefine<IGetTitresByNomDbQuery, { nom: string }, TitreByNomDb>>`
SELECT
  t.id,
  t.type_id,
  t.nom,
  t.public_lecture,
  td.demarche_date_debut
FROM titres t
LEFT JOIN titres_demarches td ON td.titre_id = t.id and td.ordre = 1 AND td.archive IS FALSE
WHERE t.archive IS FALSE AND LOWER(unaccent(t.nom)) LIKE LOWER(unaccent($nom)) LIMIT 10
`
