/**
 * ToolbarConfigManager - Centralized toolbar configuration
 *
 * Replaces duplicate toolbar filtering code that appeared in multiple locations.
 * Provides a single source of truth for toolbar configuration.
 */

import { getToolbarFormats as parseToolbarFormats, getFormatsString } from '../utils/formats';

export class ToolbarConfigManager {
  constructor() {
    // Mapping from ACF toolbar items to TinyMCE toolbar button names
    this.toolbarMappings = {
      ol: 'numlist',
      ul: 'bullist',
      media: 'tdimage'
    };

    // Items that should always be removed when their ACF counterpart is missing
    this.removableItems = ['numlist', 'bullist', 'tdimage'];
  }

  /**
   * Configure editor based on ACF toolbar settings
   * @param {Object} config - Base editor configuration
   * @param {string} toolbar - ACF toolbar string (e.g., "p,h1,h2,ul,ol,media")
   * @returns {Object} Updated configuration
   */
  configureFromToolbar(config, toolbar) {
    if (!toolbar || !config) {
      return { ...config };
    }

    const result = { ...config };
    const formatData = this.parseToolbar(toolbar);

    // Apply block formats: store as string for TinyMCE, array for tdblocks plugin
    if (formatData.formats.length > 0) {
      result.block_formats = getFormatsString(formatData.formats);
      result.tdblocks_formats = formatData.formats;
    }

    // Apply custom body classes
    if (formatData.customClasses.length > 0) {
      const customBodyClasses = formatData.customClasses
        .map(className => `has-${className}-style`)
        .join(' ');

      result.body_class = result.body_class
        ? `${result.body_class} ${customBodyClasses}`
        : customBodyClasses;
    }

    // Filter toolbar buttons
    if (result.toolbar) {
      result.toolbar = this.filterToolbar(result.toolbar, toolbar);
    }

    return result;
  }

  /**
   * Parse ACF toolbar string into formats and custom classes
   * @param {string} toolbar - ACF toolbar string
   * @returns {Object} { formats: Array, customClasses: Array }
   */
  parseToolbar(toolbar) {
    try {
      return parseToolbarFormats(toolbar);
    } catch (error) {
      console.warn('Error parsing toolbar:', error);
      return { formats: [], customClasses: [] };
    }
  }

  /**
   * Filter TinyMCE toolbar based on ACF toolbar settings
   * @param {string} toolbarString - TinyMCE toolbar string
   * @param {string} acfToolbar - ACF toolbar string
   * @returns {string} Filtered toolbar string
   */
  filterToolbar(toolbarString, acfToolbar) {
    if (!toolbarString || !acfToolbar) {
      return toolbarString;
    }

    let filtered = toolbarString;

    // Remove numlist if toolbar doesn't include 'ol'
    if (!acfToolbar.includes('ol')) {
      filtered = filtered.replace(/\s*numlist\s*/g, ' ');
    }

    // Remove bullist if toolbar doesn't include 'ul'
    if (!acfToolbar.includes('ul')) {
      filtered = filtered.replace(/\s*bullist\s*/g, ' ');
    }

    // Remove tdimage if toolbar doesn't include 'media'
    if (!acfToolbar.includes('media')) {
      filtered = filtered.replace(/\s*tdimage\s*/g, ' ');
    }

    // Clean up formatting
    return this.cleanToolbarString(filtered);
  }

  /**
   * Clean up toolbar string formatting
   * @param {string} toolbar - Toolbar string to clean
   * @returns {string} Cleaned toolbar string
   */
  cleanToolbarString(toolbar) {
    if (!toolbar) return '';

    return toolbar
      .replace(/\|\s*\|/g, '|') // Remove double pipes
      .replace(/^\s*\|\s*/, '') // Remove leading pipe
      .replace(/\s*\|\s*$/, '') // Remove trailing pipe
      .replace(/\s+/g, ' ') // Normalize spaces
      .trim();
  }

  /**
   * Check if a specific item is allowed based on ACF toolbar
   * @param {string} item - Toolbar item to check
   * @param {string} acfToolbar - ACF toolbar string
   * @returns {boolean}
   */
  isItemAllowed(item, acfToolbar) {
    if (!acfToolbar) return true;

    // Check direct mapping
    for (const [acfItem, tinymceItem] of Object.entries(this.toolbarMappings)) {
      if (item === tinymceItem) {
        return acfToolbar.includes(acfItem);
      }
    }

    // Item not in mapping, allow by default
    return true;
  }

  /**
   * Get ACF toolbar data attribute from field
   * @param {jQuery} $field - ACF field jQuery object
   * @returns {string|null}
   */
  getToolbarFromField($field) {
    if (!$field || !$field.length) return null;
    return $field.data('toolbar') || null;
  }
}

export default ToolbarConfigManager;
