import { defineComponent, onMounted, ref } from 'vue'
import { Column, TableSimple } from '../_ui/table-simple'
import { nomColumn, statutCell, typeCell, domaineColumn, domaineCell, typeColumn } from '@/components/titres/table-utils'
import { SuperTitre } from 'camino-common/src/titres'
import { LoadingElement } from '@/components/_ui/functional-loader'
import { AsyncData } from '@/api/client-rest'
import { ComponentColumnData, JSXElementColumnData, TableRow, TextColumnData } from '../_ui/table'
import { DashboardApiClient } from './dashboard-api-client'
import { User } from 'camino-common/src/roles'
import { PageContentHeader } from '../_common/page-header-content'
import { exhaustiveCheck, isNotNullNorUndefined, isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools'
import { CaminoRouterLink, routerQueryToString } from '@/router/camino-router-link'
import { DemarchesTypes } from 'camino-common/src/static/demarchesTypes'
import { capitalize } from 'camino-common/src/strings'
import { EtapesTypes } from 'camino-common/src/static/etapesTypes'
import { getDomaineId } from 'camino-common/src/static/titresTypes'
import { computed } from 'vue'
import { Tab, Tabs } from '../_ui/tabs'
import { CaminoRouteLocation } from '@/router/routes'
import { CaminoRouter } from '@/typings/vue-router'
import { ActiviteSuper } from 'camino-common/src/activite'
import { activitesColonneIdAnnee } from '../activites'
import { getPeriode } from 'camino-common/src/static/frequence'
import { ActivitesTypes } from 'camino-common/src/static/activitesTypes'
import { ActiviteStatut } from '../_common/activite-statut'
import { fr } from '@codegouvfr/react-dsfr'
import { ACTIVITES_STATUTS_IDS } from 'camino-common/src/static/activitesStatuts'
import { CaminoMachineId } from 'camino-common/src/validators/machine'

const machineIdToText = {
  AncienLogigrammeOctroiARM: "Ancien logigramme octroi d'ARM",
  AncienLogigrammeOctroiAXM: "Ancien logigramme octroi d'AEX",
  AncienLogigrammeOctroiPRM: 'Ancien logigramme octroi de PRM',
  AncienLogigrammeProlongationAXM: "Ancien logigramme prolongation d'AEX",
  AncienLogigrammeRenonciationEtProlongationARM: "Ancien logigramme renonciation et prolongation d'ARM",
  ProcedureSimplifiee: 'Procédure simplifiée',
  ProcedureSpecifique: 'Procédure spécifique',
} as const satisfies Record<CaminoMachineId, string>
interface Props {
  apiClient: Pick<DashboardApiClient, 'getTitresAvecEtapeEnBrouillon' | 'getActivitesSuper'>
  user: User
  route: CaminoRouteLocation
  router: Pick<CaminoRouter, 'push'>
}
const brouillonsColumns = [
  nomColumn,
  { id: 'demarche_type', contentTitle: 'Type de démarche' },
  { id: 'titre_type', contentTitle: 'Type de titre' },
  domaineColumn,
  { id: 'titre_statut', contentTitle: 'Statut du titre' },
  { id: 'etape_brouillon', contentTitle: 'Étape en brouillon' },
  { id: 'etape_date', contentTitle: "Date de l'étape" },
  { id: 'machine', contentTitle: 'Machine associée' },
] as const satisfies Column[]
type BrouillonColumnId = (typeof brouillonsColumns)[number]['id']

const activitesColumns = [
  nomColumn,
  typeColumn,
  { id: activitesColonneIdAnnee, contentTitle: 'Année' },
  { id: 'periode', contentTitle: 'Période' },
  { id: 'activite_type', contentTitle: 'Type de rapport' },
  { id: 'statut', contentTitle: 'Statut' },
] as const satisfies Column[]
type ActiviteColumnId = (typeof activitesColumns)[number]['id']

const tabs = ['brouillons', 'activites'] as const
type TabId = (typeof tabs)[number]

export const PureSuperDashboard = defineComponent<Props>(props => {
  const brouillonsData = ref<AsyncData<TableRow<BrouillonColumnId>[]>>({ status: 'LOADING' })
  const activitesData = ref<AsyncData<TableRow<ActiviteColumnId>[]>>({ status: 'LOADING' })

  type BrouillonColumns = (typeof brouillonsColumns)[number]['id']

  const tabId = computed<TabId>(() => routerQueryToString(props.route.query.vueId, 'brouillons') as TabId)

  const vues = [
    {
      id: 'brouillons',
      icon: 'fr-icon-draft-line',
      title: 'Brouillons',
      renderContent: () => (
        <LoadingElement
          data={brouillonsData.value}
          renderItem={item => {
            if (isNotNullNorUndefinedNorEmpty(item)) {
              return <TableSimple caption={{ value: 'Titres avec une étape en brouillon', visible: true }} columns={brouillonsColumns} rows={item} />
            }

            return <p>Aucune étape en brouillon</p>
          }}
        />
      ),
    },
    {
      id: 'activites',
      icon: 'fr-icon-delete-bin-line',
      title: 'Activités',
      renderContent: () => (
        <LoadingElement
          data={activitesData.value}
          renderItem={item => {
            if (isNotNullNorUndefinedNorEmpty(item)) {
              return <TableSimple caption={{ value: 'Activités supprimables', visible: true }} columns={activitesColumns} rows={item} />
            }

            return <p>Aucune activité supprimable</p>
          }}
        />
      ),
    },
  ] as const satisfies readonly Tab<TabId>[]

  const titresLignesBuild = (titres: SuperTitre[]): TableRow<BrouillonColumns>[] => {
    return titres.map(titre => {
      const columns: {
        [key in BrouillonColumns]: JSXElementColumnData | ComponentColumnData | TextColumnData
      } = {
        nom: {
          type: 'jsx',
          jsxElement: (
            <CaminoRouterLink to={{ name: 'demarche', params: { demarcheId: titre.demarche_slug } }} isDisabled={false} title={titre.titre_nom}>
              {capitalize(titre.titre_nom)}
            </CaminoRouterLink>
          ),
          value: titre.demarche_type_id,
        },
        titre_type: typeCell(titre.titre_type_id),
        demarche_type: {
          type: 'text',
          value: capitalize(DemarchesTypes[titre.demarche_type_id].nom),
        },
        domaine: domaineCell({ domaineId: getDomaineId(titre.titre_type_id) }),
        titre_statut: statutCell(titre),
        etape_brouillon: { type: 'text', value: capitalize(EtapesTypes[titre.etape_type_id].nom) },
        etape_date: { type: 'text', value: titre.etape_date },
        machine: { type: 'text', value: isNotNullNorUndefined(titre.machine_id) ? machineIdToText[titre.machine_id] : 'TDE' },
      }

      return {
        id: titre.titre_slug,
        link: null,
        columns,
      }
    })
  }
  const activitesLignesBuild = (activites: ActiviteSuper[]): TableRow<ActiviteColumnId>[] => {
    return activites.map(activite => {
      const columns: {
        [key in ActiviteColumnId]: JSXElementColumnData | ComponentColumnData | TextColumnData
      } = {
        nom: {
          type: 'jsx',
          jsxElement: (
            <CaminoRouterLink to={{ name: 'activite', params: { activiteId: activite.id } }} isDisabled={false} title={activite.titre_nom}>
              {capitalize(activite.titre_nom)}
            </CaminoRouterLink>
          ),
          value: activite.titre_nom,
        },
        type: typeCell(activite.titre_type_id),
        periode: {
          type: 'text',
          value: getPeriode(ActivitesTypes[activite.type_id].frequenceId, activite.periode_id),
        },
        annee: {
          type: 'text',
          value: activite.annee,
        },
        activite_type: {
          type: 'text',
          value: ActivitesTypes[activite.type_id].nom,
        },
        statut: {
          type: 'jsx',
          jsxElement: <ActiviteStatut activiteStatutId={activite.activite_statut_id} />,
          value: activite.activite_statut_id,
        },
      }

      return {
        class: activite.activite_statut_id === ACTIVITES_STATUTS_IDS.DEPOSE ? [fr.cx('fr-label--error')] : undefined,
        id: activite.id,
        link: null,
        columns,
      }
    })
  }

  const loadBrouillons = async () => {
    if (brouillonsData.value.status !== 'LOADED') {
      const titres = await props.apiClient.getTitresAvecEtapeEnBrouillon()
      if ('message' in titres) {
        brouillonsData.value = {
          status: 'NEW_ERROR',
          error: titres,
        }
      } else {
        brouillonsData.value = {
          status: 'LOADED',
          value: titresLignesBuild(titres),
        }
      }
    }
  }
  const loadActivites = async () => {
    if (activitesData.value.status !== 'LOADED') {
      const activites = await props.apiClient.getActivitesSuper()
      if ('message' in activites) {
        activitesData.value = {
          status: 'NEW_ERROR',
          error: activites,
        }
      } else {
        activitesData.value = {
          status: 'LOADED',
          value: activitesLignesBuild(activites),
        }
      }
    }
  }

  const reload = async (tabId: TabId) => {
    switch (tabId) {
      case 'brouillons':
        await loadBrouillons()
        break
      case 'activites':
        await loadActivites()
        break
      default:
        exhaustiveCheck(tabId)
    }
  }
  onMounted(async () => {
    await reload(tabId.value)
  })

  return () => (
    <div>
      <PageContentHeader nom="Tableau de bord" download={null} renderButton={null} />

      <Tabs
        id="tdb_super_vues"
        initTab={tabId.value}
        tabs={vues}
        tabsTitle={'Affichage des titres contenant un brouillon, ou des activités supprimable'}
        tabClicked={async newTabId => {
          const query: CaminoRouteLocation['query'] = { ...props.route.query, vueId: newTabId }
          await props.router.push({ name: props.route.name ?? undefined, query, params: props.route.params })
          await reload(newTabId)
        }}
      />
    </div>
  )
})

// @ts-ignore waiting for https://github.com/vuejs/core/issues/7833
PureSuperDashboard.props = ['apiClient', 'user', 'route', 'router']
