import { NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import {
  hashPassword,
  createSession,
  setSessionCookie,
  writeAuditLog,
  extractRequestMeta,
} from "@/lib/auth";
import { seedDefaultTemplates } from "@/lib/reminders";
import { registerLimiter, getLimiterKey, tooManyRequests } from "@/lib/ratelimit";

// Email validation regex (RFC-compliant enough for SaaS)
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;

export async function POST(req: Request) {
  // ── Rate limiting ──────────────────────────────────────────────────────────
  const limitKey = getLimiterKey(req, "register");
  const limit    = registerLimiter.check(limitKey);
  if (!limit.allowed) return tooManyRequests(limit.resetIn);

  try {
    const body = await req.json().catch(() => null);
    if (!body || typeof body !== "object") {
      return NextResponse.json({ error: "Invalid request body" }, { status: 400 });
    }

    const { clinicName, email, password } = body as Record<string, unknown>;

    // ── Input validation ─────────────────────────────────────────────────────
    if (typeof clinicName !== "string" || clinicName.trim().length < 2) {
      return NextResponse.json({ error: "Clinic name must be at least 2 characters" }, { status: 400 });
    }
    if (typeof email !== "string" || !EMAIL_RE.test(email)) {
      return NextResponse.json({ error: "Invalid email address" }, { status: 400 });
    }
    if (typeof password !== "string" || password.length < 8) {
      return NextResponse.json({ error: "Password must be at least 8 characters" }, { status: 400 });
    }

    const normalizedEmail = email.trim().toLowerCase();
    const normalizedName  = clinicName.trim().slice(0, 100);

    // ── Duplicate check ──────────────────────────────────────────────────────
    const existing = await prisma.clinic.findUnique({ where: { email: normalizedEmail } });
    if (existing) {
      return NextResponse.json({ error: "An account with this email already exists" }, { status: 409 });
    }

    // ── Build slug ───────────────────────────────────────────────────────────
    const baseSlug = normalizedName
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, "-")
      .replace(/^-|-$/g, "");

    // Ensure slug uniqueness
    let slug = baseSlug;
    const slugConflict = await prisma.clinic.findUnique({ where: { slug } });
    if (slugConflict) {
      slug = `${baseSlug}-${Date.now().toString(36)}`;
    }

    // ── Create clinic ────────────────────────────────────────────────────────
    const passwordHash = await hashPassword(password);
    const trialEndsAt  = new Date(Date.now() + 14 * 24 * 60 * 60 * 1000); // 14-day trial

    const clinic = await prisma.clinic.create({
      data: {
        name:        normalizedName,
        slug,
        email:       normalizedEmail,
        passwordHash,
        plan:        "free",
        trialEndsAt,
      },
    });

    // ── Seed default reminder templates ──────────────────────────────────────
    await seedDefaultTemplates(clinic.id);

    // ── Create DB session ────────────────────────────────────────────────────
    const meta  = extractRequestMeta(req);
    const token = await createSession(clinic.id, meta);
    await setSessionCookie(token);

    // ── Audit log ────────────────────────────────────────────────────────────
    await writeAuditLog({
      clinicId: clinic.id,
      action:   "register",
      actor:    clinic.email,
      metadata: { plan: "free", trialEndsAt: trialEndsAt.toISOString() },
      request:  req,
    });

    return NextResponse.json({ success: true, clinicId: clinic.id }, { status: 201 });
  } catch (error) {
    console.error("[Register]", error);
    return NextResponse.json({ error: "Registration failed" }, { status: 500 });
  }
}
