'use strict';

/**
 * Migration: Convert page_elements.element_type from ENUM to TEXT
 *
 * This migration:
 * 1. Converts element_type column from ENUM to TEXT for flexibility
 * 2. Maps nav_button to navigation_next or navigation_prev based on content_json.navType
 * 3. Drops the old ENUM type
 *
 * Benefits of TEXT over ENUM:
 * - Flexibility to add new element types without migrations
 * - No ENUM sync issues between environments
 * - Application-level validation ensures type safety
 */
module.exports = {
  async up(queryInterface, Sequelize) {
    const transaction = await queryInterface.sequelize.transaction();

    try {
      // Step 1: Create a temporary TEXT column
      await queryInterface.addColumn(
        'page_elements',
        'element_type_text',
        {
          type: Sequelize.TEXT,
          allowNull: true,
        },
        { transaction },
      );

      // Step 2: Copy ENUM values to TEXT column
      await queryInterface.sequelize.query(
        `UPDATE page_elements SET element_type_text = element_type::TEXT`,
        { transaction },
      );

      // Step 3: Drop the old ENUM column
      await queryInterface.removeColumn('page_elements', 'element_type', {
        transaction,
      });

      // Step 4: Rename TEXT column to element_type
      await queryInterface.renameColumn(
        'page_elements',
        'element_type_text',
        'element_type',
        { transaction },
      );

      // Step 5: Add NOT NULL constraint
      await queryInterface.changeColumn(
        'page_elements',
        'element_type',
        {
          type: Sequelize.TEXT,
          allowNull: false,
        },
        { transaction },
      );

      // Step 6: Now map nav_button to specific navigation types (column is TEXT now)
      // Forward navigation (default if navType not specified)
      await queryInterface.sequelize.query(
        `UPDATE page_elements
         SET element_type = 'navigation_next'
         WHERE element_type = 'nav_button'
         AND (
           content_json IS NULL
           OR content_json::jsonb->>'navType' = 'forward'
           OR content_json::jsonb->>'navType' IS NULL
         )`,
        { transaction },
      );

      // Back navigation
      await queryInterface.sequelize.query(
        `UPDATE page_elements
         SET element_type = 'navigation_prev'
         WHERE element_type = 'nav_button'
         AND content_json IS NOT NULL
         AND content_json::jsonb->>'navType' = 'back'`,
        { transaction },
      );

      // Step 7: Drop the old ENUM type if it exists
      await queryInterface.sequelize.query(
        `DROP TYPE IF EXISTS "enum_page_elements_element_type"`,
        { transaction },
      );

      await transaction.commit();
      console.log(
        'Successfully converted element_type from ENUM to TEXT and mapped nav_button types',
      );
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  },

  async down(queryInterface, _Sequelize) {
    const transaction = await queryInterface.sequelize.transaction();

    try {
      // Step 1: Map navigation types back to nav_button (before creating ENUM)
      await queryInterface.sequelize.query(
        `UPDATE page_elements
         SET element_type = 'nav_button'
         WHERE element_type IN ('navigation_next', 'navigation_prev')`,
        { transaction },
      );

      // Step 2: Drop any existing ENUM types that might conflict
      await queryInterface.sequelize.query(
        `DROP TYPE IF EXISTS "enum_page_elements_element_type" CASCADE`,
        { transaction },
      );
      await queryInterface.sequelize.query(
        `DROP TYPE IF EXISTS "enum_page_elements_element_type_enum" CASCADE`,
        { transaction },
      );

      // Step 3: Create the ENUM type with original values
      await queryInterface.sequelize.query(
        `CREATE TYPE "enum_page_elements_element_type" AS ENUM (
          'nav_button',
          'spot',
          'description',
          'tooltip',
          'gallery',
          'carousel',
          'logo',
          'video_player',
          'popup'
        )`,
        { transaction },
      );

      // Step 4: Add ENUM column directly via raw SQL to avoid Sequelize creating another type
      await queryInterface.sequelize.query(
        `ALTER TABLE page_elements ADD COLUMN element_type_enum "enum_page_elements_element_type"`,
        { transaction },
      );

      // Step 5: Copy TEXT values to ENUM column
      await queryInterface.sequelize.query(
        `UPDATE page_elements SET element_type_enum = element_type::"enum_page_elements_element_type"`,
        { transaction },
      );

      // Step 6: Drop TEXT column
      await queryInterface.removeColumn('page_elements', 'element_type', {
        transaction,
      });

      // Step 7: Rename ENUM column
      await queryInterface.renameColumn(
        'page_elements',
        'element_type_enum',
        'element_type',
        { transaction },
      );

      // Step 8: Add NOT NULL constraint
      await queryInterface.sequelize.query(
        `ALTER TABLE page_elements ALTER COLUMN element_type SET NOT NULL`,
        { transaction },
      );

      await transaction.commit();
      console.log('Successfully reverted element_type from TEXT to ENUM');
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  },
};
