import { type MigrationInterface, type QueryRunner } from 'typeorm';

/**
 * Catch-up migration — creates all tables that should have been in
 * the InitialSchema but weren't. The original InitialSchema (1775555814626)
 * was generated before the booking module / notifications / supplier
 * cost prices / tags / tax slabs landed, and those tables ended up
 * being created via `synchronize: true` in dev — never captured by a
 * migration.
 *
 * Result: any fresh DB (UAT, prod) running migrations from scratch
 * gets stuck at AddIsDayItemToSpecials1776100000000 because
 * `booking_special_items` doesn't exist yet.
 *
 * This migration is idempotent: it checks `hasTable('bookings')` and
 * is a no-op when the booking module is already installed (i.e. on
 * any local dev DB created via synchronize). On UAT/prod where those
 * tables don't exist, it creates the lot:
 *
 *   12 tables: bookings, booking_hotel_items, booking_transport_items,
 *              booking_activity_items, booking_special_items,
 *              booking_flight_details, booking_change_requests,
 *              notifications, supplier_cost_prices, tags,
 *              tax_components, tax_slabs
 *   3 enums:   booking_change_requests_kind_enum,
 *              booking_change_requests_status_enum,
 *              notifications_kind_enum
 *   + primary keys, unique partial indexes, FK relations
 *
 * Timestamp 1776000000000 places this AFTER SeasonDateToMMDD
 * (1775556000000) and BEFORE AddIsDayItemToSpecials (1776100000000),
 * so the booking_special_items table exists in time for the day-item
 * column ADD.
 */
