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

export class CreateActivityTicketTables1778500000000 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    // Enums
    await queryRunner.query(`
      CREATE TYPE "ticket_batch_status_enum" AS ENUM ('ACTIVE', 'EXHAUSTED', 'EXPIRED', 'CANCELLED')
    `);
    await queryRunner.query(`
      CREATE TYPE "ticket_item_status_enum" AS ENUM ('AVAILABLE', 'ASSIGNED', 'CANCELLED', 'EXPIRED', 'WASTED')
    `);
    await queryRunner.query(`
      CREATE TYPE "ticket_dispatch_via_enum" AS ENUM ('WHATSAPP', 'EMAIL', 'PHYSICAL')
    `);

    // activity_ticket_batches
    await queryRunner.query(`
      CREATE TABLE "activity_ticket_batches" (
        "id"            UUID NOT NULL DEFAULT uuid_generate_v4(),
        "tenant_id"     UUID NOT NULL,
        "created_by"    UUID,
        "updated_by"    UUID,
        "created_at"    TIMESTAMPTZ NOT NULL DEFAULT now(),
        "updated_at"    TIMESTAMPTZ NOT NULL DEFAULT now(),
        "is_deleted"    BOOLEAN NOT NULL DEFAULT false,
        "activity_id"   UUID NOT NULL,
        "ticket_type"   VARCHAR(100) NOT NULL,
        "age_group"     VARCHAR(50) NOT NULL,
        "supplier_id"   UUID,
        "valid_from"    DATE,
        "valid_to"      DATE,
        "time_slot"     VARCHAR(50),
        "total_qty"     INT NOT NULL DEFAULT 0,
        "available_qty" INT NOT NULL DEFAULT 0,
        "status"        "ticket_batch_status_enum" NOT NULL DEFAULT 'ACTIVE',
        "notes"         TEXT,
        CONSTRAINT "PK_activity_ticket_batches" PRIMARY KEY ("id"),
        CONSTRAINT "FK_atb_activity" FOREIGN KEY ("activity_id")
          REFERENCES "activities"("id") ON DELETE RESTRICT,
        CONSTRAINT "FK_atb_supplier" FOREIGN KEY ("supplier_id")
          REFERENCES "suppliers"("id") ON DELETE RESTRICT
      )
    `);

    // activity_ticket_items
    await queryRunner.query(`
      CREATE TABLE "activity_ticket_items" (
        "id"                        UUID NOT NULL DEFAULT uuid_generate_v4(),
        "tenant_id"                 UUID NOT NULL,
        "created_by"                UUID,
        "updated_by"                UUID,
        "created_at"                TIMESTAMPTZ NOT NULL DEFAULT now(),
        "updated_at"                TIMESTAMPTZ NOT NULL DEFAULT now(),
        "is_deleted"                BOOLEAN NOT NULL DEFAULT false,
        "batch_id"                  UUID NOT NULL,
        "ticket_ref_no"             VARCHAR(255) NOT NULL,
        "document_url"              VARCHAR(500),
        "status"                    "ticket_item_status_enum" NOT NULL DEFAULT 'AVAILABLE',
        "booking_activity_item_id"  UUID,
        "assigned_by"               UUID,
        "assigned_at"               TIMESTAMPTZ,
        "dispatched_via"            "ticket_dispatch_via_enum",
        "dispatched_at"             TIMESTAMPTZ,
        "notes"                     TEXT,
        CONSTRAINT "PK_activity_ticket_items" PRIMARY KEY ("id"),
        CONSTRAINT "FK_ati_batch" FOREIGN KEY ("batch_id")
          REFERENCES "activity_ticket_batches"("id") ON DELETE CASCADE,
        CONSTRAINT "FK_ati_booking_activity_item" FOREIGN KEY ("booking_activity_item_id")
          REFERENCES "booking_activity_items"("id") ON DELETE SET NULL
      )
    `);

    // Indexes
    await queryRunner.query(
      `CREATE INDEX "IDX_atb_tenant_deleted" ON "activity_ticket_batches" ("tenant_id", "is_deleted")`,
    );
    await queryRunner.query(
      `CREATE INDEX "IDX_atb_tenant_activity" ON "activity_ticket_batches" ("tenant_id", "activity_id")`,
    );
    await queryRunner.query(
      `CREATE INDEX "IDX_ati_tenant_deleted" ON "activity_ticket_items" ("tenant_id", "is_deleted")`,
    );
    await queryRunner.query(`CREATE INDEX "IDX_ati_batch" ON "activity_ticket_items" ("batch_id")`);
    await queryRunner.query(
      `CREATE INDEX "IDX_ati_booking_activity" ON "activity_ticket_items" ("booking_activity_item_id")`,
    );

    // Unique: one ref_no per batch per tenant (prevents duplicate allocation)
    await queryRunner.query(`
      CREATE UNIQUE INDEX "UQ_ati_tenant_batch_ref"
        ON "activity_ticket_items" ("tenant_id", "batch_id", "ticket_ref_no")
        WHERE "is_deleted" = false
    `);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`DROP TABLE IF EXISTS "activity_ticket_items"`);
    await queryRunner.query(`DROP TABLE IF EXISTS "activity_ticket_batches"`);
    await queryRunner.query(`DROP TYPE IF EXISTS "ticket_dispatch_via_enum"`);
    await queryRunner.query(`DROP TYPE IF EXISTS "ticket_item_status_enum"`);
    await queryRunner.query(`DROP TYPE IF EXISTS "ticket_batch_status_enum"`);
  }
}
