'use strict';

/**
 * Migration: Backfill project_element_defaults for existing projects
 *
 * For each existing project that doesn't have project_element_defaults,
 * create a snapshot of the current global element_type_defaults.
 */

// Default element types to ensure they exist before backfilling
const DEFAULT_ELEMENT_TYPES = [
  {
    element_type: 'navigation_next',
    name: 'Navigation Forward Button',
    sort_order: 1,
    settings_json: JSON.stringify({
      label: 'Navigation: Forward',
      navLabel: 'Forward',
      navType: 'forward',
      navDisabled: false,
      transitionReverseMode: 'auto_reverse',
      transitionDurationSec: 0.7,
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
  {
    element_type: 'navigation_prev',
    name: 'Navigation Back Button',
    sort_order: 2,
    settings_json: JSON.stringify({
      label: 'Navigation: Back',
      navLabel: 'Back',
      navType: 'back',
      navDisabled: false,
      transitionReverseMode: 'auto_reverse',
      transitionDurationSec: 0.7,
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
  {
    element_type: 'tooltip',
    name: 'Tooltip',
    sort_order: 3,
    settings_json: JSON.stringify({
      label: 'Tooltip',
      tooltipTitle: 'Tooltip title',
      tooltipText: 'Tooltip text',
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
  {
    element_type: 'description',
    name: 'Description',
    sort_order: 4,
    settings_json: JSON.stringify({
      label: 'Description',
      descriptionTitle: 'TITLE',
      descriptionText: '',
      descriptionTitleFontSize: '48px',
      descriptionTextFontSize: '36px',
      descriptionTitleFontFamily: 'inherit',
      descriptionTextFontFamily: 'inherit',
      descriptionTitleColor: '#000000',
      descriptionTextColor: '#4B5563',
      descriptionBackgroundColor: 'transparent',
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
  {
    element_type: 'gallery',
    name: 'Gallery',
    sort_order: 5,
    settings_json: JSON.stringify({
      label: 'Gallery',
      galleryCards: [{ imageUrl: '', title: 'Card 1', description: '' }],
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
  {
    element_type: 'carousel',
    name: 'Carousel',
    sort_order: 6,
    settings_json: JSON.stringify({
      label: 'Carousel',
      carouselSlides: [{ imageUrl: '', caption: 'Slide 1' }],
      carouselPrevIconUrl: '',
      carouselNextIconUrl: '',
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
  {
    element_type: 'video_player',
    name: 'Video Player',
    sort_order: 7,
    settings_json: JSON.stringify({
      label: 'Video Player',
      mediaUrl: '',
      mediaAutoplay: true,
      mediaLoop: true,
      mediaMuted: true,
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
  {
    element_type: 'audio_player',
    name: 'Audio Player',
    sort_order: 8,
    settings_json: JSON.stringify({
      label: 'Audio Player',
      mediaUrl: '',
      mediaAutoplay: true,
      mediaLoop: true,
      mediaMuted: false,
      appearDelaySec: 0,
      appearDurationSec: null,
    }),
  },
];

module.exports = {
  async up(queryInterface, Sequelize) {
    // First, ensure element_type_defaults has all default rows
    // This is needed because the API's lazy initialization won't have run yet during migration
    const [existingTypes] = await queryInterface.sequelize.query(
      `SELECT element_type FROM element_type_defaults WHERE "deletedAt" IS NULL`,
      { type: Sequelize.QueryTypes.SELECT },
    );

    const existingTypeSet = new Set(
      Array.isArray(existingTypes)
        ? existingTypes.map((t) => t.element_type)
        : existingTypes
          ? [existingTypes.element_type]
          : [],
    );

    // Insert missing element types
    for (const defaultType of DEFAULT_ELEMENT_TYPES) {
      if (!existingTypeSet.has(defaultType.element_type)) {
        await queryInterface.sequelize.query(
          `INSERT INTO element_type_defaults (id, element_type, name, sort_order, settings_json, "createdAt", "updatedAt")
           VALUES (gen_random_uuid(), :element_type, :name, :sort_order, :settings_json, NOW(), NOW())`,
          {
            replacements: {
              element_type: defaultType.element_type,
              name: defaultType.name,
              sort_order: defaultType.sort_order,
              settings_json: defaultType.settings_json,
            },
          },
        );
        console.log(
          `Created missing element_type_default: ${defaultType.element_type}`,
        );
      }
    }

    // Get all existing projects
    const [projects] = await queryInterface.sequelize.query(
      `SELECT id FROM projects WHERE "deletedAt" IS NULL`,
      { type: Sequelize.QueryTypes.SELECT },
    );

    if (!projects || projects.length === 0) {
      console.log('No projects found, skipping backfill');
      return;
    }

    // Get all global element type defaults (now guaranteed to have all types)
    const [globalDefaults] = await queryInterface.sequelize.query(
      `SELECT id, element_type, name, sort_order, settings_json
       FROM element_type_defaults
       WHERE "deletedAt" IS NULL`,
      { type: Sequelize.QueryTypes.SELECT },
    );

    if (!globalDefaults || globalDefaults.length === 0) {
      console.log('No global element type defaults found, skipping backfill');
      return;
    }

    const projectIds = Array.isArray(projects)
      ? projects.map((p) => p.id)
      : [projects.id];
    const globalDefaultRows = Array.isArray(globalDefaults)
      ? globalDefaults
      : [globalDefaults];

    // For each project, add any missing element type defaults
    for (const projectId of projectIds) {
      // Get existing element types for this project
      const [existingDefaults] = await queryInterface.sequelize.query(
        `SELECT element_type FROM project_element_defaults
         WHERE "projectId" = :projectId AND "deletedAt" IS NULL`,
        {
          replacements: { projectId },
          type: Sequelize.QueryTypes.SELECT,
        },
      );

      const existingProjectTypes = new Set(
        Array.isArray(existingDefaults)
          ? existingDefaults.map((d) => d.element_type)
          : existingDefaults
            ? [existingDefaults.element_type]
            : [],
      );

      // Create project element defaults for missing types
      let addedCount = 0;
      for (const globalDefault of globalDefaultRows) {
        if (existingProjectTypes.has(globalDefault.element_type)) {
          continue; // Already has this type
        }

        await queryInterface.sequelize.query(
          `INSERT INTO project_element_defaults
           (id, element_type, name, sort_order, settings_json, source_element_id, snapshot_version, "projectId", "createdAt", "updatedAt")
           VALUES (
             gen_random_uuid(),
             :element_type,
             :name,
             :sort_order,
             :settings_json,
             :source_element_id,
             1,
             :projectId,
             NOW(),
             NOW()
           )`,
          {
            replacements: {
              element_type: globalDefault.element_type,
              name: globalDefault.name,
              sort_order: globalDefault.sort_order,
              settings_json: globalDefault.settings_json,
              source_element_id: globalDefault.id,
              projectId,
            },
            type: Sequelize.QueryTypes.INSERT,
          },
        );
        addedCount++;
      }

      if (addedCount > 0) {
        console.log(
          `Backfilled ${addedCount} element defaults for project ${projectId}`,
        );
      } else {
        console.log(`Project ${projectId} already has all element defaults`);
      }
    }

    console.log(
      'Successfully backfilled project_element_defaults for existing projects',
    );
  },

  async down(queryInterface, _Sequelize) {
    // Delete all project_element_defaults with snapshot_version = 1
    // (only the ones we created during backfill)
    await queryInterface.sequelize.query(
      `DELETE FROM project_element_defaults WHERE snapshot_version = 1`,
    );

    console.log('Successfully removed backfilled project_element_defaults');
  },
};
