import { makeExecutableSchema } from '@graphql-tools/schema'
import Keys from '@inject/shared/localstorage/keys'
import readReceiptsQL from '../../schemas/readReceipts.graphql'
import type { Resolvers, TeamChannelReceipt } from './readReceiptsType'
import type { Context, SubschemaConfig, SubschemaResolverType } from './typing'

const schema = makeExecutableSchema<Context>({
  typeDefs: [readReceiptsQL],
  resolvers: {
    Query: {
      email(_, { id }) {
        const key = Keys.getReadReceiptEmailKey(id)
        const readReceipt = localStorage.getItem(key)
        return {
          id,
          readReceipt,
        }
      },
      readReceipt(_, { id }) {
        const key = Keys.getReadReceiptActionLogKey(id)
        const readReceipt = localStorage.getItem(key)
        return {
          id,
          readReceipt,
        }
      },
      channelId: (_, { channelId }) => ({
        id: channelId,
        readReceipt: JSON.parse(
          localStorage.getItem(Keys.getReadReceiptChannelKey(channelId)) || '[]'
        ) as TeamChannelReceipt[],
      }),
    },
    Mutation: {
      writeReadReceipt: (_, { actionLogId }) => {
        const readReceipt = new Date().toUTCString()
        localStorage.setItem(
          Keys.getReadReceiptActionLogKey(actionLogId),
          readReceipt
        )
        return {
          id: actionLogId,
          readReceipt,
        }
      },
      writeReadReceiptEmail: (_, { emailId }) => {
        const readReceipt = new Date().toUTCString()
        localStorage.setItem(Keys.getReadReceiptEmailKey(emailId), readReceipt)
        return {
          id: emailId,
          readReceipt,
        }
      },
      setIsUnreadChannel(_, { channelId, teamId, isUnread }) {
        const item = localStorage.getItem(
          Keys.getReadReceiptChannelKey(channelId)
        )
        const readReceipts = JSON.parse(item || '[]') as TeamChannelReceipt[]
        const existingReadReceiptIndex = readReceipts.findIndex(
          readReceipt => readReceipt.teamId === teamId
        )

        if (
          existingReadReceiptIndex !== -1 &&
          readReceipts[existingReadReceiptIndex].isUnread === isUnread
        ) {
          return {
            id: channelId,
            readReceipt: readReceipts,
          }
        }

        const newReadReceipts: TeamChannelReceipt[] =
          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 {
          id: channelId,
          readReceipt: newReadReceipts,
        }
      },
    },
  } as SubschemaResolverType<Resolvers>,
})

export default {
  merge: {
    DefinitionChannelType: {
      fieldName: 'channelId',
      selectionSet: '{ id }',
      args: ({ id }) => ({ channelId: id }),
    },
    ActionLogType: {
      fieldName: 'readReceipt',
      selectionSet: '{ id }',
      args: ({ id }) => ({ id }),
    },
    EmailType: {
      fieldName: 'email',
      selectionSet: '{ id }',
      args: ({ id }) => ({ id }),
    },
  },
  schema,
} as SubschemaConfig
