import ExerciseContext from '@/analyst/ExerciseContext'
import NavigationBar from '@/analyst/NavigationBar'
import { DUMMY_EXERCISE, DUMMY_EXERCISE_CONFIG } from '@/analyst/utilities'
import { useParams } from '@/router'
import { NonIdealState } from '@blueprintjs/core'
import { useTypedQuery } from '@inject/graphql/graphql'
import { GetExerciseWithConfig } from '@inject/graphql/queries'
import useActionLogSubscriptionInstructor from '@inject/graphql/utils/Subscriptions/instructor'
import useQuestionnaireSubscriptionInstructor from '@inject/graphql/utils/Subscriptions/instructorQuestionnaireState'
import CenteredSpinner from '@inject/shared/components/CenteredSpinner'
import ErrorMessage from '@inject/shared/components/ErrorMessage'
import notEmpty from '@inject/shared/utils/notEmpty'
import { useMemo } from 'react'
import { Outlet } from 'react-router-dom'

const Layout = () => {
  const { exerciseId } = useParams('/analyst/:exerciseId')

  const [{ data, fetching: loading, error }] = useTypedQuery({
    query: GetExerciseWithConfig,
    variables: { exerciseId },
  })
  useActionLogSubscriptionInstructor({ exerciseId })
  useQuestionnaireSubscriptionInstructor({
    exerciseId,
    teamIds: data?.exerciseId.teams.map(team => team.id).filter(notEmpty) || [],
  })

  const exerciseContextValue = useMemo(
    () => ({
      exercise: data?.exerciseId || DUMMY_EXERCISE,
      exerciseConfig: data?.exerciseConfig || DUMMY_EXERCISE_CONFIG,
    }),
    [data?.exerciseConfig, data?.exerciseId]
  )

  // TODO: use suspense instead (test when switching exercises)
  if (loading) {
    return <CenteredSpinner />
  }
  if (error) {
    return (
      <ErrorMessage>
        <h1>Error occurred!</h1>
        <p>{error.message}</p>
      </ErrorMessage>
    )
  }
  if (!data || !data.exerciseId || !data.exerciseConfig) {
    return (
      <NonIdealState
        icon='low-voltage-pole'
        title='No data'
        description='Please wait for the data to come in'
      />
    )
  }

  return (
    <ExerciseContext.Provider value={exerciseContextValue}>
      <NavigationBar>
        <Outlet />
      </NavigationBar>
    </ExerciseContext.Provider>
  )
}

export default Layout
