import Member from "../../../../models/member.js";
import Series from "../../../../models/series.js";
import { loadPublicEvent } from "../../../../utils/loadEvent.js";
import {
  calculateTicketPrice,
  checkTicketAvailability,
  checkUserSeriesPass,
  formatPrice,
} from "../../../../utils/tickets.js";

/**
 * GET /api/events/[id]/tickets/available
 * Check ticket availability and pricing for current user
 * Query params: ?email=user@example.com (optional)
 */
export default defineEventHandler(async (event) => {
  try {
    const identifier = getRouterParam(event, "id");
    const query = getQuery(event);
    const userEmail = query.email;

    const eventData = await loadPublicEvent(event, identifier);

    if (eventData.isCancelled) {
      return { available: false, reason: "Event has been cancelled" };
    }

    if (new Date(eventData.startDate) < new Date()) {
      return { available: false, reason: "Event has already started" };
    }

    if (
      eventData.registrationDeadline &&
      new Date(eventData.registrationDeadline) < new Date()
    ) {
      return { available: false, reason: "Registration deadline has passed" };
    }

    // Series-pass gate: when an event is linked to a series that requires a
    // pass and doesn't allow drop-ins, surface a structured response so the UI
    // can route to the series page instead of rendering a generic "Sold Out"
    // block. The register/purchase handlers enforce this gate independently.
    if (
      eventData.tickets?.requiresSeriesTicket &&
      eventData.tickets?.seriesTicketReference
    ) {
      const series = await Series.findById(
        eventData.tickets.seriesTicketReference,
      );
      if (series && !series.tickets?.allowIndividualEventTickets) {
        const hasPass = userEmail
          ? checkUserSeriesPass(series, userEmail).hasPass
          : false;
        if (!hasPass) {
          return {
            available: false,
            reason: "series_pass_required",
            requiresSeriesPass: true,
            series: {
              id: series.id,
              title: series.title,
              slug: series.slug,
            },
          };
        }
      }
    }

    let member = null;
    if (userEmail) {
      member = await Member.findOne({ email: userEmail.toLowerCase() });
    }

    const ticketInfo = calculateTicketPrice(eventData, member);

    if (!ticketInfo) {
      return {
        available: false,
        reason: eventData.membersOnly
          ? "This event is for members only"
          : "No tickets available",
        membersOnly: eventData.membersOnly,
      };
    }

    const availability = checkTicketAvailability(
      eventData,
      ticketInfo.ticketType,
    );

    const response = {
      available: availability.available,
      ticketType: ticketInfo.ticketType,
      price: ticketInfo.price,
      currency: ticketInfo.currency,
      formattedPrice: formatPrice(ticketInfo.price, ticketInfo.currency),
      isFree: ticketInfo.isFree,
      isEarlyBird: ticketInfo.isEarlyBird,
      name: ticketInfo.name,
      description: ticketInfo.description,
      remaining: availability.remaining,
      waitlistAvailable: availability.waitlistAvailable,
    };

    if (ticketInfo.isEarlyBird && eventData.tickets?.public?.earlyBirdDeadline) {
      response.earlyBirdDeadline = eventData.tickets.public.earlyBirdDeadline;
      response.regularPrice = eventData.tickets.public.price;
      response.formattedRegularPrice = formatPrice(
        eventData.tickets.public.price,
        ticketInfo.currency,
      );
    }

    if (member && eventData.tickets?.public?.available) {
      response.publicTicket = {
        price: eventData.tickets.public.price,
        formattedPrice: formatPrice(
          eventData.tickets.public.price,
          eventData.tickets.currency,
        ),
      };
      response.memberSavings =
        eventData.tickets.public.price - ticketInfo.price;
    }

    if (userEmail) {
      const alreadyRegistered = eventData.registrations?.some(
        (reg) =>
          reg.email.toLowerCase() === userEmail.toLowerCase() &&
          !reg.cancelledAt,
      );

      if (alreadyRegistered) {
        response.alreadyRegistered = true;
        response.available = false;
        response.reason = "You are already registered for this event";
      }
    }

    return response;
  } catch (error) {
    if (error.statusCode) {
      throw error;
    }
    console.error("Error checking ticket availability:", error);
    throw createError({
      statusCode: 500,
      statusMessage: "Failed to check ticket availability",
    });
  }
});
