import { makeVar, useReactiveVar } from '@inject/shared/utils/reactive'
import { useEffect } from 'react'
import { useClient } from 'urql'
import type { ResultOf, VariablesOf } from '../graphql'
import { GetExerciseLoopStatus } from '../queries'
import { exerciseLoopRunning } from '../subscriptions'

const exerciseLoopVar = makeVar<{
  running: boolean
  loading: boolean
  exerciseId: string | null
}>({
  running: false,
  loading: true,
  exerciseId: null,
})

export const useLoopStatus = () => useReactiveVar(exerciseLoopVar)

let singletonFlag = false

const useExerciseLoopStatusSubscription = (exerciseId: string) => {
  const client = useClient()

  useEffect(() => {
    if (singletonFlag) {
      throw Error('There are multiple exerciseLoopSubscriptions running!')
    }

    singletonFlag = true

    client
      .query<
        ResultOf<typeof GetExerciseLoopStatus>,
        VariablesOf<typeof GetExerciseLoopStatus>
      >(
        GetExerciseLoopStatus,
        {
          exerciseId,
        },
        {
          requestPolicy: 'cache-and-network',
        }
      )
      .then(({ data }) => {
        exerciseLoopVar({
          exerciseId,
          loading: false,
          running: data?.exerciseLoopRunning || false,
        })
      })
    const { unsubscribe } = client
      .subscription<
        ResultOf<typeof exerciseLoopRunning>,
        VariablesOf<typeof exerciseLoopRunning>
      >(exerciseLoopRunning, {
        exerciseId,
      })
      .subscribe(({ data }) => {
        exerciseLoopVar({
          exerciseId,
          loading: false,
          running: data?.exerciseLoopRunning?.exerciseLoopRunning || false,
        })
      })
    return () => {
      singletonFlag = false
      unsubscribe()
      exerciseLoopVar({
        exerciseId: null,
        loading: true,
        running: false,
      })
    }
  }, [client, exerciseId])
}

export default useExerciseLoopStatusSubscription
