import { MigrationInterface, QueryRunner, Table, TableIndex, TableForeignKey } from 'typeorm';

/**
 * Create CSV Bookings Table
 *
 * This table stores booking requests made from CSV rate search results.
 * Carriers receive email notifications with accept/reject links.
 */
export class CreateCsvBookingsTable1730000000010 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    // Create ENUM type for booking status
    await queryRunner.query(`
      CREATE TYPE csv_booking_status AS ENUM ('PENDING', 'ACCEPTED', 'REJECTED', 'CANCELLED');
    `);

    // Create csv_bookings table
    await queryRunner.createTable(
      new Table({
        name: 'csv_bookings',
        columns: [
          {
            name: 'id',
            type: 'uuid',
            isPrimary: true,
            generationStrategy: 'uuid',
            default: 'uuid_generate_v4()',
          },
          {
            name: 'user_id',
            type: 'uuid',
            isNullable: false,
          },
          {
            name: 'organization_id',
            type: 'uuid',
            isNullable: false,
          },
          {
            name: 'carrier_name',
            type: 'varchar',
            length: '255',
            isNullable: false,
          },
          {
            name: 'carrier_email',
            type: 'varchar',
            length: '255',
            isNullable: false,
          },
          {
            name: 'origin',
            type: 'varchar',
            length: '5',
            isNullable: false,
            comment: 'UN LOCODE for origin port',
          },
          {
            name: 'destination',
            type: 'varchar',
            length: '5',
            isNullable: false,
            comment: 'UN LOCODE for destination port',
          },
          {
            name: 'volume_cbm',
            type: 'decimal',
            precision: 10,
            scale: 2,
            isNullable: false,
            comment: 'Cargo volume in cubic meters',
          },
          {
            name: 'weight_kg',
            type: 'decimal',
            precision: 10,
            scale: 2,
            isNullable: false,
            comment: 'Cargo weight in kilograms',
          },
          {
            name: 'pallet_count',
            type: 'integer',
            isNullable: false,
            comment: 'Number of pallets',
          },
          {
            name: 'price_usd',
            type: 'decimal',
            precision: 10,
            scale: 2,
            isNullable: false,
            comment: 'Price in USD',
          },
          {
            name: 'price_eur',
            type: 'decimal',
            precision: 10,
            scale: 2,
            isNullable: false,
            comment: 'Price in EUR',
          },
          {
            name: 'primary_currency',
            type: 'varchar',
            length: '3',
            isNullable: false,
            comment: 'Primary currency (USD or EUR)',
          },
          {
            name: 'transit_days',
            type: 'integer',
            isNullable: false,
            comment: 'Estimated transit time in days',
          },
          {
            name: 'container_type',
            type: 'varchar',
            length: '50',
            isNullable: false,
            comment: 'Container type (LCL, FCL 20, FCL 40, etc.)',
          },
          {
            name: 'status',
            type: 'csv_booking_status',
            isNullable: false,
            default: "'PENDING'",
          },
          {
            name: 'documents',
            type: 'jsonb',
            isNullable: false,
            default: "'[]'",
            comment: 'Array of uploaded document metadata',
          },
          {
            name: 'confirmation_token',
            type: 'varchar',
            length: '255',
            isNullable: false,
            isUnique: true,
            comment: 'Unique token for carrier email confirmation links',
          },
          {
            name: 'requested_at',
            type: 'timestamp with time zone',
            isNullable: false,
            comment: 'When the booking request was created',
          },
          {
            name: 'responded_at',
            type: 'timestamp with time zone',
            isNullable: true,
            comment: 'When the carrier accepted or rejected the booking',
          },
          {
            name: 'notes',
            type: 'text',
            isNullable: true,
            comment: 'Additional notes from the user',
          },
          {
            name: 'rejection_reason',
            type: 'text',
            isNullable: true,
            comment: 'Reason provided by carrier for rejection',
          },
          {
            name: 'created_at',
            type: 'timestamp with time zone',
            isNullable: false,
            default: 'CURRENT_TIMESTAMP',
          },
          {
            name: 'updated_at',
            type: 'timestamp with time zone',
            isNullable: false,
            default: 'CURRENT_TIMESTAMP',
          },
        ],
      }),
      true
    );

    // Create indexes
    await queryRunner.createIndex(
      'csv_bookings',
      new TableIndex({
        name: 'IDX_csv_bookings_user_id',
        columnNames: ['user_id'],
      })
    );

    await queryRunner.createIndex(
      'csv_bookings',
      new TableIndex({
        name: 'IDX_csv_bookings_organization_id',
        columnNames: ['organization_id'],
      })
    );

    await queryRunner.createIndex(
      'csv_bookings',
      new TableIndex({
        name: 'IDX_csv_bookings_status',
        columnNames: ['status'],
      })
    );

    await queryRunner.createIndex(
      'csv_bookings',
      new TableIndex({
        name: 'IDX_csv_bookings_carrier_email',
        columnNames: ['carrier_email'],
      })
    );

    await queryRunner.createIndex(
      'csv_bookings',
      new TableIndex({
        name: 'IDX_csv_bookings_confirmation_token',
        columnNames: ['confirmation_token'],
      })
    );

    await queryRunner.createIndex(
      'csv_bookings',
      new TableIndex({
        name: 'IDX_csv_bookings_requested_at',
        columnNames: ['requested_at'],
      })
    );

    // Add foreign key constraints
    await queryRunner.createForeignKey(
      'csv_bookings',
      new TableForeignKey({
        columnNames: ['user_id'],
        referencedTableName: 'users',
        referencedColumnNames: ['id'],
        onDelete: 'CASCADE',
        name: 'FK_csv_bookings_user',
      })
    );

    await queryRunner.createForeignKey(
      'csv_bookings',
      new TableForeignKey({
        columnNames: ['organization_id'],
        referencedTableName: 'organizations',
        referencedColumnNames: ['id'],
        onDelete: 'CASCADE',
        name: 'FK_csv_bookings_organization',
      })
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    // Drop foreign keys
    await queryRunner.dropForeignKey('csv_bookings', 'FK_csv_bookings_organization');
    await queryRunner.dropForeignKey('csv_bookings', 'FK_csv_bookings_user');

    // Drop indexes
    await queryRunner.dropIndex('csv_bookings', 'IDX_csv_bookings_requested_at');
    await queryRunner.dropIndex('csv_bookings', 'IDX_csv_bookings_confirmation_token');
    await queryRunner.dropIndex('csv_bookings', 'IDX_csv_bookings_carrier_email');
    await queryRunner.dropIndex('csv_bookings', 'IDX_csv_bookings_status');
    await queryRunner.dropIndex('csv_bookings', 'IDX_csv_bookings_organization_id');
    await queryRunner.dropIndex('csv_bookings', 'IDX_csv_bookings_user_id');

    // Drop table
    await queryRunner.dropTable('csv_bookings', true);

    // Drop ENUM type
    await queryRunner.query(`DROP TYPE csv_booking_status;`);
  }
}
