import { NextRequest, NextResponse } from "next/server";
import { promises as dns } from "dns";

interface CheckResult {
  name: string;
  status: "ok" | "warn" | "err";
  message: string;
  records?: string[];
}

export async function GET(req: NextRequest) {
  const domain = req.nextUrl.searchParams.get("domain")?.trim().toLowerCase();
  if (!domain) return NextResponse.json({ error: "domain required" }, { status: 400 });
  if (!/^[a-zA-Z0-9._\-]+$/.test(domain)) {
    return NextResponse.json({ error: "Invalid domain" }, { status: 400 });
  }

  const checks: CheckResult[] = [];

  // A/AAAA records
  try {
    const aRecords = await dns.resolve4(domain);
    checks.push({ name: "A Records", status: "ok", message: `${aRecords.length} IPv4 address(es)`, records: aRecords });
  } catch {
    try {
      const aaaaRecords = await dns.resolve6(domain);
      checks.push({ name: "AAAA Records", status: "ok", message: `${aaaaRecords.length} IPv6 address(es)`, records: aaaaRecords });
    } catch {
      checks.push({ name: "A/AAAA Records", status: "err", message: "No A or AAAA records found" });
    }
  }

  // NS records
  try {
    const ns = await dns.resolveNs(domain);
    checks.push({ name: "NS Records", status: ns.length >= 2 ? "ok" : "warn", message: `${ns.length} nameserver(s)${ns.length < 2 ? " — at least 2 recommended" : ""}`, records: ns });
  } catch {
    checks.push({ name: "NS Records", status: "err", message: "No NS records found" });
  }

  // MX records
  try {
    const mx = await dns.resolveMx(domain);
    checks.push({ name: "MX Records", status: mx.length > 0 ? "ok" : "warn", message: mx.length > 0 ? `${mx.length} mail exchanger(s)` : "No MX records — email not configured", records: mx.map((m) => `${m.priority} ${m.exchange}`) });
  } catch {
    checks.push({ name: "MX Records", status: "warn", message: "No MX records found" });
  }

  // SPF (TXT)
  try {
    const txt = await dns.resolveTxt(domain);
    const spf = txt.flat().filter((r) => r.startsWith("v=spf1"));
    if (spf.length > 0) {
      checks.push({ name: "SPF Record", status: spf.length === 1 ? "ok" : "warn", message: spf.length > 1 ? "Multiple SPF records (only one allowed)" : "SPF configured", records: spf });
    } else {
      checks.push({ name: "SPF Record", status: "warn", message: "No SPF record found — email spoofing risk" });
    }
  } catch {
    checks.push({ name: "SPF Record", status: "warn", message: "Could not query TXT records" });
  }

  // DMARC
  try {
    const dmarc = await dns.resolveTxt(`_dmarc.${domain}`);
    const dmarcRec = dmarc.flat().filter((r) => r.startsWith("v=DMARC1"));
    checks.push({ name: "DMARC Record", status: dmarcRec.length > 0 ? "ok" : "warn", message: dmarcRec.length > 0 ? "DMARC configured" : "No DMARC record", records: dmarcRec });
  } catch {
    checks.push({ name: "DMARC Record", status: "warn", message: "No DMARC record found" });
  }

  // SOA
  try {
    const soa = await dns.resolveSoa(domain);
    checks.push({ name: "SOA Record", status: "ok", message: `Primary NS: ${soa.nsname}`, records: [`nsname: ${soa.nsname}`, `hostmaster: ${soa.hostmaster}`, `serial: ${soa.serial}`] });
  } catch {
    checks.push({ name: "SOA Record", status: "err", message: "No SOA record found" });
  }

  // CAA
  try {
    const caa = await dns.resolveCaa(domain);
    checks.push({ name: "CAA Record", status: "ok", message: `${caa.length} CAA record(s)`, records: caa.map((c) => `${c.critical} ${c.issue ?? c.issuewild ?? c.iodef}`) });
  } catch {
    checks.push({ name: "CAA Record", status: "warn", message: "No CAA records — any CA can issue SSL" });
  }

  const score = Math.round((checks.filter((c) => c.status === "ok").length / checks.length) * 100);
  return NextResponse.json({ domain, score, checks });
}
