import dns from "node:dns/promises";

/**
 * IMAP-Provider Konfigurationen
 * Automatisch erkennen anhand der Email-Domain
 */
export interface ImapConfig {
  host: string;
  port: number;
  name: string;
}

const PROVIDER_MAP: Record<string, ImapConfig> = {
  // Google
  "gmail.com": { host: "imap.gmail.com", port: 993, name: "Gmail" },
  "googlemail.com": { host: "imap.gmail.com", port: 993, name: "Gmail" },
  // Apple
  "icloud.com": { host: "imap.mail.me.com", port: 993, name: "iCloud" },
  "me.com": { host: "imap.mail.me.com", port: 993, name: "iCloud" },
  "mac.com": { host: "imap.mail.me.com", port: 993, name: "iCloud" },
  // Microsoft
  "outlook.com": { host: "outlook.office365.com", port: 993, name: "Outlook" },
  "hotmail.com": { host: "outlook.office365.com", port: 993, name: "Hotmail" },
  "hotmail.de": { host: "outlook.office365.com", port: 993, name: "Hotmail" },
  "live.com": { host: "outlook.office365.com", port: 993, name: "Live" },
  "live.de": { host: "outlook.office365.com", port: 993, name: "Live" },
  "msn.com": { host: "outlook.office365.com", port: 993, name: "Outlook" },
  // Yahoo
  "yahoo.com": { host: "imap.mail.yahoo.com", port: 993, name: "Yahoo" },
  "yahoo.de": { host: "imap.mail.yahoo.com", port: 993, name: "Yahoo" },
  "yahoo.co.uk": { host: "imap.mail.yahoo.com", port: 993, name: "Yahoo" },
  "ymail.com": { host: "imap.mail.yahoo.com", port: 993, name: "Yahoo" },
  // GMX / Web.de (United Internet)
  "gmx.de": { host: "imap.gmx.net", port: 993, name: "GMX" },
  "gmx.net": { host: "imap.gmx.net", port: 993, name: "GMX" },
  "gmx.at": { host: "imap.gmx.net", port: 993, name: "GMX" },
  "gmx.ch": { host: "imap.gmx.net", port: 993, name: "GMX" },
  "web.de": { host: "imap.web.de", port: 993, name: "Web.de" },
  // Telekom
  "t-online.de": { host: "secureimap.t-online.de", port: 993, name: "T-Online" },
  "magenta.de": { host: "secureimap.t-online.de", port: 993, name: "T-Online" },
  // Freenet
  "freenet.de": { host: "mx.freenet.de", port: 993, name: "Freenet" },
  // Posteo
  "posteo.de": { host: "posteo.de", port: 993, name: "Posteo" },
  // Tutanota / Tuta
  "tutanota.com": { host: "mail.tutanota.com", port: 993, name: "Tutanota" },
  "tuta.io": { host: "mail.tutanota.com", port: 993, name: "Tutanota" },
  // IONOS / 1&1 (direkte Consumer-Domains)
  "ionos.de": { host: "imap.ionos.de", port: 993, name: "IONOS" },
  "1und1.de": { host: "imap.ionos.de", port: 993, name: "IONOS" },
  "1and1.com": { host: "imap.ionos.de", port: 993, name: "IONOS" },
  "1and1.de": { host: "imap.ionos.de", port: 993, name: "IONOS" },
  "1blu.de": { host: "imap.1blu.de", port: 993, name: "1blu" },
};

/**
 * MX-Record-Patterns die IONOS-Hosting-Infrastruktur identifizieren.
 * IONOS-Kunden mit eigener Domain nutzen mx00.ionos.de oder kundenserver.de.
 * Quelle: IONOS Hilfe-Seite + eigene DNS-Lookups (verifiziert 2026-05).
 */
const MX_IONOS_PATTERNS = [
  "ionos.de",
  "kundenserver.de",
  "perfora.net",
  "ui-dns.de",
  "ui-dns.org",
  "ui-dns.biz",
  "ui-dns.com",
];

/**
 * Versucht via MX-Record-Lookup den Provider einer Custom-Domain zu erkennen.
 * Wird nur aufgerufen wenn PROVIDER_MAP keinen direkten Treffer hat.
 * Timeout: 3s (schnell genug für Connect-Flow, kein User-Impact).
 */
