import type { Email, ConversationMessage } from "@/lib/email-data"
import type {
  Contact,
  ComposeOpenPreset,
  ThreadComposeKind,
} from "@/lib/compose-context"
import { readCoarsePointerMatches } from "@/hooks/use-touch-nav"
import { readXsMatches } from "@/hooks/use-xs"
import { DEFAULT_IDENTITIES, SIGNATURES } from "@/lib/compose-context"
import { formatMailDetailDate } from "@/lib/mail-date"
import { cleanSenderName } from "@/lib/sender-display"

function appendDefaultSignature(html: string): string {
  const identity = DEFAULT_IDENTITIES[0]
  const sigId = identity.defaultSignatureId
  const sig = sigId ? SIGNATURES.find((s) => s.id === sigId) : null
  if (!sig) return html
  return `${html}<div id="ultimail-signature"><p>--</p>${sig.html}</div>`
}

/** Signature juste après la zone de saisie, avant le bloc « message transféré ». */
function insertSignatureBeforeForwardedBlock(html: string): string {
  const identity = DEFAULT_IDENTITIES[0]
  const sigId = identity.defaultSignatureId
  const sig = sigId ? SIGNATURES.find((s) => s.id === sigId) : null
  if (!sig) return html
  const sigBlock = `<div id="ultimail-signature"><p>--</p>${sig.html}</div>`
  const lead = "<p></p>"
  if (html.startsWith(lead)) {
    return `${lead}${sigBlock}${html.slice(lead.length)}`
  }
  return `${lead}${sigBlock}${html}`
}

function escapeHtml(text: string): string {
  return text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
}

function myEmailSet(): Set<string> {
  return new Set(DEFAULT_IDENTITIES.map((i) => i.email.toLowerCase()))
}

function contactKey(email: string): string {
  return email.trim().toLowerCase()
}

/** Tous les expéditeurs des messages du fil (hors « moi »), ordre chronologique conservé. */
export function collectThreadParticipants(email: Email): Contact[] {
  const my = myEmailSet()
  const seen = new Set<string>()
  const out: Contact[] = []

  const push = (name: string, addrRaw: string) => {
    const addr = addrRaw.trim()
    if (!addr) return
    const k = contactKey(addr)
    if (my.has(k) || seen.has(k)) return
    seen.add(k)
    out.push({
      name: cleanSenderName(name) || addr,
      email: addr,
    })
  }

  for (const m of email.conversation ?? []) {
    push(m.sender, m.senderEmail)
  }
  const mainAddr =
    email.senderEmail ??
    `${cleanSenderName(email.sender).toLowerCase().replace(/\s+/g, ".")}@example.com`
  push(email.sender, mainAddr)

  return out
}

function lastMessage(email: Email): ConversationMessage | null {
  const conv = email.conversation ?? []
  if (conv.length === 0) return null
  return conv[conv.length - 1]!
}

function replySubject(subject: string): string {
  const s = subject.trim()
  if (/^re\s*:/i.test(s)) return s
  return `Re: ${s}`
}

function forwardSubject(subject: string): string {
  const s = subject.trim()
  if (/^(fwd|fw|tr)\s*:/i.test(s)) return s
  return `Fwd: ${s}`
}

function buildReferences(email: Email): string[] {
  const ids: string[] = []
  for (const m of email.conversation ?? []) {
    ids.push(`<thread-msg-${m.id}@local>`)
  }
  ids.push(`<thread-msg-${email.id}@local>`)
  return ids
}

function inReplyToFor(email: Email): string {
  const last = lastMessage(email)
  if (last) return `<thread-msg-${last.id}@local>`
  return `<thread-msg-${email.id}@local>`
}

function formatQuoteDate(
  dateIso: string,
  senderEmail: string,
  senderName: string
): string {
  const who =
    senderName && senderName !== senderEmail
      ? `${escapeHtml(senderName)} &lt;${escapeHtml(senderEmail)}&gt;`
      : escapeHtml(senderEmail)
  return `Le ${escapeHtml(formatMailDetailDate(dateIso))}, ${who} a écrit :`
}

function quotedBlock(html: string): string {
  return `<blockquote type="cite" style="margin:0 0 0 0.8ex;border-left:1px solid #ccc;padding-left:1ex;color:#500">${html}</blockquote>`
}

function replyQuotedHtml(email: Email): string {
  const last = lastMessage(email)
  if (last) {
    const line = formatQuoteDate(last.date, last.senderEmail, cleanSenderName(last.sender))
    return `<p><br></p><div style="color:#666;font-size:13px">${line}</div>${quotedBlock(last.body)}`
  }
  const addr =
    email.senderEmail ??
    `${cleanSenderName(email.sender).toLowerCase().replace(/\s+/g, ".")}@example.com`
  const line = formatQuoteDate(email.date, addr, cleanSenderName(email.sender))
  const body = email.body ?? `<p style="color:#5f6368">${escapeHtml(email.preview)}</p>`
  return `<p><br></p><div style="color:#666;font-size:13px">${line}</div>${quotedBlock(body)}`
}

