import milestoneStatesEqual from '@inject/graphql/utils/milestoneStatesEqual'
import notEmpty from '@inject/shared/utils/notEmpty'
import { useEffect } from 'react'
import { useGetAnalyticsMilestonesSuspenseQuery } from '../queries/GetAnalyticsMilestones.generated'
import type { ExerciseMilestones } from '../subscriptions/AnalyticsMilestones.generated'
import { ExerciseMilestonesDocument } from '../subscriptions/AnalyticsMilestones.generated'

const useAnalyticsMilestonesSubscription = (exerciseId: string) => {
  const query = useGetAnalyticsMilestonesSuspenseQuery({
    variables: { exerciseId },
  })

  const { subscribeToMore } = query
  useEffect(
    () =>
      subscribeToMore({
        document: ExerciseMilestonesDocument,
        variables: { exerciseId },
        updateQuery: (prev, { subscriptionData }) => {
          // Codegen implicitly typecasts subscriptionData to the parent query type, this is not desired
          const retypedData =
            subscriptionData.data as unknown as ExerciseMilestones

          if (!retypedData.analyticsMilestonesSubscription?.milestones)
            return prev
          if (!prev.analyticsMilestones) return prev

          const subscribedMilestones =
            retypedData.analyticsMilestonesSubscription.milestones.filter(
              notEmpty
            )
          const newMilestones = prev.analyticsMilestones
            .filter(notEmpty)
            .map(oldMilestoneState => {
              const newMilestoneState = subscribedMilestones.find(
                milestoneState =>
                  milestoneStatesEqual(milestoneState, oldMilestoneState)
              )

              return newMilestoneState ? newMilestoneState : oldMilestoneState
            })

          return {
            ...prev,
            analyticsMilestones: newMilestones,
          }
        },
      }),
    [exerciseId, subscribeToMore]
  )

  return query
}

export default useAnalyticsMilestonesSubscription
