import { makeExecutableSchema } from '@graphql-tools/schema'
import Keys from '@inject/shared/localstorage/keys'
import readReceiptsQL from '../../schemas/readReceipts.graphql'
import type { ChannelReceipt, EmailThreadReceipt } from '../cache-typing'
import type { SubschemaConfig } from './typing'

const readReceiptsSchema: SubschemaConfig = {
  schema: makeExecutableSchema({
    typeDefs: [readReceiptsQL],
    resolvers: {
      Mutation: {
        writeReadReceipt: (_, { actionLogId }) => {
          const readReceipt = new Date().toUTCString()
          localStorage.setItem(
            Keys.getReadReceiptActionLogKey(actionLogId),
            readReceipt
          )
          return {
            actionLogId,
            readReceipt,
          }
        },
        writeReadReceiptEmail: (_, { emailId }) => {
          const readReceipt = new Date().toUTCString()
          localStorage.setItem(
            Keys.getReadReceiptEmailKey(emailId),
            readReceipt
          )
          return {
            emailId,
            readReceipt,
          }
        },
        setIsUnreadEmailThread(_, { threadId, teamId, isUnread }) {
          const item = localStorage.getItem(
            Keys.getReadReceiptEmailThreadKey(threadId)
          )
          const readReceipts = JSON.parse(item || '[]') as EmailThreadReceipt[]
          const existingReadReceiptIndex = readReceipts.findIndex(
            readReceipt => readReceipt.teamId === teamId
          )

          if (
            existingReadReceiptIndex !== -1 &&
            !isUnread &&
            readReceipts[existingReadReceiptIndex].isUnread === isUnread
          ) {
            return { operationDone: false }
          }

          const newReadReceipts =
            existingReadReceiptIndex === -1
              ? [...readReceipts, { teamId, isUnread, threadId }]
              : [
                  ...readReceipts.slice(0, existingReadReceiptIndex),
                  { teamId, isUnread, threadId },
                  ...readReceipts.slice(existingReadReceiptIndex + 1),
                ]
          localStorage.setItem(
            Keys.getReadReceiptEmailThreadKey(threadId),
            JSON.stringify(newReadReceipts)
          )

          return { operationDone: true }
        },
        setIsUnreadChannel(_, { channelId, teamId, isUnread }) {
          const item = localStorage.getItem(
            Keys.getReadReceiptChannelKey(channelId)
          )
          const readReceipts = JSON.parse(item || '[]') as Omit<
            ChannelReceipt,
            '__typename'
          >[]
          const existingReadReceiptIndex = readReceipts.findIndex(
            readReceipt => readReceipt.teamId === teamId
          )

          if (
            existingReadReceiptIndex !== -1 &&
            readReceipts[existingReadReceiptIndex].isUnread === isUnread
          ) {
            return { operationDone: false }
          }

          const newReadReceipts: Omit<ChannelReceipt, '__typename'>[] =
            existingReadReceiptIndex === -1
              ? [...readReceipts, { teamId, isUnread, id: channelId }]
              : [
                  ...readReceipts.slice(0, existingReadReceiptIndex),
                  { teamId, isUnread, id: channelId },
                  ...readReceipts.slice(existingReadReceiptIndex + 1),
                ]
          localStorage.setItem(
            Keys.getReadReceiptChannelKey(channelId),
            JSON.stringify(newReadReceipts)
          )
          return { operationDone: true }
        },
      },
    },
  }),
}

export default readReceiptsSchema
