import type { ConversationMessage, Email } from "@/lib/email-data"

/** Id fil pour étoile, important, libellés, composition. */
export function threadStoreId(email: Pick<Email, "id" | "threadHeadId">): string {
  return email.threadHeadId ?? email.id
}

/** Message affiché en tête de fil en mode conversation. */
export function isThreadHeadMessage(
  email: Pick<Email, "id" | "isThreadHead" | "threadHeadId">
): boolean {
  if (email.isThreadHead === false) return false
  if (email.isThreadHead === true) return true
  return !email.threadHeadId || email.threadHeadId === email.id
}

function threadMetaFromHead(head: Email): Pick<
  Email,
  | "subject"
  | "labels"
  | "starred"
  | "important"
  | "spam"
  | "deleted"
  | "tag"
  | "hasInvitation"
  | "calendarInvitation"
  | "scheduledSendAt"
  | "scheduledToName"
  | "snoozeWakeAt"
> {
  return {
    subject: head.subject,
    labels: head.labels,
    starred: head.starred,
    important: head.important,
    spam: head.spam,
    deleted: head.deleted,
    tag: head.tag,
    hasInvitation: head.hasInvitation,
    calendarInvitation: head.calendarInvitation,
    scheduledSendAt: head.scheduledSendAt,
    scheduledToName: head.scheduledToName,
    snoozeWakeAt: head.snoozeWakeAt,
  }
}

function priorToEmail(
  msg: ConversationMessage,
  head: Email,
  threadMessageIds: string[]
): Email {
  return {
    ...threadMetaFromHead(head),
    id: msg.id,
    sender: msg.sender,
    senderEmail: msg.senderEmail,
    date: msg.date,
    preview: msg.preview,
    body: msg.body,
    attachments: msg.attachments,
    hasAttachment: (msg.attachments?.length ?? 0) > 0,
    read: msg.read ?? true,
    threadHeadId: head.id,
    threadMessageIds,
    isThreadHead: false,
  }
}

/** Découpe les fixtures legacy (`conversation[]`) en messages autonomes. */
export function normalizeLegacyEmailCatalog(raw: Email[]): Email[] {
  const out: Email[] = []

  for (const root of raw) {
    const conv = root.conversation ?? []
    if (conv.length === 0) {
      out.push({
        ...root,
        conversation: undefined,
        threadHeadId: root.id,
        threadMessageIds: [root.id],
        isThreadHead: true,
      })
      continue
    }

    const threadMessageIds = [...conv.map((m) => m.id), root.id]
    for (const msg of conv) {
      out.push(priorToEmail(msg, root, threadMessageIds))
    }
    out.push({
      ...root,
      conversation: undefined,
      threadHeadId: root.id,
      threadMessageIds,
      isThreadHead: true,
    })
  }

  return out
}

/** Reconstruit la vue fil (conversation[]) pour l’aperçu / réponse. */
export function buildThreadViewEmail(
  message: Email,
  byId: Map<string, Email>
): Email {
  const headId = message.threadHeadId ?? message.id
  const head = byId.get(headId) ?? message
  const ids = head.threadMessageIds ?? [headId]
  const priorIds = ids.slice(0, -1)

  const conversation: ConversationMessage[] = priorIds.map((id) => {
    const m = byId.get(id)!
    return {
      id: m.id,
      sender: m.sender,
      senderEmail: m.senderEmail ?? "",
      date: m.date,
      body: m.body ?? "",
      preview: m.preview,
      attachments: m.attachments,
    }
  })

  return { ...head, conversation }
}

export function getThreadMessageCount(
  email: Pick<Email, "threadMessageIds" | "conversation">
): number {
  if (email.threadMessageIds?.length) return email.threadMessageIds.length
  return 1 + (email.conversation?.length ?? 0)
}

/** Lu en liste : fil entier en mode conversation, message seul sinon. */
export function isListRowRead(
  email: Email,
  readOverrides: Record<string, boolean>,
  byId: Map<string, Email>,
  conversationMode: boolean
): boolean {
  if (
    conversationMode &&
    email.threadMessageIds &&
    email.threadMessageIds.length > 1
  ) {
    return email.threadMessageIds.every((id) => {
      const m = byId.get(id)
      if (!m) return true
      return readOverrides[id] ?? m.read
    })
  }
  return readOverrides[email.id] ?? email.read
}

/** Marque lu / non lu (un message ou tout le fil). */
export function readStateTargets(
  email: Email,
  conversationMode: boolean
): string[] {
  if (
    conversationMode &&
    email.threadMessageIds &&
    email.threadMessageIds.length > 1
  ) {
    return [...email.threadMessageIds]
  }
  return [email.id]
}