export class CatchUpMissingTables1776000000000 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    // No-op when the booking module is already installed.
    if (await queryRunner.hasTable('bookings')) return;

    // ── Enums ────────────────────────────────────────────────────
    // CREATE TYPE has no IF NOT EXISTS in older PG, so wrap in DO blocks.
    await queryRunner.query(`
      DO $$ BEGIN
        IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'booking_change_requests_kind_enum') THEN
          CREATE TYPE "booking_change_requests_kind_enum" AS ENUM ('itinerary', 'zero_value', 'selling_price', 'below_floor_price');
        END IF;
      END $$;
    `);
    await queryRunner.query(`
      DO $$ BEGIN
        IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'booking_change_requests_status_enum') THEN
          CREATE TYPE "booking_change_requests_status_enum" AS ENUM ('pending', 'approved', 'rejected', 'on_hold', 'withdrawn');
        END IF;
      END $$;
    `);
    await queryRunner.query(`
      DO $$ BEGIN
        IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'notifications_kind_enum') THEN
          CREATE TYPE "notifications_kind_enum" AS ENUM ('change_request_pending', 'change_request_decided');
        END IF;
      END $$;
    `);

    // ── Tables ───────────────────────────────────────────────────
    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "bookings" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "booking_number" character varying(20) NOT NULL,
      "query_id" uuid NOT NULL,
      "quote_id" uuid NOT NULL,
      "hotel_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "transport_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "activity_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "special_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "grand_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "status" character varying(20) DEFAULT 'upcoming' NOT NULL,
      "notes" text,
      "selling_currency_id" uuid,
      "exchange_rate" numeric(12,6) DEFAULT '1' NOT NULL,
      "selling_hotel_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "selling_transport_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "selling_activity_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "selling_special_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "selling_total" numeric(12,2) DEFAULT '0' NOT NULL,
      "is_quick_booking" boolean DEFAULT false NOT NULL,
      CONSTRAINT "PK_bee6805982cc1e248e94ce94957" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "booking_hotel_items" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "booking_id" uuid NOT NULL,
      "hotel_id" uuid NOT NULL,
      "room_type" character varying(100),
      "meal_plan" character varying(100),
      "check_in_date" date NOT NULL,
      "check_out_date" date NOT NULL,
      "nights" integer NOT NULL,
      "pax_per_room" integer DEFAULT 1 NOT NULL,
      "num_rooms" integer DEFAULT 1 NOT NULL,
      "aweb" integer DEFAULT 0 NOT NULL,
      "cweb" integer DEFAULT 0 NOT NULL,
      "cnb" integer DEFAULT 0 NOT NULL,
      "nightly_rates" text,
      "subtotal" numeric(12,2) DEFAULT '0' NOT NULL,
      "notes" text,
      CONSTRAINT "PK_c90f3c315020ae18c1a6bd5330f" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "booking_transport_items" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "booking_id" uuid NOT NULL,
      "transport_service_id" uuid NOT NULL,
      "quantity" integer DEFAULT 1 NOT NULL,
      "unit_price" numeric(12,2) DEFAULT '0' NOT NULL,
      "subtotal" numeric(12,2) DEFAULT '0' NOT NULL,
      "date" date,
      "sort_order" integer DEFAULT 0 NOT NULL,
      "notes" text,
      "supplier_id" uuid,
      "driver_id" uuid,
      "vehicle_id" uuid,
      "pickup_time" character varying(10),
      "pickup_address" character varying(500),
      "dropoff_address" character varying(500),
      "assignment_status" character varying(20),
      "is_shared" boolean DEFAULT false NOT NULL,
      "driver_name_text" character varying(255),
      "driver_phone_text" character varying(20),
      "supplier_name_text" character varying(255),
      "vehicle_no_text" character varying(50),
      "supplier_2_id" uuid,
      "supplier_2_name_text" character varying(255),
      "adults_override" integer,
      "children_override" integer,
      "op_status" character varying(20) DEFAULT 'PLANNED' NOT NULL,
      "op_status_at" timestamp without time zone,
      "return_pickup_time" character varying(10),
      "pickup_notes" text,
      "dropoff_notes" text,
      "linked_activity_id" uuid,
      "vehicle_type_id" uuid,
      CONSTRAINT "PK_ac4d1b1e088131dc52804942c56" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "booking_activity_items" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "booking_id" uuid NOT NULL,
      "activity_id" uuid NOT NULL,
      "ticket_id" uuid,
      "age_group" character varying(50) NOT NULL,
      "quantity" integer DEFAULT 1 NOT NULL,
      "unit_price" numeric(12,2) DEFAULT '0' NOT NULL,
      "subtotal" numeric(12,2) DEFAULT '0' NOT NULL,
      "slot" character varying(100),
      "date" date,
      "sort_order" integer DEFAULT 0 NOT NULL,
      "notes" text,
      "supplier_id" uuid,
      "ticket_file_url" character varying(500),
      "assignment_status" character varying(20),
      "supplier_name_text" character varying(255),
      "supplier_phone_text" character varying(20),
      "adults_override" integer,
      "children_override" integer,
      "op_status" character varying(20) DEFAULT 'PLANNED' NOT NULL,
      "op_status_at" timestamp without time zone,
      CONSTRAINT "PK_bc2ff72a2cf059f3e66f0a73403" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "booking_special_items" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "booking_id" uuid NOT NULL,
      "service_name" character varying(255) NOT NULL,
      "total_price" numeric(12,2) NOT NULL,
      "date" date,
      "sort_order" integer DEFAULT 0 NOT NULL,
      "comments" text,
      CONSTRAINT "PK_d6a432e4d2901225151e6b729c3" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "booking_flight_details" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "booking_id" uuid NOT NULL,
      "transport_item_id" uuid,
      "direction" character varying(50),
      "flight_number" character varying(50) NOT NULL,
      "airline" character varying(100),
      "origin_airport" character varying(10),
      "destination_airport" character varying(10),
      "departure_time" character varying(25),
      "arrival_time" character varying(25),
      "terminal" character varying(50),
      "gate" character varying(50),
      "pnr" character varying(100),
      "notes" text,
      CONSTRAINT "PK_2f02b215b2f49f0df21f704ed38" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "booking_change_requests" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "booking_id" uuid NOT NULL,
      "kind" booking_change_requests_kind_enum NOT NULL,
      "status" booking_change_requests_status_enum DEFAULT 'pending' NOT NULL,
      "requester_id" uuid,
      "requester_remarks" text NOT NULL,
      "decided_by" uuid,
      "decision_remarks" text,
      "decided_at" timestamp with time zone,
      "payload" jsonb NOT NULL,
      "before_snapshot" jsonb,
      CONSTRAINT "PK_047c927611db00dc8115bcab3f2" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "notifications" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "user_id" uuid NOT NULL,
      "kind" notifications_kind_enum NOT NULL,
      "title" character varying(255) NOT NULL,
      "message" text NOT NULL,
      "link" character varying(500),
      "related_entity_type" character varying(100),
      "related_entity_id" uuid,
      "is_read" boolean DEFAULT false NOT NULL,
      "read_at" timestamp with time zone,
      CONSTRAINT "PK_6a72c3c0f683f6462415e653c3a" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "supplier_cost_prices" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "supplier_id" uuid NOT NULL,
      "transport_service_id" uuid NOT NULL,
      "vehicle_type_id" uuid,
      "season_id" uuid,
      "cost_price" numeric(12,2) DEFAULT '0' NOT NULL,
      "currency_id" uuid,
      "notes" text,
      "is_active" boolean DEFAULT true NOT NULL,
      "mode" character varying(8) DEFAULT 'PVT' NOT NULL,
      CONSTRAINT "PK_5b2921426decb1e4093d8752268" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "tags" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "name" character varying(100) NOT NULL,
      "type" character varying(20) DEFAULT 'remark' NOT NULL,
      CONSTRAINT "PK_e7dc17249a1148a1970748eda99" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "tax_components" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "name" character varying(100) NOT NULL,
      "sort_order" integer DEFAULT 0 NOT NULL,
      "tax_type_id" uuid NOT NULL,
      "is_active" boolean DEFAULT true NOT NULL,
      CONSTRAINT "PK_004f5fd44eb6ed3165c458ee7d1" PRIMARY KEY (id)
    )`);

    await queryRunner.query(`CREATE TABLE IF NOT EXISTS "tax_slabs" (
      "id" uuid DEFAULT uuid_generate_v4() NOT NULL,
      "tenant_id" uuid NOT NULL,
      "created_by" uuid,
      "updated_by" uuid,
      "created_at" timestamp with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
      "is_deleted" boolean DEFAULT false NOT NULL,
      "tax_type_id" uuid NOT NULL,
      "destination_id" uuid NOT NULL,
      "total_rate" numeric(5,2) DEFAULT '0' NOT NULL,
      "notes" text,
      "is_active" boolean DEFAULT true NOT NULL,
      "component_rates" jsonb,
      CONSTRAINT "PK_9138b80c90b7096dbbd9b43d6aa" PRIMARY KEY (id)
    )`);

    // ── Indexes ──────────────────────────────────────────────────
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_0c41823fa6a879a6aeba177465" ON "bookings" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_0198df42452691d684870e6046" ON "bookings" ("tenant_id", "booking_number") WHERE (is_deleted = false)`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_6ed4c4716b99948d4356fb8917" ON "booking_hotel_items" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_e576f7c4d6831eea7e0c9de86d" ON "booking_transport_items" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_d57fdc8fe7199f9f3ac324be7f" ON "booking_activity_items" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_d31f43113618f6731013d9a879" ON "booking_special_items" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_de8328e900aa943b38d692efa5" ON "booking_flight_details" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_963d139459ec1d1c8699f66116" ON "booking_change_requests" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_4c3134704c1cc3d6b1815ede72" ON "booking_change_requests" ("tenant_id", "status")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_ea74a5387ee59fa761bd594726" ON "booking_change_requests" ("booking_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_d93ddd7e1b890535ecafbb334e" ON "notifications" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_22ebb4e81d60e0a942ac0b2717" ON "notifications" ("tenant_id", "user_id", "is_read")`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_a4ff5b8687c5a7925bb0f21403" ON "supplier_cost_prices" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_scp_pvt_default_unique" ON "supplier_cost_prices" ("tenant_id", "supplier_id", "transport_service_id", "vehicle_type_id", "mode") WHERE (is_deleted = false AND mode = 'PVT' AND season_id IS NULL)`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_scp_pvt_seasoned_unique" ON "supplier_cost_prices" ("tenant_id", "supplier_id", "transport_service_id", "vehicle_type_id", "mode", "season_id") WHERE (is_deleted = false AND mode = 'PVT' AND season_id IS NOT NULL)`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_scp_sic_default_unique" ON "supplier_cost_prices" ("tenant_id", "supplier_id", "transport_service_id", "mode") WHERE (is_deleted = false AND mode = 'SIC' AND vehicle_type_id IS NULL AND season_id IS NULL)`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_scp_sic_seasoned_unique" ON "supplier_cost_prices" ("tenant_id", "supplier_id", "transport_service_id", "mode", "season_id") WHERE (is_deleted = false AND mode = 'SIC' AND vehicle_type_id IS NULL AND season_id IS NOT NULL)`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_4c9d89c0373bf1e54134eb21ea" ON "tags" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_1ceee620fefd7efb35352dcf43" ON "tags" ("tenant_id", "name", "type") WHERE (is_deleted = false)`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_e10d1049c7fd76b43d9f03fb61" ON "tax_components" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_0f515bcedf8d300170160b184f" ON "tax_components" ("tenant_id", "tax_type_id", "name") WHERE (is_deleted = false)`,
    );
    await queryRunner.query(
      `CREATE INDEX IF NOT EXISTS "IDX_c20cdaab2d6373e2bcb8160508" ON "tax_slabs" ("tenant_id")`,
    );
    await queryRunner.query(
      `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_f400d50d61efaee1b2c7fc9ea1" ON "tax_slabs" ("tenant_id", "tax_type_id", "destination_id") WHERE (is_deleted = false)`,
    );

    // ── Foreign keys ─────────────────────────────────────────────
    // Wrapped order matters — child tables reference parent tables.
    await queryRunner.query(
      `ALTER TABLE "bookings" ADD CONSTRAINT "FK_c38b1051c03cad97437d47e0121" FOREIGN KEY ("query_id") REFERENCES "queries"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "bookings" ADD CONSTRAINT "FK_a375ce9ae5929cf25cfc9127d60" FOREIGN KEY ("quote_id") REFERENCES "query_quotes"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "bookings" ADD CONSTRAINT "FK_1c0dbf48d0ee95d8384b5d92486" FOREIGN KEY ("selling_currency_id") REFERENCES "currencies"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_hotel_items" ADD CONSTRAINT "FK_d7193b081c6e1d5e5d60392291b" FOREIGN KEY ("booking_id") REFERENCES "bookings"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_hotel_items" ADD CONSTRAINT "FK_0698ec1eb5482fee67bcb9eca55" FOREIGN KEY ("hotel_id") REFERENCES "hotels"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_activity_items" ADD CONSTRAINT "FK_4f517f2838c47fe9e799dc694d3" FOREIGN KEY ("booking_id") REFERENCES "bookings"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_activity_items" ADD CONSTRAINT "FK_81973d6b6c92ecae248b7ab4426" FOREIGN KEY ("activity_id") REFERENCES "activities"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_activity_items" ADD CONSTRAINT "FK_920c0f228d557b488170754fc94" FOREIGN KEY ("ticket_id") REFERENCES "activity_tickets"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_activity_items" ADD CONSTRAINT "FK_d586e76e3889a68c90fedde02a1" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_transport_items" ADD CONSTRAINT "FK_570167744e3750c9e257502d2bc" FOREIGN KEY ("booking_id") REFERENCES "bookings"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_transport_items" ADD CONSTRAINT "FK_2e4df3f5510dc88f3fd925e0eaf" FOREIGN KEY ("transport_service_id") REFERENCES "transport_services"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_transport_items" ADD CONSTRAINT "FK_b58c489bbf972e7f9877e9dbe50" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_transport_items" ADD CONSTRAINT "FK_2005bb6e8f1e086361229aa4aee" FOREIGN KEY ("driver_id") REFERENCES "drivers"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_transport_items" ADD CONSTRAINT "FK_d49286a488c761d6f5c0c67b000" FOREIGN KEY ("vehicle_id") REFERENCES "vehicles"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_transport_items" ADD CONSTRAINT "FK_cb57531a55dee8fc5d3d950e6d0" FOREIGN KEY ("vehicle_type_id") REFERENCES "vehicle_types"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_transport_items" ADD CONSTRAINT "FK_33577666ee4b4e79ca9fabd7119" FOREIGN KEY ("linked_activity_id") REFERENCES "booking_activity_items"("id") ON DELETE SET NULL`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_special_items" ADD CONSTRAINT "FK_06eebe3cbdd571f7eb58cd9caa6" FOREIGN KEY ("booking_id") REFERENCES "bookings"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_flight_details" ADD CONSTRAINT "FK_3aeacf62490e6c5a9bb627f143c" FOREIGN KEY ("booking_id") REFERENCES "bookings"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_flight_details" ADD CONSTRAINT "FK_61324a8bb1d1edbe97f58454924" FOREIGN KEY ("transport_item_id") REFERENCES "booking_transport_items"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_change_requests" ADD CONSTRAINT "FK_ea74a5387ee59fa761bd594726b" FOREIGN KEY ("booking_id") REFERENCES "bookings"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_change_requests" ADD CONSTRAINT "FK_925f2cc2b20c1db54775e73300c" FOREIGN KEY ("requester_id") REFERENCES "users"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "booking_change_requests" ADD CONSTRAINT "FK_8fbeb6767dddd9f0b97851d7cc5" FOREIGN KEY ("decided_by") REFERENCES "users"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "notifications" ADD CONSTRAINT "FK_9a8a82462cab47c73d25f49261f" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "supplier_cost_prices" ADD CONSTRAINT "FK_b0b4984383fb5f027e98a844ed6" FOREIGN KEY ("supplier_id") REFERENCES "suppliers"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "supplier_cost_prices" ADD CONSTRAINT "FK_7c43480fa2f5ed546c946d82213" FOREIGN KEY ("transport_service_id") REFERENCES "transport_services"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "supplier_cost_prices" ADD CONSTRAINT "FK_d963f5a59c2db13c2254f1f3189" FOREIGN KEY ("vehicle_type_id") REFERENCES "vehicle_types"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "supplier_cost_prices" ADD CONSTRAINT "FK_e2d568b91d9a37417358dcad212" FOREIGN KEY ("season_id") REFERENCES "seasons"("id") ON DELETE SET NULL`,
    );
    await queryRunner.query(
      `ALTER TABLE "supplier_cost_prices" ADD CONSTRAINT "FK_90e333cda441ec3a0bd460249a5" FOREIGN KEY ("currency_id") REFERENCES "currencies"("id")`,
    );
    await queryRunner.query(
      `ALTER TABLE "tax_components" ADD CONSTRAINT "FK_f53f720ad1143cbef1bea6719f3" FOREIGN KEY ("tax_type_id") REFERENCES "tax_types"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "tax_slabs" ADD CONSTRAINT "FK_bf86f04ad14c696b7bcb1ccc777" FOREIGN KEY ("tax_type_id") REFERENCES "tax_types"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "tax_slabs" ADD CONSTRAINT "FK_262eacc1271aeb62041aff3abeb" FOREIGN KEY ("destination_id") REFERENCES "destinations"("id") ON DELETE CASCADE`,
    );
  }

  public async down(): Promise<void> {
    // No-op down — this migration backfills missing schema for fresh
    // installs. Reversing it would drop production data; if a rollback
    // is ever needed, do it manually by dropping the listed tables +
    // enums in reverse FK order.
  }
}
