import type { Identity } from "@/lib/compose-context"
import type {
  AgendaAutoImportSource,
  AgendaInvitationExclusion,
} from "@/lib/agenda/agenda-settings-types"

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

/** Extrait l'email d'une clé stockée (legacy `accountId:email` ou email seul). */
export function destinationEmailFromStoredKey(key: string): string {
  const trimmed = key.trim()
  if (!trimmed) return trimmed
  const at = trimmed.lastIndexOf("@")
  if (at <= 0) return normalizeDestinationEmail(trimmed)
  const colon = trimmed.lastIndexOf(":", at)
  if (colon >= 0) return normalizeDestinationEmail(trimmed.slice(colon + 1))
  return normalizeDestinationEmail(trimmed)
}

export type AgendaDestinationMailbox = {
  /** Clé stable (email normalisé). */
  key: string
  /** Libellé affiché (casse d'origine). */
  label: string
}

function addDestinationEmail(map: Map<string, string>, raw: string) {
  const trimmed = raw.trim()
  if (!trimmed || !trimmed.includes("@")) return
  const key = normalizeDestinationEmail(trimmed)
  if (!map.has(key)) map.set(key, trimmed)
}

/** Boîtes mail de destination uniques (comptes + identités), dédupliquées par email. */
export function buildDestinationMailboxes(
  identities: Identity[],
  accountEmails: string[] = [],
): AgendaDestinationMailbox[] {
  const map = new Map<string, string>()
  for (const email of accountEmails) addDestinationEmail(map, email)
  for (const identity of identities) addDestinationEmail(map, identity.email)
  return [...map.entries()]
    .map(([key, label]) => ({ key, label }))
    .sort((a, b) => a.label.localeCompare(b.label, "fr", { sensitivity: "base" }))
}

export function destinationMailboxLabel(
  storedKey: string,
  mailboxes: AgendaDestinationMailbox[],
): string {
  const key = destinationEmailFromStoredKey(storedKey)
  return mailboxes.find((m) => m.key === key)?.label ?? key
}

export function normalizeAutoImportDestinationKeys(keys: string[]): string[] {
  return [...new Set(keys.map(destinationEmailFromStoredKey).filter(Boolean))]
}

export function normalizeAutoImportInvitationSources(
  items: AgendaInvitationExclusion[],
  mailboxes: AgendaDestinationMailbox[] = [],
): AgendaAutoImportSource[] {
  const seen = new Set<string>()
  const out: AgendaAutoImportSource[] = []
  for (const item of items) {
    if (item.type !== "identity" && item.type !== "contact") continue
    let normalized: AgendaAutoImportSource
    if (item.type === "identity") {
      const value = destinationEmailFromStoredKey(item.value)
      normalized = {
        type: "identity",
        value,
        label: destinationMailboxLabel(value, mailboxes) || value,
      }
    } else {
      const value = normalizeDestinationEmail(item.value)
      if (!value) continue
      normalized = {
        type: "contact",
        value,
        label: item.label.trim() || value,
      }
    }
    const id =
      normalized.type === "identity"
        ? `identity:${normalized.value}`
        : `contact:${normalized.value}`
    if (seen.has(id)) continue
    seen.add(id)
    out.push(normalized)
  }
  return out
}

export function migrateAutoImportIdentityKeys(
  keys: string[],
  mailboxes: AgendaDestinationMailbox[] = [],
): AgendaAutoImportSource[] {
  return normalizeAutoImportInvitationSources(
    keys.map((key) => ({
      type: "identity" as const,
      value: destinationEmailFromStoredKey(key),
      label: destinationEmailFromStoredKey(key),
    })),
    mailboxes,
  )
}

export function normalizeInvitationImportExclusions(
  items: AgendaInvitationExclusion[],
  mailboxes: AgendaDestinationMailbox[] = [],
): AgendaInvitationExclusion[] {
  const seen = new Set<string>()
  const out: AgendaInvitationExclusion[] = []
  for (const item of items) {
    if (item.type !== "identity") {
      out.push(item)
      continue
    }
    const value = destinationEmailFromStoredKey(item.value)
    const id = `identity:${value}`
    if (seen.has(id)) continue
    seen.add(id)
    out.push({
      type: "identity",
      value,
      label: destinationMailboxLabel(value, mailboxes) || value,
    })
  }
  return out
}