function forwardParticipantsLine(email: Email): string {
  const parts = collectThreadParticipants(email)
  if (parts.length === 0) return "To: (inconnu)"
  return `To: ${parts.map((p) => `${p.name} <${p.email}>`).join(", ")}`
}

/** Corps HTML du fil (messages précédents + message principal), sans en-tête « Forwarded ». */
function forwardConversationHtml(email: Email): string {
  const blocks: string[] = []
  for (const m of email.conversation ?? []) {
    blocks.push(
      `<div style="margin-top:12px;padding-top:12px;border-top:1px solid #e0e0e0">` +
        `<div style="color:#666;font-size:12px;margin-bottom:8px"><strong>De :</strong> ${escapeHtml(cleanSenderName(m.sender))} &lt;${escapeHtml(m.senderEmail)}&gt;<br/>` +
        `<strong>Date :</strong> ${escapeHtml(formatMailDetailDate(m.date))}</div>${m.body}</div>`
    )
  }
  const mainAddr =
    email.senderEmail ??
    `${cleanSenderName(email.sender).toLowerCase().replace(/\s+/g, ".")}@example.com`
  blocks.push(
    `<div style="margin-top:12px;padding-top:12px;border-top:1px solid #e0e0e0">` +
      `<div style="color:#666;font-size:12px;margin-bottom:8px"><strong>De :</strong> ${escapeHtml(cleanSenderName(email.sender))} &lt;${escapeHtml(mainAddr)}&gt;<br/>` +
      `<strong>Date :</strong> ${escapeHtml(formatMailDetailDate(email.date))}</div>` +
      `${email.body ?? `<p style="color:#5f6368">${escapeHtml(email.preview)}</p>`}</div>`
  )
  return blocks.join("")
}

function forwardBodyHtml(email: Email): string {
  const mainAddr =
    email.senderEmail ??
    `${cleanSenderName(email.sender).toLowerCase().replace(/\s+/g, ".")}@example.com`
  const header =
    `<p>---------- Forwarded message ---------</p>` +
    `<p style="color:#222;font-size:13px;line-height:1.5">` +
    `<strong>De :</strong> ${escapeHtml(cleanSenderName(email.sender))} &lt;${escapeHtml(mainAddr)}&gt;<br/>` +
    `<strong>Date :</strong> ${escapeHtml(formatMailDetailDate(email.date))}<br/>` +
    `<strong>Objet :</strong> ${escapeHtml(email.subject)}<br/>` +
    `<strong>${escapeHtml(forwardParticipantsLine(email))}</strong></p>`
  return `<p></p>${header}${forwardConversationHtml(email)}`
}

/** Tablette / tactile : composition plein écran (dock maximisé) au lieu d’inline sous le fil. */
export function withTouchFullscreenComposePreset(
  preset: ComposeOpenPreset
): ComposeOpenPreset {
  if (typeof window === "undefined" || !readCoarsePointerMatches()) {
    return preset
  }
  return {
    ...preset,
    placement: "dock",
    maximized: true,
  }
}

/**
 * Preset pour une fenêtre de composition inline (réponse / transfert) rattachée au fil `email`.
 */
export function buildThreadComposePreset(
  email: Email,
  kind: ThreadComposeKind
): ComposeOpenPreset {
  const participants = collectThreadParticipants(email)
  const last = lastMessage(email)
  const lastContact: Contact | null = last
    ? { name: cleanSenderName(last.sender), email: last.senderEmail }
    : participants.length > 0
      ? participants[participants.length - 1]!
      : null

  const threading = {
    inReplyTo: inReplyToFor(email),
    references: buildReferences(email),
  }

  if (kind === "forward") {
    const baseBody = insertSignatureBeforeForwardedBlock(forwardBodyHtml(email))
    return {
      to: [],
      cc: [],
      bcc: [],
      subject: forwardSubject(email.subject),
      bodyHtml: baseBody,
      placement: "inline",
      threadEmailId: email.id,
      threadKind: "forward",
      focusToOnMount: true,
      focusBodyOnMount: false,
      threading,
    }
  }

  if (kind === "reply") {
    const to = lastContact ? [lastContact] : []
    return {
      to,
      cc: [],
      bcc: [],
      subject: replySubject(email.subject),
      bodyHtml: appendDefaultSignature(replyQuotedHtml(email)),
      placement: "inline",
      threadEmailId: email.id,
      threadKind: "reply",
      focusToOnMount: false,
      focusBodyOnMount: true,
      threading,
    }
  }

  /* replyAll */
  const to: Contact[] = []
  const cc: Contact[] = []
  if (lastContact) {
    to.push(lastContact)
    for (const p of participants) {
      if (p.email === lastContact.email) continue
      cc.push(p)
    }
  } else if (participants.length > 0) {
    to.push(participants[0]!)
    for (let i = 1; i < participants.length; i++) {
      cc.push(participants[i]!)
    }
  }

  return {
    to,
    cc,
    bcc: [],
    subject: replySubject(email.subject),
    bodyHtml: appendDefaultSignature(replyQuotedHtml(email)),
    placement: "inline",
    threadEmailId: email.id,
    threadKind: "replyAll",
    focusToOnMount: false,
    focusBodyOnMount: true,
    threading,
    showCc: cc.length > 0,
  }
}
