import { compareDates } from '@/analyst/utilities'
import type { EmailThread } from '@inject/graphql/fragment-types'
import { useMemo } from 'react'
import type { ExtendedEmaiLThread } from './typing'

interface FilteredThreads {
  received: ExtendedEmaiLThread[]
  sent: ExtendedEmaiLThread[]
}

interface FilteredThreadsWithUnread {
  sent: { emailThreads: ExtendedEmaiLThread[]; unread: number }
  received: { emailThreads: ExtendedEmaiLThread[]; unread: number }
}

const getLastEmail = (
  emailThread: EmailThread,
  teamId: string,
  type: 'sent' | 'received'
) =>
  emailThread.emails
    .filter(email =>
      type === 'sent'
        ? email.sender.team?.id === teamId
        : email.sender.team?.id !== teamId
    )
    .at(0)

const sortFn = (a: ExtendedEmaiLThread, b: ExtendedEmaiLThread) =>
  -compareDates(
    new Date(a.lastEmail.timestamp),
    new Date(b.lastEmail.timestamp)
  )

const useFilteredThreads = ({
  emailThreads,
  teamId,
}: {
  emailThreads: EmailThread[]
  teamId: string
}): FilteredThreadsWithUnread => {
  const { received, sent } = useMemo(
    () =>
      emailThreads.reduce(
        (accumulator: FilteredThreads, emailThread: EmailThread) => {
          const lastEmailReceived = getLastEmail(
            emailThread,
            teamId,
            'received'
          )
          const lastEmailSent = getLastEmail(emailThread, teamId, 'sent')

          return {
            received: [
              ...accumulator.received,
              ...(lastEmailReceived
                ? [{ ...emailThread, lastEmail: lastEmailReceived }]
                : []),
            ],
            sent: [
              ...accumulator.sent,
              ...(lastEmailSent
                ? [{ ...emailThread, lastEmail: lastEmailSent }]
                : []),
            ],
          }
        },
        { sent: [], received: [] }
      ),
    [emailThreads, teamId]
  )

  const result = useMemo(
    () => ({
      received: {
        emailThreads: received.sort(sortFn),
        unread: received.filter(thread =>
          thread.readReceipt.some(
            readReceipt => readReceipt.teamId === teamId && readReceipt.isUnread
          )
        ).length,
      },
      sent: {
        emailThreads: sent.sort(sortFn),
        unread: sent.filter(thread =>
          thread.readReceipt.some(
            readReceipt => readReceipt.teamId === teamId && readReceipt.isUnread
          )
        ).length,
      },
    }),
    [received, sent, teamId]
  )

  return result
}

export default useFilteredThreads
