import { MigrationInterface, QueryRunner } from "typeorm";

/**
 * Snapshot the booking-window rule onto each train schedule.
 *
 * A schedule's window (open time + reopen cycles) must be frozen to the rule it
 * was created with: a later global-rules edit applies only to FUTURE schedules,
 * while an already-open schedule keeps its base rule. Previously the batch board
 * recomputed windows from the LIVE global config, so editing the rule redrew the
 * board for open schedules (a synthetic grid that no longer matched the window
 * the customer was shown). These columns give the board a per-schedule rule to
 * derive its display windows from.
 *
 * Existing rows are backfilled from the current global-rules singleton — the best
 * available base, since they never stored one. Their stamped windowOpensAt/
 * windowClosesAt are still real, so only projected reopen cycles rely on the
 * backfill.
 */
export class AddScheduleWindowRuleSnapshot1920000000000
  implements MigrationInterface
{
  name = "AddScheduleWindowRuleSnapshot1920000000000";

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      ALTER TABLE freight.train_schedules
        ADD COLUMN IF NOT EXISTS rule_window_open_hour integer,
        ADD COLUMN IF NOT EXISTS rule_window_duration_hours numeric(6, 4),
        ADD COLUMN IF NOT EXISTS rule_reopen_delay_minutes integer,
        ADD COLUMN IF NOT EXISTS rule_import_window_lead_days integer,
        ADD COLUMN IF NOT EXISTS rule_export_booking_lead_hours integer;
    `);

    // Backfill from the global-rules singleton so pre-existing schedules render.
    await queryRunner.query(`
      UPDATE freight.train_schedules ts
      SET
        rule_window_open_hour = COALESCE(ts.rule_window_open_hour, r.window_open_hour),
        rule_window_duration_hours = COALESCE(ts.rule_window_duration_hours, r.window_duration_hours),
        rule_reopen_delay_minutes = COALESCE(ts.rule_reopen_delay_minutes, r.reopen_delay_minutes),
        rule_import_window_lead_days = COALESCE(ts.rule_import_window_lead_days, r.import_window_lead_days),
        rule_export_booking_lead_hours = COALESCE(ts.rule_export_booking_lead_hours, r.export_booking_lead_hours)
      FROM freight.train_scheduling_global_rules r
      WHERE ts.rule_window_open_hour IS NULL;
    `);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      ALTER TABLE freight.train_schedules
        DROP COLUMN IF EXISTS rule_window_open_hour,
        DROP COLUMN IF EXISTS rule_window_duration_hours,
        DROP COLUMN IF EXISTS rule_reopen_delay_minutes,
        DROP COLUMN IF EXISTS rule_import_window_lead_days,
        DROP COLUMN IF EXISTS rule_export_booking_lead_hours;
    `);
  }
}
