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

export class AddServiceTypesAndCargoTypes1748427600000 implements MigrationInterface {
  name = "AddServiceTypesAndCargoTypes1748427600000";

  public async up(queryRunner: QueryRunner): Promise<void> {
    // Create service_types table
    if (!(await queryRunner.hasTable("freight.service_types"))) await queryRunner.createTable(
      new Table({
        name: "service_types",
        schema: "freight",
        columns: [
          {
            name: "id",
            type: "uuid",
            isPrimary: true,
            generationStrategy: "uuid",
            default: "uuid_generate_v4()",
          },
          {
            name: "service_name",
            type: "varchar",
            length: "255",
            isNullable: false,
          },
          {
            name: "description",
            type: "text",
            isNullable: true,
          },
          {
            name: "can_be_booked_alone",
            type: "boolean",
            default: true,
            isNullable: false,
          },
          {
            name: "includes_first_mile",
            type: "boolean",
            default: false,
            isNullable: false,
          },
          {
            name: "includes_last_mile",
            type: "boolean",
            default: false,
            isNullable: false,
          },
          {
            name: "includes_customs",
            type: "boolean",
            default: false,
            isNullable: false,
          },
          {
            name: "priority_bonus_points",
            type: "int",
            default: 0,
            isNullable: false,
          },
          {
            name: "is_active",
            type: "boolean",
            default: true,
            isNullable: false,
          },
          {
            name: "display_order",
            type: "int",
            default: 1,
            isNullable: false,
          },
          {
            name: "created_at",
            type: "timestamptz",
            default: "now()",
            isNullable: false,
          },
          {
            name: "updated_at",
            type: "timestamptz",
            default: "now()",
            isNullable: false,
          },
          {
            name: "deleted_at",
            type: "timestamptz",
            isNullable: true,
          },
        ],
      }),
      true,
    );

    // Create indexes for service_types
    await queryRunner.createIndex(
      "freight.service_types",
      new TableIndex({
        name: "IDX_SERVICE_TYPES_IS_ACTIVE",
        columnNames: ["is_active"],
      }),
    );
    await queryRunner.createIndex(
      "freight.service_types",
      new TableIndex({
        name: "IDX_SERVICE_TYPES_DISPLAY_ORDER",
        columnNames: ["display_order"],
      }),
    );

    // Create cargo_types table
    if (!(await queryRunner.hasTable("freight.cargo_types"))) await queryRunner.createTable(
      new Table({
        name: "cargo_types",
        schema: "freight",
        columns: [
          {
            name: "id",
            type: "uuid",
            isPrimary: true,
            generationStrategy: "uuid",
            default: "uuid_generate_v4()",
          },
          {
            name: "cargo_type_name",
            type: "varchar",
            length: "255",
            isNullable: false,
          },
          {
            name: "parent_group_id",
            type: "uuid",
            isNullable: true,
          },
          {
            name: "show_free_text_box",
            type: "boolean",
            default: false,
            isNullable: false,
          },
          {
            name: "requires_director_approval",
            type: "boolean",
            default: false,
            isNullable: false,
          },
          {
            name: "is_active",
            type: "boolean",
            default: true,
            isNullable: false,
          },
          {
            name: "display_order",
            type: "int",
            default: 1,
            isNullable: false,
          },
          {
            name: "created_at",
            type: "timestamptz",
            default: "now()",
            isNullable: false,
          },
          {
            name: "updated_at",
            type: "timestamptz",
            default: "now()",
            isNullable: false,
          },
          {
            name: "deleted_at",
            type: "timestamptz",
            isNullable: true,
          },
        ],
      }),
      true,
    );

    // Create indexes for cargo_types
    await queryRunner.createIndex(
      "freight.cargo_types",
      new TableIndex({
        name: "IDX_CARGO_TYPES_IS_ACTIVE",
        columnNames: ["is_active"],
      }),
    );
    await queryRunner.createIndex(
      "freight.cargo_types",
      new TableIndex({
        name: "IDX_CARGO_TYPES_DISPLAY_ORDER",
        columnNames: ["display_order"],
      }),
    );
    await queryRunner.createIndex(
      "freight.cargo_types",
      new TableIndex({
        name: "IDX_CARGO_TYPES_PARENT_GROUP_ID",
        columnNames: ["parent_group_id"],
      }),
    );

    // Create self-referencing foreign key for cargo_types
    await queryRunner.createForeignKey(
      "freight.cargo_types",
      new TableForeignKey({
        name: "FK_CARGO_TYPES_PARENT_GROUP",
        columnNames: ["parent_group_id"],
        referencedSchema: "freight",
        referencedTableName: "cargo_types",
        referencedColumnNames: ["id"],
        onDelete: "SET NULL",
      }),
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    // Drop foreign key first
    await queryRunner.dropForeignKey("freight.cargo_types", "FK_CARGO_TYPES_PARENT_GROUP");

    // Drop cargo_types table
    await queryRunner.dropTable("freight.cargo_types", true);

    // Drop service_types table
    await queryRunner.dropTable("freight.service_types", true);
  }
}
