import { NextRequest } from "next/server";
import { z } from "zod";
import { findResort, calculateResortScore, type Resort } from "@/lib/resorts";
import { format, addDays } from "date-fns";

const schema = z.object({
  resorts: z.array(z.string()).nonempty(),
  departureDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  origin: z.string().min(3).max(4).default("YOW"),
  tripLength: z.number().int().positive().default(7),
  budget: z.number().positive().optional(),
  contingencyPercent: z.number().min(0).max(50).optional().default(15), // Allow up to 15% over budget for high scores
  preferences: z.object({
    beach: z.number().min(0).max(10).optional(),
    pool: z.number().min(0).max(10).optional(),
    golf: z.number().min(0).max(10).optional(),
    spa: z.number().min(0).max(10).optional(),
    food: z.number().min(0).max(10).optional(),
    nightlife: z.number().min(0).max(10).optional(),
    shopping: z.number().min(0).max(10).optional(),
    culture: z.number().min(0).max(10).optional(),
    outdoor: z.number().min(0).max(10).optional(),
    family: z.number().min(0).max(10).optional(),
  }).optional()
});

type ResortComparison = {
  resort: Resort;
  matchScore: number;
  flightLinks: {
    skyscanner: string;
    googleFlights: string;
    airCanada: string;
  };
  estimatedFlightPrice?: string;
  estimatedFlightPriceMin?: number;
  estimatedFlightPriceMax?: number;
  estimatedTotalMin?: number;
  estimatedTotalMax?: number;
  withinBudget?: boolean;
  budgetStatus?: string;
  overBudgetAmount?: number;
};

function buildFlightLinks(origin: string, destination: string, departureDate: string, returnDate: string) {
  const depFormatted = departureDate.replace(/-/g, "");
  const retFormatted = returnDate.replace(/-/g, "");
  
  return {
    skyscanner: `https://www.skyscanner.ca/transport/flights/${origin.toLowerCase()}/${destination.toLowerCase()}/${depFormatted}/${retFormatted}/`,
    googleFlights: `https://www.google.com/travel/flights?q=${encodeURIComponent(`flights from ${origin} to ${destination} ${departureDate} to ${returnDate}`)}`,
    airCanada: `https://www.aircanada.com/ca/en/aco/home/book/travel.html?${new URLSearchParams({
      org1: origin.toUpperCase(),
      dest1: destination.toUpperCase(),
      departureDate1: departureDate,
      returnDate1: returnDate,
      tripType: "2",
      lang: "en-CA"
    }).toString()}`
  };
}

function estimateResortCost(priceRange: string, nights: number): { min: number; max: number } {
  // CANADIAN ALL-INCLUSIVE PACKAGE PRICING (per person, CAD)
  // Based on real travel agent quotes for 7-night packages from Ottawa
  // Includes: flights, accommodations, transfers, taxes
  const packageRanges: Record<string, { min: number; max: number }> = {
    "$": { min: 1200, max: 1600 },      // Budget packages
    "$$": { min: 1600, max: 2000 },     // Mid-range packages
    "$$$": { min: 2000, max: 2400 },    // Upper mid-range
    "$$$$": { min: 2400, max: 2800 },   // Premium (Dreams Onyx: $2509)
    "$$$$$": { min: 2800, max: 3500 }   // Luxury packages
  };
  
  // Adjust for trip length (base is 7 nights)
  const baseDays = 7;
  const lengthMultiplier = nights / baseDays;
  
  const range = packageRanges[priceRange] || packageRanges["$$$"];
  return {
    min: Math.round(range.min * lengthMultiplier),
    max: Math.round(range.max * lengthMultiplier)
  };
}

