import { MigrationInterface, QueryRunner } from 'typeorm';

/**
 * Rename subscription plans:
 * FREE -> BRONZE, STARTER -> SILVER, PRO -> GOLD, ENTERPRISE -> PLATINIUM
 *
 * PostgreSQL does not support removing values from an enum type directly,
 * so we create a new enum, migrate the column, and drop the old one.
 */
export class RenamePlansToBronzeSilverGoldPlatinium1740000000001 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    // Step 1: Create new enum type
    await queryRunner.query(
      `CREATE TYPE "subscription_plan_enum_new" AS ENUM ('BRONZE', 'SILVER', 'GOLD', 'PLATINIUM')`
    );

    // Step 2: Convert the column to VARCHAR temporarily so we can update values
    await queryRunner.query(`ALTER TABLE "subscriptions" ALTER COLUMN "plan" TYPE VARCHAR(20)`);

    // Step 3: Update existing values
    await queryRunner.query(`UPDATE "subscriptions" SET "plan" = 'BRONZE' WHERE "plan" = 'FREE'`);
    await queryRunner.query(
      `UPDATE "subscriptions" SET "plan" = 'SILVER' WHERE "plan" = 'STARTER'`
    );
    await queryRunner.query(`UPDATE "subscriptions" SET "plan" = 'GOLD' WHERE "plan" = 'PRO'`);
    await queryRunner.query(
      `UPDATE "subscriptions" SET "plan" = 'PLATINIUM' WHERE "plan" = 'ENTERPRISE'`
    );

    // Step 4: Drop existing default (required before changing enum type)
    await queryRunner.query(`ALTER TABLE "subscriptions" ALTER COLUMN "plan" DROP DEFAULT`);

    // Step 5: Set column to new enum type
    await queryRunner.query(
      `ALTER TABLE "subscriptions" ALTER COLUMN "plan" TYPE "subscription_plan_enum_new" USING "plan"::"subscription_plan_enum_new"`
    );

    // Step 6: Set new default
    await queryRunner.query(`ALTER TABLE "subscriptions" ALTER COLUMN "plan" SET DEFAULT 'BRONZE'`);

    // Step 7: Drop old enum type (name may vary — TypeORM often creates it as subscriptions_plan_enum)
    // We handle both possible names
    await queryRunner.query(`
      DO $$ BEGIN
        IF EXISTS (SELECT 1 FROM pg_type WHERE typname = 'subscriptions_plan_enum') THEN
          DROP TYPE "subscriptions_plan_enum";
        END IF;
      END $$;
    `);

    // Step 8: Rename new enum to standard name
    await queryRunner.query(
      `ALTER TYPE "subscription_plan_enum_new" RENAME TO "subscriptions_plan_enum"`
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    // Reverse: create old enum, migrate back
    await queryRunner.query(
      `CREATE TYPE "subscription_plan_enum_old" AS ENUM ('FREE', 'STARTER', 'PRO', 'ENTERPRISE')`
    );

    await queryRunner.query(`ALTER TABLE "subscriptions" ALTER COLUMN "plan" TYPE VARCHAR(20)`);

    await queryRunner.query(`UPDATE "subscriptions" SET "plan" = 'FREE' WHERE "plan" = 'BRONZE'`);
    await queryRunner.query(
      `UPDATE "subscriptions" SET "plan" = 'STARTER' WHERE "plan" = 'SILVER'`
    );
    await queryRunner.query(`UPDATE "subscriptions" SET "plan" = 'PRO' WHERE "plan" = 'GOLD'`);
    await queryRunner.query(
      `UPDATE "subscriptions" SET "plan" = 'ENTERPRISE' WHERE "plan" = 'PLATINIUM'`
    );

    await queryRunner.query(
      `ALTER TABLE "subscriptions" ALTER COLUMN "plan" TYPE "subscription_plan_enum_old" USING "plan"::"subscription_plan_enum_old"`
    );

    await queryRunner.query(`ALTER TABLE "subscriptions" ALTER COLUMN "plan" SET DEFAULT 'FREE'`);

    await queryRunner.query(`
      DO $$ BEGIN
        IF EXISTS (SELECT 1 FROM pg_type WHERE typname = 'subscriptions_plan_enum') THEN
          DROP TYPE "subscriptions_plan_enum";
        END IF;
      END $$;
    `);

    await queryRunner.query(
      `ALTER TYPE "subscription_plan_enum_old" RENAME TO "subscriptions_plan_enum"`
    );
  }
}
