import { useApolloClient } from '@apollo/client'
import notEmpty from '@inject/shared/utils/notEmpty'
import { useEffect } from 'react'
import { GetTeamLearningObjectivesDocument } from '../queries/GetTeamLearningObjectives.generated'
import { useGetTeamMilestones } from '../queries/GetTeamMilestones.generated'
import type { TeamMilestones } from '../subscriptions/TeamMilestones.generated'
import { TeamMilestonesDocument } from '../subscriptions/TeamMilestones.generated'
import milestoneStatesEqual from './milestoneStatesEqual'

const useTeamMilestonesSubscription = (teamId: string) => {
  const query = useGetTeamMilestones({
    variables: {
      teamId,
    },
    initialFetchPolicy: 'network-only',
    nextFetchPolicy: 'cache-and-network',
  })

  const { subscribeToMore, networkStatus } = query
  const client = useApolloClient()

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

          if (!retypedData.milestones?.milestones) return prev
          if (!prev.teamMilestones) return prev

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

              return newMilestoneState ? newMilestoneState : oldMilestoneState
            })

          client.refetchQueries({
            include: [GetTeamLearningObjectivesDocument],
          })

          return {
            ...prev,
            teamMilestones: newMilestones,
          }
        },
      }),
    [client, subscribeToMore, teamId]
  )

  return { teamId, networkStatus }
}

export default useTeamMilestonesSubscription