async function detectImapProviderByMx(domain: string): Promise<ImapConfig | null> {
  try {
    const mxRecords = await Promise.race([
      dns.resolveMx(domain),
      new Promise<never>((_, reject) => setTimeout(() => reject(new Error("timeout")), 3000)),
    ]);

    for (const mx of mxRecords) {
      const exchange = mx.exchange.toLowerCase();
      if (MX_IONOS_PATTERNS.some((pattern) => exchange.endsWith(pattern))) {
        return { host: "imap.ionos.de", port: 993, name: "IONOS" };
      }
    }
  } catch {
    // DNS-Lookup fehlgeschlagen oder Timeout — kein Problem, Fallback greift
  }
  return null;
}

export function detectImapProvider(email: string): ImapConfig {
  const domain = email.split("@")[1]?.toLowerCase() ?? "";
  return (
    PROVIDER_MAP[domain] ?? {
      host: `imap.${domain}`,
      port: 993,
      name: domain,
    }
  );
}

/**
 * Async-Variante mit MX-Lookup-Fallback für Custom-Domains.
 * Nutzen wenn detectImapProvider keinen bekannten Provider zurückgibt
 * (erkennbar daran dass name === domain, also kein Friendly-Name).
 */
export async function detectImapProviderAsync(email: string): Promise<ImapConfig> {
  const domain = email.split("@")[1]?.toLowerCase() ?? "";
  const direct = PROVIDER_MAP[domain];
  if (direct) return direct;

  const byMx = await detectImapProviderByMx(domain);
  if (byMx) return byMx;

  // Letzter Fallback: imap.<domain> — Standard-Konvention
  return { host: `imap.${domain}`, port: 993, name: domain };
}

const SMTP_MAP: Record<string, { host: string; port: number }> = {
  "imap.gmail.com": { host: "smtp.gmail.com", port: 587 },
  "imap.mail.me.com": { host: "smtp.mail.me.com", port: 587 },
  "imap.gmx.net": { host: "mail.gmx.net", port: 587 },
  "imap.web.de": { host: "smtp.web.de", port: 587 },
  "outlook.office365.com": { host: "smtp-mail.outlook.com", port: 587 },
  "imap.mail.yahoo.com": { host: "smtp.mail.yahoo.com", port: 587 },
  "secureimap.t-online.de": { host: "securesmtp.t-online.de", port: 587 },
  "mx.freenet.de": { host: "mx.freenet.de", port: 587 },
  "posteo.de": { host: "posteo.de", port: 587 },
};

export function detectSmtpProvider(imapHost: string): { host: string; port: number } {
  return SMTP_MAP[imapHost] ?? { host: imapHost.replace("imap.", "smtp."), port: 587 };
}

/**
 * Leitet einen normalisierten Provider-Key + Label aus dem gespeicherten
 * providerName/imapHost einer MailConnection ab.
 * Wird in List-Endpoints + Stats-Endpoints für Filterung und Donut-Chart genutzt.
 *
 * Gibt { provider, providerLabel, isCustomDomain } zurück:
 *   provider      = slug (z.B. "gmail", "outlook", "icloud", "custom")
 *   providerLabel = human-readable (z.B. "Gmail", "Outlook", "iCloud Mail")
 *   isCustomDomain = true wenn kein bekannter großer Provider
 */
const HOST_TO_PROVIDER: Record<string, { provider: string; providerLabel: string }> = {
  "imap.gmail.com":            { provider: "gmail",    providerLabel: "Gmail" },
  "outlook.office365.com":     { provider: "outlook",  providerLabel: "Outlook" },
  "imap.mail.me.com":          { provider: "icloud",   providerLabel: "iCloud Mail" },
  "imap.gmx.net":              { provider: "gmx",      providerLabel: "GMX" },
  "imap.web.de":               { provider: "webde",    providerLabel: "Web.de" },
  "imap.mail.yahoo.com":       { provider: "yahoo",    providerLabel: "Yahoo" },
  "secureimap.t-online.de":    { provider: "tonline",  providerLabel: "T-Online" },
  "mx.freenet.de":             { provider: "freenet",  providerLabel: "Freenet" },
  "posteo.de":                 { provider: "posteo",   providerLabel: "Posteo" },
  "imap.ionos.de":             { provider: "ionos",    providerLabel: "IONOS" },
};

export function resolveProviderMeta(imapHost: string): {
  provider: string;
  providerLabel: string;
  isCustomDomain: boolean;
} {
  const match = HOST_TO_PROVIDER[imapHost];
  if (match) return { ...match, isCustomDomain: false };
  return { provider: "custom", providerLabel: imapHost, isCustomDomain: true };
}
