import { defineComponent, inject, ref } from 'vue'
import { Liste, Params } from './_common/liste'
import { useRouter } from 'vue-router'
import { canCreateEntreprise } from 'camino-common/src/permissions/utilisateurs'
import { User } from 'camino-common/src/roles'
import { EntrepriseAddPopup } from './entreprise/add-popup'
import { entrepriseApiClient } from './entreprise/entreprise-api-client'
import { Entreprise, Siren } from 'camino-common/src/entreprise'
import { DsfrButtonIcon } from './_ui/dsfr-button'
import { ApiClient, apiClient } from '../api/api-client'
import { entreprisesDownloadFormats } from 'camino-common/src/filters'
import { Column, TableRow } from './_ui/table'
import { entreprisesKey, userKey } from '@/moi'
import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools'
import { newGetWithJson } from '@/api/client-rest'
import { CaminoRouteLocation, routesDefinitions } from '@/router/routes'
import { CaminoRouter } from '@/typings/vue-router'

const entreprisesColonnes = [
  {
    id: 'nom',
    contentTitle: 'Nom',
    noSort: true,
  },
  {
    id: 'siren',
    contentTitle: 'Siren',
    noSort: true,
  },
] as const satisfies readonly Column[]

type ColonneId = (typeof entreprisesColonnes)[number]['id']

interface Props {
  currentRoute: CaminoRouteLocation
  updateUrlQuery: Pick<CaminoRouter, 'push'>
  apiClient: Pick<ApiClient, 'creerEntreprise' | 'titresRechercherByNom' | 'getTitresByIds'>
  entreprises: Entreprise[]
  user: User
}
export const PureEntreprises = defineComponent<Props>(props => {
  const popupVisible = ref(false)
  const addPopupOpen = () => {
    popupVisible.value = true
  }
  const close = () => {
    popupVisible.value = !popupVisible.value
  }

  const getData = (options: Params<ColonneId>): Promise<{ total: number; values: TableRow<string>[] }> => {
    const lignes = [...props.entreprises]
      .filter(entreprise => {
        if (isNotNullNorUndefined(options.filtres) && isNotNullNorUndefined(options.filtres.nomsEntreprise) && options.filtres.nomsEntreprise !== '') {
          if (
            !entreprise.nom.toLowerCase().includes(options.filtres.nomsEntreprise.toLowerCase()) &&
            !(entreprise.legal_siren ?? '').toLowerCase().includes(options.filtres.nomsEntreprise.toLowerCase())
          ) {
            return false
          }
        }

        return true
      })
      .map<TableRow>(entreprise => {
        const columns: TableRow['columns'] = {
          nom: { type: 'text', value: entreprise.nom },
          siren: { type: 'text', value: entreprise.legal_siren ?? '–' },
        }

        return {
          id: entreprise.id,
          link: { name: 'entreprise', params: { id: entreprise.id } },
          columns,
        }
      })

    return Promise.resolve({ total: lignes.length, values: lignes })
  }

  return () => (
    <Liste
      nom="entreprises"
      colonnes={entreprisesColonnes}
      download={{ id: 'entreprisesDownload', downloadTitle: 'Télécharger les entreprises', downloadRoute: '/entreprises', formats: entreprisesDownloadFormats, params: {} }}
      getData={getData}
      listeFiltre={{
        filtres: routesDefinitions[props.currentRoute.name].meta.filtres,
        apiClient: props.apiClient,
        updateUrlQuery: props.updateUrlQuery,
        entreprises: props.entreprises,
      }}
      route={props.currentRoute}
      renderButton={() => {
        if (canCreateEntreprise(props.user)) {
          return (
            <>
              <DsfrButtonIcon class="fr-ml-1w" icon="fr-icon-add-line" buttonType="secondary" title="Ajouter une entreprise" label="Ajouter une entreprise" onClick={addPopupOpen} />
              {popupVisible.value ? <EntrepriseAddPopup close={close} user={props.user} apiClient={props.apiClient} /> : null}
            </>
          )
        } else {
          return <span></span>
        }
      }}
    />
  )
})

// @ts-ignore waiting for https://github.com/vuejs/core/issues/7833
PureEntreprises.props = ['currentRoute', 'updateUrlQuery', 'apiClient', 'user', 'entreprises']

export const Entreprises = defineComponent(() => {
  const router = useRouter()
  const user = inject(userKey)
  const entreprises = inject(entreprisesKey, ref([]))

  const customApiClient = () => {
    return {
      ...apiClient,
      creerEntreprise: async (siren: Siren) => {
        const value = await entrepriseApiClient.creerEntreprise(siren)
        if ('message' in value) {
          return value
        }
        const newEntreprises = await newGetWithJson('/rest/entreprises', {})
        if ('message' in newEntreprises) {
          return newEntreprises
        }
        entreprises.value = newEntreprises
        router.push({ name: 'entreprise', params: { id: `fr-${siren}` } })
        return value
      },
    }
  }

  return () => <PureEntreprises entreprises={entreprises.value} currentRoute={router.currentRoute.value} updateUrlQuery={router} user={user} apiClient={customApiClient()} />
})
