const GenericDBApi = require('./base.api');
const db = require('../models');

class Element_type_defaultsDBApi extends GenericDBApi {
  static get MODEL() {
    return db.element_type_defaults;
  }

  static get TABLE_NAME() {
    return 'element_type_defaults';
  }

  static get SEARCHABLE_FIELDS() {
    return ['name', 'element_type'];
  }

  static get RANGE_FIELDS() {
    return ['sort_order'];
  }

  static get ENUM_FIELDS() {
    return [];
  }

  static get CSV_FIELDS() {
    return [
      'id',
      'element_type',
      'name',
      'sort_order',
      'is_active',
      'createdAt',
    ];
  }

  static get AUTOCOMPLETE_FIELD() {
    return 'name';
  }

  // Declarative field configuration using base class patterns
  static get JSON_FIELDS() {
    return ['default_settings_json'];
  }

  static get FIELD_DEFAULTS() {
    return {
      element_type: { default: null },
      name: { default: null },
      sort_order: { default: 0 },
    };
  }

  static getFieldMapping(data) {
    // Apply base class transformations (JSON fields, defaults, transformers)
    const mapped = super.getFieldMapping(data);

    return {
      id: mapped.id || undefined,
      element_type: mapped.element_type,
      name: mapped.name,
      sort_order: mapped.sort_order,
      default_settings_json: mapped.default_settings_json,
    };
  }

  static get DEFAULT_ROWS() {
    return [
      {
        element_type: 'navigation_next',
        name: 'Navigation Forward Button',
        sort_order: 1,
        default_settings_json: {
          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,
        default_settings_json: {
          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,
        default_settings_json: {
          label: 'Tooltip',
          tooltipTitle: 'Tooltip title',
          tooltipText: 'Tooltip text',
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
      {
        element_type: 'description',
        name: 'Description',
        sort_order: 4,
        default_settings_json: {
          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,
        default_settings_json: {
          label: 'Gallery',
          galleryCards: [{ imageUrl: '', title: 'Card 1', description: '' }],
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
      {
        element_type: 'carousel',
        name: 'Carousel',
        sort_order: 6,
        default_settings_json: {
          label: 'Carousel',
          carouselSlides: [{ imageUrl: '', caption: 'Slide 1' }],
          carouselPrevIconUrl: '',
          carouselNextIconUrl: '',
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
      {
        element_type: 'video_player',
        name: 'Video Player',
        sort_order: 7,
        default_settings_json: {
          label: 'Video Player',
          mediaUrl: '',
          mediaAutoplay: true,
          mediaLoop: true,
          mediaMuted: true,
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
      {
        element_type: 'audio_player',
        name: 'Audio Player',
        sort_order: 8,
        default_settings_json: {
          label: 'Audio Player',
          mediaUrl: '',
          mediaAutoplay: true,
          mediaLoop: true,
          mediaMuted: false,
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
      {
        element_type: 'spot',
        name: 'Hotspot',
        sort_order: 9,
        default_settings_json: {
          label: 'Hotspot',
          iconUrl: '',
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
      {
        element_type: 'logo',
        name: 'Logo',
        sort_order: 10,
        default_settings_json: {
          label: 'Logo',
          iconUrl: '',
          backgroundImageUrl: '',
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
      {
        element_type: 'popup',
        name: 'Popup',
        sort_order: 11,
        default_settings_json: {
          label: 'Popup',
          iconUrl: '',
          popupTitle: '',
          popupContent: '',
          appearDelaySec: 0,
          appearDurationSec: null,
        },
      },
    ];
  }

  static async ensureInitialized() {
    if (!this.initializationPromise) {
      this.initializationPromise = (async () => {
        let count = 0;

        try {
          count = await this.MODEL.count();
        } catch (error) {
          if (error?.original?.code !== '42P01') {
            throw error;
          }

          await this.MODEL.sync();
          count = await this.MODEL.count();
        }

        if (count > 0) return;

        const now = new Date();
        await this.MODEL.bulkCreate(
          this.DEFAULT_ROWS.map((item) => ({
            ...this.getFieldMapping(item),
            createdAt: now,
            updatedAt: now,
          })),
        );
      })().catch((error) => {
        this.initializationPromise = null;
        throw error;
      });
    }

    await this.initializationPromise;
  }

  static async create(data, options = {}) {
    await this.ensureInitialized();
    return super.create(data, options);
  }

  static async bulkImport(data, options = {}) {
    await this.ensureInitialized();
    return super.bulkImport(data, options);
  }

  static async update(id, data, options = {}) {
    await this.ensureInitialized();
    return super.update(id, data, options);
  }

  static async deleteByIds(ids, options = {}) {
    await this.ensureInitialized();
    return super.deleteByIds(ids, options);
  }

  static async remove(id, options = {}) {
    await this.ensureInitialized();
    return super.remove(id, options);
  }

  static async findBy(where, options = {}) {
    await this.ensureInitialized();
    return super.findBy(where, options);
  }

  static async findAll(filter = {}, options = {}) {
    await this.ensureInitialized();
    return super.findAll(filter, options);
  }

  static async findAllAutocomplete(query, limit, offset) {
    await this.ensureInitialized();
    return super.findAllAutocomplete(query, limit, offset);
  }
}

Element_type_defaultsDBApi.initializationPromise = null;

module.exports = Element_type_defaultsDBApi;
