import Member from "../../../models/member.js";
import Series from "../../../models/series.js";
import Event from "../../../models/event.js";
import { sendEventRegistrationEmail } from "../../../utils/resend.js";
import { validateBody } from "../../../utils/validateBody.js";
import { eventRegistrationSchema } from "../../../utils/schemas.js";
import { loadPublicEvent } from "../../../utils/loadEvent.js";
import {
  hasMemberAccess,
  validateTicketPurchase,
  checkUserSeriesPass,
} from "../../../utils/tickets.js";

export default defineEventHandler(async (event) => {
  try {
    const identifier = getRouterParam(event, "id");
    const body = await validateBody(event, eventRegistrationSchema);

    const eventData = await loadPublicEvent(event, identifier);

    // Series-pass gate: when an event is linked to a series and that series
    // requires a pass, reject drop-in registration unless the series
    // explicitly allows individual event tickets.
    if (
      eventData.tickets?.requiresSeriesTicket &&
      eventData.tickets?.seriesTicketReference
    ) {
      const series = await Series.findById(
        eventData.tickets.seriesTicketReference,
      );
      if (!series) {
        throw createError({
          statusCode: 500,
          statusMessage: "Series referenced by this event could not be found",
        });
      }
      if (!series.tickets?.allowIndividualEventTickets) {
        const { hasPass } = checkUserSeriesPass(series, body.email);
        if (!hasPass) {
          throw createError({
            statusCode: 403,
            statusMessage:
              "This event requires a series pass. See the series page to purchase.",
            data: { seriesSlug: series.slug },
          });
        }
      }
    }

    // Look up member for pricing/access purposes. hasMemberAccess treats
    // guest/suspended/cancelled as non-members.
    const member = await Member.findOne({ email: body.email.toLowerCase() });

    // Single gate: validateTicketPurchase covers deadline, cancelled, already
    // started, already-registered, members-only, and sold-out.
    const validation = validateTicketPurchase(eventData, {
      email: body.email,
      name: body.name,
      member: hasMemberAccess(member) ? member : null,
    });

    if (!validation.valid) {
      const statusCode = /members only/i.test(validation.reason) ? 403 : 400;
      throw createError({ statusCode, statusMessage: validation.reason });
    }

    const memberHasAccess = hasMemberAccess(member);
    let isMember = false;
    let membershipLevel = "non-member";

    if (memberHasAccess) {
      isMember = true;
      membershipLevel = `${member.circle}-${member.contributionAmount}`;
    }

    // Add registration
    const registration = {
      memberId: member ? member._id : null,
      name: body.name,
      email: body.email.toLowerCase(),
      membershipLevel,
      isMember,
      paymentStatus: "not_required", // Free events or member registrations
      amountPaid: 0,
      dietary: body.dietary || false,
      registeredAt: new Date(),
    };

    // Use $push to avoid re-validating the whole document (e.g. legacy location formats)
    const result = await Event.findByIdAndUpdate(
      eventData._id,
      { $push: { registrations: registration } },
      { new: true, runValidators: false },
    );
    const newRegistration =
      result.registrations[result.registrations.length - 1];

    // Log activity
    if (member) {
      logActivity(member._id, 'event_registered', {
        eventId: eventData._id,
        eventTitle: eventData.title,
        eventSlug: eventData.slug
      })
    }

    // Send confirmation email — respect member notification preferences
    const shouldSendEventEmail =
      !member || member.notifications?.events !== false;
    if (shouldSendEventEmail) {
      try {
        await sendEventRegistrationEmail(registration, eventData);
        if (member) {
          logActivity(member._id, 'email_sent', {
            emailType: 'event_registration',
            subject: `You're registered for ${eventData.title}`
          })
        }
      } catch (emailError) {
        console.error("Failed to send confirmation email:", emailError);
      }
    }

    return {
      success: true,
      message: "Successfully registered for the event",
      registrationId: newRegistration._id,
    };
  } catch (error) {
    console.error("Error registering for event:", error);

    if (error.statusCode) {
      throw error;
    }

    throw createError({
      statusCode: 500,
      statusMessage: "Failed to register for event",
    });
  }
});
