import { NextRequest } from "next/server";
import { z } from "zod";
import type { SearchCriteria, Deal } from "@/lib/types";
import { fetchCityDeals } from "@/lib/providers/yowDeals";
import { buildSkyscannerLinks, buildGoogleFlightsLinks, buildAirCanadaLinks, buildAirTransatLinks } from "@/lib/providers/linkBuilders";
import { scoreDeal } from "@/lib/score";

const schema = z.object({
  origin: z.string().min(3).max(4),
  destinations: z.array(z.string().min(3)).nonempty(),
  startDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  endDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  tripLengthMin: z.number().int().positive(),
  tripLengthMax: z.number().int().positive(),
  budget: z.number().int().positive().optional().nullable(),
  currency: z.string().default("CAD").optional(),
  nonStopOnly: z.boolean().optional(),
  sources: z.array(z.string()).optional(),
  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()
});

export async function POST(req: NextRequest) {
  try {
    const body = await req.json();
    const parsed = schema.parse(body) as SearchCriteria;
    const sources = (parsed.sources && parsed.sources.length ? parsed.sources : ["Deals", "Skyscanner", "GoogleFlights", "AirCanada", "AirTransat"]).map(s => s.toLowerCase());

    const tasks: Promise<Deal[]>[] = [];

    if (sources.includes("deals")) tasks.push(fetchCityDeals(parsed));
    if (sources.includes("skyscanner")) tasks.push(buildSkyscannerLinks(parsed));
    if (sources.includes("googleflights")) tasks.push(buildGoogleFlightsLinks(parsed));
    if (sources.includes("aircanada")) tasks.push(buildAirCanadaLinks(parsed));
    if (sources.includes("airtransat")) tasks.push(buildAirTransatLinks(parsed));

    // Demo mode fallback
    const demo = process.env.DEMO === "true";

    let results: Deal[] = [];
    if (demo) {
      results = [
        { id: "demo1", title: "🔥 Ottawa → Cancun (7 nights)", source: "Demo", link: "#", price: 685, currency: "CAD", startDate: parsed.startDate, endDate: parsed.startDate, nights: 7, origin: parsed.origin, destination: parsed.destinations[0], stops: 0 },
        { id: "demo2", title: "Ottawa → Punta Cana (7 nights)", source: "Demo", link: "#", price: 712, currency: "CAD", startDate: parsed.startDate, endDate: parsed.startDate, nights: 7, origin: parsed.origin, destination: parsed.destinations[0], stops: 1 }
      ];
    } else {
      const settled = await Promise.allSettled(tasks);
      for (const s of settled) {
        if (s.status === "fulfilled") results.push(...s.value);
      }
    }

    // Filter and score
    if (parsed.budget) results = results.filter(r => !r.price || r.price <= (parsed.budget || 0));
    if (parsed.nonStopOnly) results = results.filter(r => r.stops == null || r.stops === 0);

    results.forEach(r => r.score = scoreDeal(r, parsed.preferences));
    results.sort((a,b) => (b.score || 0) - (a.score || 0));

    // Optional n8n webhook
    const webhook = process.env.N8N_WEBHOOK_URL;
    if (webhook) {
      try {
        await fetch(webhook, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ criteria: parsed, top10: results.slice(0,10) }) });
      } catch(e) { /* ignore */ }
    }

    return new Response(JSON.stringify({ results }), { 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" } });
  }
}
