// app/api/emails/route.ts
import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { validateEmailPrefix, computeExpiryDate } from "@/lib/validation";
import { generateRandomPrefix } from "@/lib/generate-name";

// Explicit shape (mirrors the TempEmail model + the includes below)
// instead of relying purely on inference, so this map callback never
// silently degrades to implicit-any.
interface TempEmailWithRelations {
  id: string;
  address: string;
  prefix: string;
  createdAt: Date;
  expiresAt: Date;
  isActive: boolean;
  domain: { name: string };
  _count: { messages: number };
}

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

    const now = new Date();

    // Filter on BOTH isActive and expiresAt so this list stays consistent
    // with the acceptance check used in the inbound-mail webhook — a row
    // that is expired OR has been deactivated should not show as "active".
    const emails = await prisma.tempEmail.findMany({
      where: { expiresAt: { gt: now }, isActive: true },
      orderBy: { createdAt: "desc" },
      include: {
        domain: { select: { name: true } },
        _count: { select: { messages: true } },
      },
    });

    const shaped = emails.map((e: TempEmailWithRelations) => ({
      id: e.id,
      address: e.address,
      prefix: e.prefix,
      domainName: e.domain.name,
      createdAt: e.createdAt,
      expiresAt: e.expiresAt,
      isActive: e.isActive,
      messageCount: e._count.messages,
    }));

    return NextResponse.json({ emails: shaped });
  } catch (err) {
    console.error("GET /api/emails failed:", err);
    return NextResponse.json({ error: "Failed to fetch emails" }, { 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.domainId !== "string") {
      return NextResponse.json(
        { error: "Request body must include a 'domainId' field" },
        { status: 400 }
      );
    }

    const domain = await prisma.domain.findUnique({ where: { id: body.domainId } });
    if (!domain) {
      return NextResponse.json({ error: "Domain not found" }, { status: 404 });
    }
    if (domain.status !== "ACTIVE") {
      return NextResponse.json(
        { error: "Cannot create an email under a domain that is not ACTIVE" },
        { status: 422 }
      );
    }

    // Resolve prefix: custom (validated) or auto-generated, with a
    // uniqueness retry loop for the auto-generated case.
    let prefix: string;
    if (body.prefix && typeof body.prefix === "string" && body.prefix.trim().length > 0) {
      const validation = validateEmailPrefix(body.prefix.trim());
      if (!validation.valid) {
        return NextResponse.json({ error: validation.error }, { status: 422 });
      }
      prefix = body.prefix.trim().toLowerCase();
    } else {
      prefix = generateRandomPrefix();
      let attempts = 0;
      while (attempts < 5) {
        const address = `${prefix}@${domain.name}`;
        const clash = await prisma.tempEmail.findUnique({ where: { address } });
        if (!clash) break;
        prefix = generateRandomPrefix();
        attempts++;
      }
    }

    const address = `${prefix}@${domain.name}`;

    const existing = await prisma.tempEmail.findUnique({ where: { address } });
    if (existing) {
      return NextResponse.json(
        { error: "An email with this prefix already exists on this domain" },
        { status: 409 }
      );
    }

    const now = new Date();
    const tempEmail = await prisma.tempEmail.create({
      data: {
        address,
        prefix,
        domainId: domain.id,
        createdAt: now,
        expiresAt: computeExpiryDate(now), // exactly 10 days from now
        isActive: true,
      },
    });

    return NextResponse.json({ email: tempEmail }, { status: 201 });
  } catch (err) {
    console.error("POST /api/emails failed:", err);
    return NextResponse.json({ error: "Failed to create temp email" }, { status: 500 });
  }
}
