import * as React from "react";
import { NextResponse } from "next/server";
import { z } from "zod";
import { isValidPhoneNumber, parsePhoneNumber } from "libphonenumber-js";
import { sendMail, headerSafe, mailRecipient, MailNotConfiguredError } from "@/lib/mail";
import { renderEmail, ContactInternalEmail, ContactConfirmationEmail } from "@/emails";

// This route talks to SMTP (nodemailer), so it must run on the Node.js runtime.
export const runtime = "nodejs";

// Server-side validation mirrors the client schema so the API is the source of
// truth (never trusts the client). This is a real request/response endpoint —
// the success page is only reached after this returns ok.
const schema = z.object({
  name: z.string().trim().min(2).max(80),
  email: z.email(),
  company: z.string().trim().min(1).max(120),
  phone: z.string().trim().max(50).optional(),
  phoneCountry: z.string().trim().max(10).optional(),
  department: z.string().trim().max(80).optional(),
  message: z.string().trim().min(10).max(4000),
  // Honeypot — accept any value; a non-empty value marks a bot (dropped below).
  website: z.string().optional(),
});

export async function POST(req: Request) {
  // Top-level guard: any unexpected runtime error (e.g. a phone-parsing throw or
  // an email-render fault) returns a CLEAN JSON 500 — never an empty 500 that
  // leaves the client showing a generic failure with no signal.
  try {
    return await handleContact(req);
  } catch (err) {
    console.error("[contact] unexpected error — returning clean 500:", err);
    return NextResponse.json(
      { ok: false, error: "Something went wrong on our side. Please try again." },
      { status: 500 },
    );
  }
}

async function handleContact(req: Request) {
  let body: unknown;
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ ok: false, error: "Invalid request." }, { status: 400 });
  }

  const parsed = schema.safeParse(body);
  if (!parsed.success) {
    return NextResponse.json(
      { ok: false, error: "Please check the highlighted fields and try again." },
      { status: 400 },
    );
  }

  // Bot silently accepted (no processing).
  if (parsed.data.website) return NextResponse.json({ ok: true });

  const { name, email, company, phone, phoneCountry, department, message } = parsed.data;

  // Server-side telephone validation: reject clearly invalid numbers if supplied
  if (phone && phone.trim().length > 0) {
    const valid = isValidPhoneNumber(phone, phoneCountry as any);
    if (!valid) {
      return NextResponse.json(
        { ok: false, error: "Please enter a valid phone number for the selected country." },
        { status: 400 },
      );
    }
  }

  // Canonical display / normalized phone for email lead delivery
  let displayPhone = phone || "—";
  if (phone) {
    try {
      const parsedPhone = parsePhoneNumber(phone, phoneCountry as any);
      if (parsedPhone) {
        displayPhone = `${parsedPhone.formatInternational()} (${parsedPhone.number})`;
      }
    } catch {
      // keep displayPhone as is
    }
  }

  // 1. Deliver the lead to the team sales inbox (mailRecipient())
  const isBooking = department === "Enterprise Sales";
  const internalSubject = headerSafe(
    isBooking
      ? `New Enterprise Booking: ${name} — ${company}`
      : `New Contact Inquiry: ${name} — ${company}`
  );

  try {
    const { html: internalHtml, text: internalText } = await renderEmail(
      React.createElement(ContactInternalEmail, {
        name,
        email,
        company,
        phone: displayPhone !== "—" ? displayPhone : undefined,
        department: department || "Enterprise Sales",
        message,
        submittedAt: new Date().toUTCString(),
      })
    );

    await sendMail({
      to: mailRecipient(),
      subject: internalSubject,
      text: internalText,
      html: internalHtml,
      replyTo: email,
    });
    console.log(`[contact] lead emailed to ${mailRecipient()} — from ${email}`);
  } catch (err) {
    if (err instanceof MailNotConfiguredError) {
      console.warn(
        `[contact] SMTP not configured — lead NOT emailed to ${mailRecipient()}. Set SMTP_* env. Lead:`,
        { name, email, company, phone, department, message },
      );
    } else {
      console.error(`[contact] email send FAILED to ${mailRecipient()}:`, err, {
        name,
        email,
        company,
      });
    }
    // Do not block the visitor if mail server hiccups; lead is logged above
    return NextResponse.json({ ok: true });
  }

  // 2. Deliver branded confirmation email to the visitor
  try {
    const userSubject = headerSafe("We received your request — Quto AI");
    const { html: userHtml, text: userText } = await renderEmail(
      React.createElement(ContactConfirmationEmail, {
        name,
        company,
        department: department || "Enterprise Sales",
        message,
      })
    );

    await sendMail({
      to: email,
      subject: userSubject,
      text: userText,
      html: userHtml,
    });
    console.log(`[contact] confirmation emailed to submitter ${email}`);
  } catch (err) {
    // Non-blocking for the client response; log for NOC visibility
    console.warn(`[contact] visitor confirmation email to ${email} skipped or failed:`, err);
  }

  return NextResponse.json({ ok: true });
}
