import Event from "../../../../models/event.js";
import Member from "../../../../models/member.js";
import { connectDB } from "../../../../utils/mongoose.js";
import {
  calculateTicketPrice,
  checkTicketAvailability,
  formatPrice,
} from "../../../../utils/tickets.js";
import mongoose from "mongoose";

/**
 * 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 {
    await connectDB();
    const identifier = getRouterParam(event, "id");
    const query = getQuery(event);
    const userEmail = query.email;

    if (!identifier) {
      throw createError({
        statusCode: 400,
        statusMessage: "Event identifier is required",
      });
    }

    // Fetch the event
    let eventData;
    if (mongoose.Types.ObjectId.isValid(identifier)) {
      eventData = await Event.findById(identifier);
    }
    if (!eventData) {
      eventData = await Event.findOne({ slug: identifier });
    }

    if (!eventData) {
      throw createError({
        statusCode: 404,
        statusMessage: "Event not found",
      });
    }

    // Check if event is cancelled or past
    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",
      };
    }

    // Check if user is a member (if email provided)
    let member = null;
    if (userEmail) {
      member = await Member.findOne({ email: userEmail.toLowerCase() });
    }

    // Calculate ticket pricing for this user
    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,
      };
    }

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

    // Build response
    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,
    };

    // Add early bird deadline if applicable
    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
      );
    }

    // Add member vs public comparison for transparency
    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;
    }

    // Check if user is already registered
    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) {
    console.error("Error checking ticket availability:", error);

    if (error.statusCode) {
      throw error;
    }

    throw createError({
      statusCode: 500,
      statusMessage: "Failed to check ticket availability",
    });
  }
});
