/**
 * @package PublishPress
 * @author PublishPress
 *
 * PublishPress Statuses Integration for PublishPress Checklists
 * This file provides integration with PublishPress Statuses plugin for custom status support.
 */

/**
 * Class PPChStatusesIntegration provides integration with PublishPress Statuses plugin.
 * Extends the base PPChStatusFilter with custom status detection and workflow button handling.
 *
 * @class PPChStatusesIntegration
 */
class PPChStatusesIntegration {
  /**
   * DOM selectors for PublishPress Statuses elements.
   *
   * @static
   * @type {Object}
   */
  static SELECTORS = {
    statusDropdown: 'div.publishpress-extended-post-status select',
    workflowButton: '.presspermit-editor-button'
  };

  /**
   * Constructs the integration instance.
   *
   * @param {Object} wp - WordPress global object
   * @param {Function} $ - jQuery instance
   * @param {PPChStatusFilter} statusFilter - The main status filter instance
   */
  constructor(wp, $, statusFilter) {
    this.wp = wp;
    this.$ = $;
    this.statusFilter = statusFilter;
    this.select = wp.data.select;
    this.dispatch = wp.data.dispatch;
  }

  /**
   * Initializes the integration.
   *
   * @returns {void}
   */
  init() {
    this._setupEventListeners();
    this._overrideStatusDetection();
  }

  /**
   * Sets up event listeners for PublishPress Statuses elements.
   *
   * @private
   * @returns {void}
   */
  _setupEventListeners() {
    // Listen for PublishPress Statuses dropdown changes
    this.$(document).on('change', PPChStatusesIntegration.SELECTORS.statusDropdown, () => {
      this._handleStatusDropdownChange();
    });

    // Listen for clicks on PublishPress Statuses workflow buttons
    this.$(document).on('click', PPChStatusesIntegration.SELECTORS.workflowButton, (e) => {
      this._handleWorkflowButtonClick(e);
    });
  }

  /**
   * Overrides the status detection in the main filter to include PP Statuses support.
   *
   * @private
   * @returns {void}
   */
  _overrideStatusDetection() {
    if (!this.statusFilter) return;

    // Store reference to the original method
    const originalGetCurrentPostStatus = this.statusFilter.getCurrentPostStatus.bind(this.statusFilter);

    // Override with our enhanced version
    this.statusFilter.getCurrentPostStatus = () => {
      // Check for PublishPress Statuses custom field first (pp_status_selection)
      const ppStatus = this._getStatusFromPPStatuses();
      if (ppStatus) {
        return ppStatus;
      }

      // Fall back to the original implementation
      return originalGetCurrentPostStatus();
    };
  }

  /**
   * Gets the current post status from PublishPress Statuses.
   * Checks the REST field first, then falls back to DOM.
   *
   * @private
   * @returns {string|null} The status from PP Statuses or null
   */
  _getStatusFromPPStatuses() {
    const editorStore = this.select('core/editor');

    // Check for PublishPress Statuses REST field (pp_status_selection)
    const ppStatusSelection = editorStore.getEditedPostAttribute?.('pp_status_selection');
    if (ppStatusSelection && typeof ppStatusSelection === 'string') {
      return ppStatusSelection;
    }

    // Fallback: Check the DOM selector
    const statusSelect = document.querySelector(PPChStatusesIntegration.SELECTORS.statusDropdown);
    if (statusSelect && statusSelect.value) {
      return statusSelect.value;
    }

    return null;
  }

  /**
   * Handles PublishPress Statuses dropdown change.
   *
   * @private
   * @returns {void}
   */
  _handleStatusDropdownChange() {
    // Delay to allow pp_status_selection to be updated in the store
    setTimeout(() => {
      if (!this.statusFilter) return;

      const currentStatus = this.statusFilter.getCurrentPostStatus();
      if (currentStatus && currentStatus !== this.statusFilter.previousStatus) {
        this.statusFilter.previousStatus = currentStatus;
        this.statusFilter.updateChecklistItemsVisibility(currentStatus);
      }
    }, 50);
  }

  /**
   * Handles click on PublishPress Statuses workflow buttons.
   * Shows notification if there are unfulfilled blocking requirements.
   *
   * @private
   * @param {Event} e - Click event
   * @returns {void}
   */
  _handleWorkflowButtonClick(e) {
    // Check if post saving is locked due to checklist requirements
    const editorSelect = this.select('core/editor');
    const isLocked = typeof editorSelect.isPostSavingLocked === 'function'
      ? editorSelect.isPostSavingLocked()
      : false;

    if (!isLocked) {
      return; // Not locked, allow normal behavior
    }

    // Count visible failed blocking requirements
    const failedBlockCount = this.statusFilter?._countFailedBlockingRequirements() || 0;

    if (failedBlockCount > 0) {
      this._showChecklistNotification();
    }
  }

  /**
   * Shows a notification that checklist tasks need to be completed.
   *
   * @private
   * @returns {void}
   */
  _showChecklistNotification() {
    // Use WordPress notices API
    if (this.dispatch('core/notices')) {
      const noticeId = 'pp-checklists-workflow-notice';

      // Remove existing notice first to avoid duplicates
      this.dispatch('core/notices').removeNotice(noticeId);

      // Create error notice
      this.dispatch('core/notices').createErrorNotice(
        window.ppChecklists?.completeRequirementMessage || 'Please complete the required(*) checklists task.',
        {
          id: noticeId,
          isDismissible: true,
          speak: true
        }
      );
      return;
    }

    // Fallback: Try to use the existing remodal alert
    const $modalContent = this.$('#pp-checklists-modal-alert-content');
    const $modal = this.$('[data-remodal-id=pp-checklists-modal-alert]');

    if ($modalContent.length && $modal.length && typeof $modal.remodal === 'function') {
      $modalContent.html(window.ppChecklists?.completeRequirementMessage || 'Please complete the required(*) checklists task.');
      $modal.remodal().open();
    }
  }
}

// Initialize when the main status filter is ready
window.wp.domReady(() => {
  // Wait for the main status filter to be initialized
  const checkAndInit = () => {
    if (typeof window.PPChStatusFilterInstance !== 'undefined' && window.PPChStatusFilterInstance) {
      new PPChStatusesIntegration(window.wp, window.jQuery, window.PPChStatusFilterInstance).init();
    } else {
      // Retry after a short delay
      setTimeout(checkAndInit, 100);
    }
  };

  // Start checking
  setTimeout(checkAndInit, 100);
});
