// app/api/domains/route.ts
import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { validateDomainName } from "@/lib/validation";
import { buildRequiredDnsRecords } from "@/lib/dns-verify";

// Explicit shape (mirrors the Domain model + the _count include below)
// instead of relying purely on inference, so this map callback never
// silently degrades to implicit-any.
interface DomainWithCount {
  id: string;
  name: string;
  status: "PENDING" | "ACTIVE";
  verifiedAt: Date | null;
  createdAt: Date;
  verificationToken: string;
  _count: { tempEmails: number };
}

export async function GET() {
  try {
    const session = await getServerSession(authOptions);
    if (!session) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const domains = await prisma.domain.findMany({
      orderBy: { createdAt: "desc" },
      include: {
        _count: { select: { tempEmails: true } },
      },
    });

    const shaped = domains.map((d: DomainWithCount) => ({
      id: d.id,
      name: d.name,
      status: d.status,
      verifiedAt: d.verifiedAt,
      createdAt: d.createdAt,
      activeEmailCount: d._count.tempEmails,
      dnsRecords: buildRequiredDnsRecords(d.verificationToken),
    }));

    return NextResponse.json({ domains: shaped });
  } catch (err) {
    console.error("GET /api/domains failed:", err);
    return NextResponse.json(
      { error: "Failed to fetch domains" },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    if (!session) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const body = await req.json().catch(() => null);
    if (!body || typeof body.name !== "string") {
      return NextResponse.json(
        { error: "Request body must include a 'name' field" },
        { status: 400 }
      );
    }

    const normalizedName = body.name.trim().toLowerCase();
    const validation = validateDomainName(normalizedName);
    if (!validation.valid) {
      return NextResponse.json({ error: validation.error }, { status: 422 });
    }

    const existing = await prisma.domain.findUnique({
      where: { name: normalizedName },
    });
    if (existing) {
      return NextResponse.json(
        { error: "This domain has already been added" },
        { status: 409 }
      );
    }

    const domain = await prisma.domain.create({
      data: { name: normalizedName },
    });

    return NextResponse.json(
      {
        domain: {
          ...domain,
          dnsRecords: buildRequiredDnsRecords(domain.verificationToken),
        },
      },
      { status: 201 }
    );
  } catch (err) {
    console.error("POST /api/domains failed:", err);
    return NextResponse.json(
      { error: "Failed to create domain" },
      { status: 500 }
    );
  }
}
