import type { TeamStateMap } from '@/clientsettings/vars/teams'
import { teamStateMap } from '@/clientsettings/vars/teams'
import type { ResultOf } from '@inject/graphql/graphql'
import { GetRunningExercises } from '@inject/graphql/queries'
import { useClient } from '@inject/graphql/urql/client'
import notEmpty from '@inject/shared/utils/notEmpty'
import { useCallback } from 'react'

const useTeamStateValidator = () => {
  const client = useClient()

  return useCallback(async () => {
    const { data } = await client.query<ResultOf<typeof GetRunningExercises>>(
      GetRunningExercises,
      {},
      {
        requestPolicy: 'network-only',
      }
    )
    if (!data || !data.exercises) return
    const runningExercises = data.exercises.filter(notEmpty)

    const teamStateMapVar = teamStateMap()

    if (runningExercises.length === 0) {
      /*
       * if the teamStateMapVar is not empty, the viewed exercise finished
       * or was paused
       *
       * keep the team state map but mark all teams as inactive
       */
      teamStateMap(
        Object.fromEntries(
          Object.entries(teamStateMapVar).map(([key, value]) => [
            key,
            { ...value, inactive: true },
          ])
        )
      )
      return
    }

    /*
     * create a new team state map with the teams from the currently running
     * exercises
     */
    const newTeamStateMap: TeamStateMap = Object.fromEntries(
      runningExercises.flatMap(exercise =>
        exercise.teams.map(team => [
          team.id,
          {
            team: {
              id: team.id,
              name: team.name,
              role: team.role,
              exercise: {
                id: team.exercise.id,
                name: team.exercise.name,
              },
            },
            show: false,
            inactive: false,
          },
        ])
      )
    )
    /*
     * if the teamStateMapVar is not empty, a previously selected exercise was
     * paused and is now running again
     *
     * keep the teams from the currently running exercises, but mark them
     * as active
     */
    const oldTeamStateMap: TeamStateMap = Object.fromEntries(
      Object.entries(teamStateMapVar)
        .filter(([, value]) =>
          runningExercises.some(
            exercise => exercise.id === value.team.exercise.id
          )
        )
        .map(([key, value]) => [
          key,
          {
            ...value,
            inactive: false,
          },
        ])
    )

    teamStateMap({
      ...newTeamStateMap,
      ...oldTeamStateMap,
    })
  }, [client])
}

export default useTeamStateValidator
