import { MigrationInterface, QueryRunner } from "typeorm";

/**
 * Make the payment projection source-agnostic so any domain (not just bookings)
 * can own a payment intent.
 *
 *   - `payments.type` enum `('booking')` → `varchar(50)`. It now stores the
 *     invoice SOURCE (e.g. 'booking', 'demurrage'), supplied by the caller, so a
 *     new domain no longer needs an enum migration to write its intents.
 *   - adds `payments.reference_type varchar(40)` — the gateway reference type
 *     (`PaymentReferenceType`) the intent was opened with, so the reconcile/poll
 *     path can query the provider without hardcoding it.
 *
 * Matches payment/entities/payment.entity.ts.
 */
export class MakePaymentsTypeGeneric1821000000004 implements MigrationInterface {
  name = "MakePaymentsTypeGeneric1821000000004";

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `ALTER TABLE freight.payments ALTER COLUMN type TYPE varchar(50) USING type::text;`,
    );
    await queryRunner.query(`DROP TYPE IF EXISTS freight.payments_type_enum;`);

    await queryRunner.query(
      `ALTER TABLE freight.payments ADD COLUMN reference_type varchar(40);`,
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `ALTER TABLE freight.payments DROP COLUMN IF EXISTS reference_type;`,
    );

    // Restore the single-value enum. Any non-'booking' rows would block the cast;
    // collapse them first so the down migration is safe.
    await queryRunner.query(
      `UPDATE freight.payments SET type = 'booking' WHERE type <> 'booking';`,
    );
    await queryRunner.query(
      `CREATE TYPE freight.payments_type_enum AS ENUM ('booking');`,
    );
    await queryRunner.query(
      `ALTER TABLE freight.payments ALTER COLUMN type TYPE freight.payments_type_enum USING type::freight.payments_type_enum;`,
    );
  }
}