export async function POST(req: NextRequest) {
  try {
    const body = await req.json();
    const parsed = schema.parse(body);
    
    const comparisons: ResortComparison[] = [];
    const notFound: string[] = [];
    
    // Calculate return date
    const returnDate = format(addDays(new Date(parsed.departureDate), parsed.tripLength), "yyyy-MM-dd");
    
    for (const resortName of parsed.resorts) {
      const resort = findResort(resortName);
      
      if (!resort) {
        notFound.push(resortName);
        continue;
      }
      
      const matchScore = calculateResortScore(resort, parsed.preferences);
      const flightLinks = buildFlightLinks(parsed.origin, resort.airportCode, parsed.departureDate, returnDate);
      
      // Package pricing (per person, includes flights)
      const packageCost = estimateResortCost(resort.priceRange || "$$$", parsed.tripLength);
      
      // Total cost for 2 people (standard package assumption)
      const estimatedTotalMin = packageCost.min * 2;
      const estimatedTotalMax = packageCost.max * 2;
      
      // Per person cost for display
      const estimatedPerPerson = `$${packageCost.min}-$${packageCost.max} per person`;

      
      // Budget analysis
      let withinBudget = true;
      let budgetStatus = "Within Budget";
      let overBudgetAmount = 0;
      
      if (parsed.budget) {
        const contingencyAmount = parsed.budget * ((parsed.contingencyPercent || 15) / 100);
        const budgetWithContingency = parsed.budget + contingencyAmount;
        
        if (estimatedTotalMin > parsed.budget) {
          overBudgetAmount = estimatedTotalMin - parsed.budget;
          
          // Check if high score justifies going over budget
          if (matchScore >= 1800 && estimatedTotalMin <= budgetWithContingency) {
            withinBudget = true;
            budgetStatus = `Over budget by $${overBudgetAmount.toFixed(0)} but HIGH MATCH (within ${parsed.contingencyPercent}% contingency)`;
          } else if (estimatedTotalMin <= budgetWithContingency) {
            withinBudget = true;
            budgetStatus = `Within ${parsed.contingencyPercent}% contingency (+$${overBudgetAmount.toFixed(0)})`;
          } else {
            withinBudget = false;
            budgetStatus = `Over budget by $${overBudgetAmount.toFixed(0)} (exceeds contingency)`;
          }
        } else {
          budgetStatus = `Under budget by $${(parsed.budget - estimatedTotalMin).toFixed(0)}`;
        }
      }
      
      comparisons.push({
        resort,
        matchScore,
        flightLinks,
        estimatedFlightPrice: estimatedPerPerson,
        estimatedFlightPriceMin: packageCost.min,
        estimatedFlightPriceMax: packageCost.max,
        estimatedTotalMin,
        estimatedTotalMax,
        withinBudget,
        budgetStatus,
        overBudgetAmount: overBudgetAmount > 0 ? overBudgetAmount : undefined
      });
    }
    
    // Sort by match score (highest first)
    comparisons.sort((a, b) => b.matchScore - a.matchScore);
    
    // Filter by budget if specified (but include high-scoring resorts within contingency)
    let budgetFiltered = comparisons;
    if (parsed.budget) {
      budgetFiltered = comparisons.filter(c => c.withinBudget);
    }
    
    return new Response(JSON.stringify({ 
      comparisons: budgetFiltered,
      allComparisons: comparisons, // Include all for reference
      notFound,
      budgetInfo: parsed.budget ? {
        budget: parsed.budget,
        contingencyPercent: parsed.contingencyPercent || 15,
        contingencyAmount: parsed.budget * ((parsed.contingencyPercent || 15) / 100),
        maxBudget: parsed.budget + (parsed.budget * ((parsed.contingencyPercent || 15) / 100)),
        withinBudgetCount: budgetFiltered.length,
        totalCount: comparisons.length,
        overBudgetCount: comparisons.length - budgetFiltered.length
      } : null,
      flightInfo: {
        origin: parsed.origin,
        departureDate: parsed.departureDate,
        returnDate,
        tripLength: parsed.tripLength
      },
      packageSites: [
        "Sunwing Vacations",
        "Air Canada Vacations",
        "WestJet Vacations",
        "Air Transat Holidays",
        "RedTag.ca"
      ],
      pricingNote: "Estimates are for individual bookings (flight + resort). Package deals are typically 30-40% cheaper."
    }), { 
      headers: { "content-type": "application/json" } 
    });
    
  } catch (e: any) {
    return new Response(JSON.stringify({ 
      error: e?.message || "Invalid payload" 
    }), { 
      status: 400, 
      headers: { "content-type": "application/json" } 
    });
  }
}
