// Scoring engine — computes effective cost, break-even, and recommendation logic.

function computePassMetrics(pass, inputs, resorts) {
  const { days, flexibility, travel, regions, groupSize } = inputs;

  // Effective days available given blackout flexibility
  // null = unknown → assume medium-low penalty
  // High flex = no penalty; medium = lose ~half blackout days; low = lose all
  let blackoutPenalty = 0;
  if (pass.blackouts > 0) {
    if (flexibility === "low") blackoutPenalty = Math.min(pass.blackouts, days * 0.25);
    else if (flexibility === "medium") blackoutPenalty = Math.min(pass.blackouts * 0.5, days * 0.1);
    else if (flexibility == null) blackoutPenalty = Math.min(pass.blackouts * 0.3, days * 0.08);
    // high flex = 0 penalty
  }

  // Partner-day caps for trip-style passes
  let partnerCap = Infinity;
  if (pass.id === "mountain-collective") partnerCap = 2;
  if (pass.id === "indy") partnerCap = 2;

  // Coverage score: fraction of user's preferred regions covered
  const coveredRegions = regions.filter(r => pass.regions.includes(r) || r === "Any");
  const coverageRatio = regions.length === 0 ? 1 : coveredRegions.length / regions.length;

  // For trip-style passes, cap usable days at partnerCap × est resorts visited (approx)
  let usableDays = days - blackoutPenalty;
  if (partnerCap < Infinity && travel === "destination") {
    // assume destination skiers visit ~ days/3 different resorts
    const estResorts = Math.max(1, Math.ceil(days / 3));
    usableDays = Math.min(usableDays, estResorts * partnerCap);
  } else if (partnerCap < Infinity && travel === "local") {
    // local skiers will exhaust the 2-day cap quickly
    usableDays = Math.min(usableDays, partnerCap * 2);
  } else if (partnerCap < Infinity && travel == null) {
    // unknown — assume mid pattern: ~days/4 resorts
    const estResorts = Math.max(1, Math.ceil(days / 4));
    usableDays = Math.min(usableDays, estResorts * partnerCap);
  }

  // Cap usable days by pass's maximum available days (e.g., Session Pass only has 2-4 days)
  if (pass.maxDays && pass.maxDays > 0) {
    usableDays = Math.min(usableDays, pass.maxDays);
  }

  // Window-ticket equivalent cost (what days would cost without a pass)
  const windowCost = days * pass.avgWindow;

  // Effective cost per day
  const costPerDay = usableDays > 0 ? pass.price / usableDays : Infinity;

  // Break-even: at what day count does pass.price / d == avgWindow?
  const breakEven = Math.ceil(pass.price / pass.avgWindow);

  // Savings vs window tickets (only count usable days)
  const savings = windowCost - pass.price;

  // Group multiplier — buddy discount value
  let buddyValue = 0;
  if (groupSize > 1) {
    const buddies = groupSize - 1;
    const buddyDays = Math.min(usableDays, days);
    if (pass.buddyTickets > 0) {
      buddyValue += Math.min(pass.buddyTickets, buddies * 4) * pass.avgWindow * pass.buddyDiscount;
    } else if (pass.buddyDiscount > 0) {
      buddyValue += buddies * buddyDays * pass.avgWindow * pass.buddyDiscount * 0.3;
    }
  }

  // Composite score: lower cost-per-day + better coverage = higher score
  const baseScore = (1 / Math.max(costPerDay, 1)) * 100;
  const coverageBonus = coverageRatio * 30;
  const flexBonus = (flexibility === "low" && pass.blackouts === 0) ? 15 : 0;
  const travelBonus = (travel === "destination" && pass.travelFriendly) ? 5
                    : (travel === "local" && pass.localFriendly) ? 5 : 0;
  const buddyBonus = buddyValue / 50;
  const score = baseScore + coverageBonus + flexBonus + travelBonus + buddyBonus;

  return {
    pass,
    usableDays: Math.max(0, usableDays),
    costPerDay,
    breakEven,
    savings,
    coverageRatio,
    coveredRegions,
    buddyValue,
    blackoutPenalty,
    partnerCap,
    score,
    windowCost,
  };
}

function rankPasses(passes, inputs, resorts) {
  return passes.map(p => computePassMetrics(p, inputs, resorts)).sort((a, b) => b.score - a.score);
}

// Build a cost curve: $/day vs days for chart
function costCurve(pass, inputs, maxDays = 40) {
  const points = [];
  for (let d = 1; d <= maxDays; d++) {
    const m = computePassMetrics(pass, { ...inputs, days: d }, []);
    points.push({ d, cpd: Math.min(m.costPerDay, pass.avgWindow), passLine: pass.avgWindow });
  }
  return points;
}

window.computePassMetrics = computePassMetrics;
window.rankPasses = rankPasses;
window.costCurve = costCurve;
