import type { Cache } from '@urql/exchange-graphcache'
import type { ActionLogType } from '../../cache-typing'

// This routine is ran whenever a new actionLog arrives to the client and needs to be sorted into relevant queries (or to better intuitize, bucket)
function commitActionLogToCache(cache: Cache, actionLog: ActionLogType) {
  if (
    actionLog.type === 'EMAIL' &&
    actionLog.details.__typename === 'EmailType'
  ) {
    const newEmailThread = actionLog.details.thread
    if (newEmailThread) {
      const params = [
        'Query',
        'emailThreads',
        { teamId: actionLog.team.id as string },
      ] as const

      const link =
        cache.resolve({ __typename: 'Query' }, 'emailThreads', {
          teamId: actionLog.team.id,
        }) || []

      if (!Array.isArray(link)) {
        throw Error('Generic type error, please check emailThreads')
      }

      const needle = cache.keyOfEntity({
        __typename: 'EmailThreadType',
        id: newEmailThread.id,
      })
      cache.link(...params, [
        ...link.filter(emailThreadKey => emailThreadKey !== needle),
        needle,
      ])
    }
  }

  const params = [
    'Query',
    'teamChannelLogs',
    {
      teamId: actionLog.team.id,
      channelId: actionLog.channel.id,
    },
  ] as const

  const link = cache.resolve(...params)

  // The idea is to prevent needless write-ins to ensure that when querying for the channel for first time it reliably fetches the necessary actionLog for given channel/team/exercise without being overridden by subscription routine.
  if (!link) {
    console.log(
      `!!!: A new actionLog ${actionLog.id} to a non-initialized channel ${actionLog.channel.id}, blocking write!`
    )
    return
  }

  if (!Array.isArray(link)) {
    throw new Error('Generic typing error, please check commitActionLog')
  }

  const key = cache.keyOfEntity({
    __typename: 'ActionLogType',
    id: actionLog.id,
  })

  cache.link(...params, [...link, key])
}

export default commitActionLogToCache
