import { MigrationInterface, QueryRunner } from 'typeorm';

/**
 * Multi-locomotive train sets: a train set is now pulled by 2+ locomotives.
 *
 * Adds the `freight.train_set_locomotives` link table (train set ⇄ locomotive,
 * with an order index) and backfills one row per existing train set from its
 * current `locomotive_id`, so existing read paths keep resolving locomotives.
 * The `train_sets.locomotive_id` column is retained as the "primary" locomotive.
 *
 * NOTE: the shared dev DB has no applied migration history, so this is also
 * hand-applied there. IF NOT EXISTS keeps that idempotent.
 */
export class AddTrainSetLocomotives1820000000011 implements MigrationInterface {
  name = 'AddTrainSetLocomotives1820000000011';

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      CREATE TABLE IF NOT EXISTS freight.train_set_locomotives (
        id uuid NOT NULL DEFAULT uuid_generate_v4(),
        train_set_id uuid NOT NULL,
        locomotive_id uuid NOT NULL,
        sequence_no int NOT NULL DEFAULT 0,
        created_at timestamptz NOT NULL DEFAULT now(),
        updated_at timestamptz NOT NULL DEFAULT now(),
        deleted_at timestamptz,
        CONSTRAINT "PK_train_set_locomotives" PRIMARY KEY (id),
        CONSTRAINT "FK_train_set_locomotives_train_set" FOREIGN KEY (train_set_id)
          REFERENCES freight.train_sets (id) ON DELETE CASCADE,
        CONSTRAINT "FK_train_set_locomotives_locomotive" FOREIGN KEY (locomotive_id)
          REFERENCES freight.locomotives (id)
      );
    `);

    await queryRunner.query(`
      CREATE UNIQUE INDEX IF NOT EXISTS "UQ_train_set_locomotives_set_loco"
        ON freight.train_set_locomotives (train_set_id, locomotive_id);
    `);

    // Backfill: one link row per existing train set, from its current primary loco.
    await queryRunner.query(`
      INSERT INTO freight.train_set_locomotives (train_set_id, locomotive_id, sequence_no)
      SELECT ts.id, ts.locomotive_id, 0
      FROM freight.train_sets ts
      WHERE ts.locomotive_id IS NOT NULL
        AND NOT EXISTS (
          SELECT 1 FROM freight.train_set_locomotives tsl
          WHERE tsl.train_set_id = ts.id AND tsl.locomotive_id = ts.locomotive_id
        );
    `);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `DROP INDEX IF EXISTS freight."UQ_train_set_locomotives_set_loco";`,
    );
    await queryRunner.query(`DROP TABLE IF EXISTS freight.train_set_locomotives;`);
  }
}
