// Future-booking generator. The "pipeline" is upcoming reservations that
// haven't been collected yet (paid + checked in). It's generator output —
// not stored in the DB — because it'll come from Lodgify in a later phase.
//
// Exposes window.generatePipeline(houses) -> array of pipeline bookings.

(function () {
  const PIPELINE_TODAY = '2026-04-24';

  function pipeRand(seed) {
    return function () {
      let t = (seed += 0x6d2b79f5);
      t = Math.imul(t ^ (t >>> 15), t | 1);
      t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
      return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
    };
  }

  function shiftDate(dateStr, days) {
    const d = new Date(dateStr + 'T00:00:00');
    d.setDate(d.getDate() + days);
    return d.toISOString().slice(0, 10);
  }

  const FIRST = ['Emma','Liam','Noah','Ava','Olivia','James','Sophia','Mia','Lucas','Ethan','Isabella','Mason','Harper','Benjamin','Amelia','Charlotte'];
  const LAST  = ['Chen','Walker','Nguyen','Patel','Murphy','Bianchi','Okafor','Silva','Larsen','Kowalski'];

  function generatePipeline(houses) {
    const rand = pipeRand(42);
    const pipeline = [];
    let id = 1;
    const years = [2024, 2025, 2026];

    houses.forEach(house => {
      years.forEach(year => {
        for (let m = 0; m < 12; m++) {
          const seasonMult = 0.6 + Math.sin(((m + 3) / 12) * Math.PI * 2) * 0.4 + 0.4;
          const bookingsThisMonth = Math.max(1, Math.floor(3 + seasonMult * 4 + rand() * 2));

          for (let b = 0; b < bookingsThisMonth; b++) {
            const day = Math.floor(rand() * 27) + 1;
            const nights = Math.floor(rand() * 4) + 2;
            const amount = Math.round(house.nightlyRate * nights * (0.85 + rand() * 0.4));
            const channelRoll = rand();
            const channelName = channelRoll < 0.55 ? 'Airbnb' : channelRoll < 0.8 ? 'Lodgify' : 'Direct booking';
            const checkInDate  = `${year}-${String(m + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
            const checkOutDate = `${year}-${String(m + 1).padStart(2, '0')}-${String(Math.min(28, day + nights)).padStart(2, '0')}`;

            const isFuture = checkInDate > PIPELINE_TODAY;
            const paymentStatus = isFuture ? (rand() < 0.75 ? 'Paid' : 'Pending') : 'Paid';
            const paymentClearedAt = paymentStatus === 'Paid'
              ? shiftDate(checkInDate, -Math.floor(1 + rand() * 14))
              : null;

            const isCollected = paymentStatus === 'Paid' && checkInDate <= PIPELINE_TODAY;
            // Burn rand() calls that the original generator made so seasonal
            // distributions stay identical even though we skip the collected
            // path here. This keeps the visible pipeline stable across builds.
            if (isCollected) continue;

            pipeline.push({
              id: id++,
              houseId: house.id,
              date: checkInDate,
              checkInDate, checkOutDate, nights,
              type: 'income',
              category: channelName,
              description: `${nights}-night stay — ${FIRST[Math.floor(rand() * FIRST.length)]} ${LAST[Math.floor(rand() * LAST.length)]}`,
              amount,
              channel: channelName,
              source: channelName === 'Direct booking' ? 'direct' : 'lodgify',
              paymentStatus, paymentClearedAt,
            });
          }
        }
      });
    });

    return pipeline.sort((a, b) => a.checkInDate.localeCompare(b.checkInDate));
  }

  window.generatePipeline = generatePipeline;
})();
