import { NextRequest } from "next/server";
import { z } from "zod";
import { getSession } from "../../../lib/auth/session";
import { getPrisma } from "../../../lib/db";
import { ok, fail } from "../../../lib/http";
import { getStripe } from "../../../lib/stripe";
import { loadSystemConfig } from "../../../lib/system-config";
import { sendEmail } from "../../../lib/email";
import { createWebinarCalendarEvent } from "../../../lib/calendar";

export const runtime = "nodejs";

const Body = z.object({
  webinarId: z.string().uuid(),
});

export async function POST(req: NextRequest) {
  const session = await getSession();
  if (!session) return fail(new Error("Unauthorized"), { status: 401 });

  const prisma = await getPrisma();
  if (!prisma) return fail(new Error("Database not configured"), { status: 503 });

  // Check if user is admin - prevent admin registration for webinars
  const user = await prisma.user.findUnique({ where: { id: session.sub } });
  if (user?.role === "ADMIN") {
    return fail(new Error("Admins cannot register for webinars"), { status: 403 });
  }

  const parsed = Body.safeParse(await req.json().catch(() => ({})));
  if (!parsed.success) return fail(new Error("Invalid input"));

  const webinar = await prisma.webinar.findUnique({ where: { id: parsed.data.webinarId } });
  if (!webinar || webinar.visibility !== "PUBLIC" || !webinar.isActive) return fail(new Error("Not found"), { status: 404 });

  const count = await prisma.webinarRegistration.count({
    where: { webinarId: webinar.id, status: { not: "CANCELLED" } },
  });
  if (count >= webinar.capacity) return fail(new Error("Webinar is full"), { status: 409 });

  // Upsert registration
  if (webinar.priceCents <= 0) {
    const reg = await prisma.webinarRegistration.upsert({
      where: { userId_webinarId: { userId: session.sub, webinarId: webinar.id } },
      update: { status: "CONFIRMED" },
      create: { userId: session.sub, webinarId: webinar.id, status: "CONFIRMED" },
    });

    // Send confirmation email with calendar invite for free webinars
    const cfg = await loadSystemConfig();
    if (cfg.email?.enabled && user) {
      try {
        const { icsContent } = await createWebinarCalendarEvent(webinar, user.email);

        const meetingInfo = webinar.meetingInfo as any;
        const meetingLink = meetingInfo?.meetingLink || "TBD";
        const htmlContent = `
          <h2>Webinar Registration Confirmed</h2>
          <p>Hi ${user.firstName},</p>
          <p>Thank you for registering for <strong>${webinar.title}</strong>.</p>
          <p><strong>Date & Time:</strong> ${new Date(webinar.startAt).toLocaleString()}</p>
          <p><strong>Duration:</strong> ${webinar.duration} minutes</p>
          <p><strong>Join Link:</strong> <a href="${meetingLink}">${meetingLink}</a></p>
          <p>A calendar invitation is attached to this email.</p>
          <p>See you there!</p>
        `;

        await sendEmail({
          to: user.email,
          subject: `Registration Confirmed: ${webinar.title}`,
          html: htmlContent,
          attachments: [
            {
              filename: "webinar-invite.ics",
              content: icsContent,
              contentType: "text/calendar",
            },
          ],
        });
      } catch (error) {
        console.error("[REGISTRATION] Failed to send email:", error);
        // Don't fail the registration if email fails
      }
    }

    return ok({ registration: reg, next: "CONFIRMED" });
  }

  const cfg = await loadSystemConfig();
  const stripe = await getStripe();
  if (!stripe) return fail(new Error("Stripe not configured"), { status: 503 });

  const baseUrl = cfg.app?.initialized ? (process.env.APP_BASE_URL || "http://localhost:3000") : (process.env.APP_BASE_URL || "http://localhost:3000");

  const reg = await prisma.webinarRegistration.upsert({
    where: { userId_webinarId: { userId: session.sub, webinarId: webinar.id } },
    update: { status: "PAYMENT_PENDING" },
    create: { userId: session.sub, webinarId: webinar.id, status: "PAYMENT_PENDING" },
  });

  const checkout = await stripe.checkout.sessions.create({
    mode: "payment",
    success_url: `${baseUrl}/webinars/${webinar.id}?payment=success`,
    cancel_url: `${baseUrl}/webinars/${webinar.id}?payment=cancel`,
    line_items: [
      {
        quantity: 1,
        price_data: {
          currency: "usd",
          unit_amount: webinar.priceCents,
          product_data: { name: webinar.title },
        },
      },
    ],
    metadata: { registrationId: reg.id, userId: session.sub, webinarId: webinar.id },
  });

  await prisma.webinarRegistration.update({
    where: { id: reg.id },
    data: { stripeCheckoutSessionId: checkout.id },
  });

  return ok({ next: "STRIPE_CHECKOUT", url: checkout.url });
}
