<?php
/**
 * Addons Page Class
 *
 * Central registry and UI for plugin addons.
 *
 * @package Polanger_Dashboard_Tools
 */

if ( ! defined( 'ABSPATH' ) ) {
  exit;
}

class PDT_Addons_Page {

  /**
   * Option key for active addons.
   *
   * @var string
   */
  private $active_addons_option = 'pdt_active_addons';

  /**
   * Default active addon slugs.
   *
   * @var array
   */
  private $default_active_addons = array(
    'admin-activity-log',
    'dashboard-widgets',
  );

  /**
   * Constructor.
   */
  public function __construct() {
    add_action( 'admin_init', array( $this, 'maybe_handle_activation_toggle' ) );
  }

  /**
   * Return registered addons.
   *
   * Addons can register themselves via `pdt_register_addons` filter.
   *
   * @return array
   */
  public function get_addons() {
    $addons = array(
      'admin-activity-log' => array(
        'title'       => __( 'Admin Activity Log', 'polanger-admin-menu-manager' ),
        'description' => __( 'Track administrative actions for auditing and security monitoring.', 'polanger-admin-menu-manager' ),
        'status'      => 'inactive',
        'slug'        => 'polanger-activity-log',
        'is_core'     => true,
      ),
      'dashboard-widgets'  => array(
        'title'       => __( 'Dashboard Widgets', 'polanger-admin-menu-manager' ),
        'description' => __( 'Manage dashboard widgets and customize what users see on WordPress Dashboard.', 'polanger-admin-menu-manager' ),
        'status'      => 'inactive',
        'slug'        => 'polanger-dashboard-widgets',
        'is_core'     => true,
      ),
      'custom-admin-menu'  => array(
        'title'       => __( 'Custom Admin Menu Builder', 'polanger-admin-menu-manager' ),
        'description' => __( 'Add new custom main menus and submenus to the WordPress admin sidebar.', 'polanger-admin-menu-manager' ),
        'status'      => 'inactive',
        'slug'        => 'polanger-dashboard',
      ),
    );

    // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Backward-compatible public extension hook.
    $addons = apply_filters( 'pdt_register_addons', $addons );

    if ( ! is_array( $addons ) ) {
      return array();
    }

    return $addons;
  }

  /**
   * Get active addon slugs.
   *
   * @return array
   */
  public function get_active_addons() {
    $active_addons = get_option( $this->active_addons_option, null );

    if ( null === $active_addons ) {
      update_option( $this->active_addons_option, $this->default_active_addons );
      return $this->default_active_addons;
    }

    if ( ! is_array( $active_addons ) ) {
      return $this->default_active_addons;
    }

    return array_values( array_unique( array_map( 'sanitize_key', $active_addons ) ) );
  }

  /**
   * Save active addons.
   *
   * @param array $active_addons Active addon slugs.
   * @return void
   */
  private function update_active_addons( $active_addons ) {
    if ( ! is_array( $active_addons ) ) {
      return;
    }

    $clean = array_values( array_unique( array_map( 'sanitize_key', $active_addons ) ) );
    update_option( $this->active_addons_option, $clean );
  }

  /**
   * Resolve whether an addon can be activated.
   *
   * Addons may declare dependency requirements through this filter so the
   * Addons screen can block unsupported activations in both UI and POST flow.
   *
   * @param string $addon_key Addon slug.
   * @param array  $addon     Addon registry definition.
   * @return array
   */
  private function get_addon_availability( $addon_key, $addon ) {
    $availability = array(
      'available'   => true,
      'reason'      => '',
      'status_text' => __( 'Inactive', 'polanger-admin-menu-manager' ),
      'button_text' => __( 'Activate', 'polanger-admin-menu-manager' ),
      'fact_text'   => '',
    );

    if ( 'woocommerce-security' === $addon_key ) {
      $woocommerce_file = WP_PLUGIN_DIR . '/woocommerce/woocommerce.php';
      $woo_installed    = file_exists( $woocommerce_file );
      $woo_active       = class_exists( 'WooCommerce' ) || function_exists( 'WC' );

      $availability['fact_text'] = __( 'Requires WooCommerce', 'polanger-admin-menu-manager' );

      if ( ! $woo_active ) {
        $availability['available'] = false;
        $availability['reason']    = $woo_installed
          ? __( 'WooCommerce is installed but currently inactive. Activate WooCommerce before enabling this addon.', 'polanger-admin-menu-manager' )
          : __( 'WooCommerce is not installed. Install WooCommerce before enabling this addon.', 'polanger-admin-menu-manager' );
        $availability['status_text'] = $woo_installed
          ? __( 'WooCommerce inactive', 'polanger-admin-menu-manager' )
          : __( 'WooCommerce not installed', 'polanger-admin-menu-manager' );
        $availability['button_text'] = $woo_installed
          ? __( 'Activate WooCommerce first', 'polanger-admin-menu-manager' )
          : __( 'Install WooCommerce first', 'polanger-admin-menu-manager' );
        $availability['fact_text'] = $woo_installed
          ? __( 'WooCommerce installed', 'polanger-admin-menu-manager' )
          : __( 'WooCommerce required', 'polanger-admin-menu-manager' );
      }
    }

    $availability = apply_filters( 'pdt_addon_availability', $availability, $addon_key, $addon );

    if ( ! is_array( $availability ) ) {
      $availability = array();
    }

    $availability['available']   = ! empty( $availability['available'] );
    $availability['reason']      = isset( $availability['reason'] ) ? sanitize_text_field( $availability['reason'] ) : '';
    $availability['status_text'] = isset( $availability['status_text'] ) ? sanitize_text_field( $availability['status_text'] ) : __( 'Inactive', 'polanger-admin-menu-manager' );
    $availability['button_text'] = isset( $availability['button_text'] ) ? sanitize_text_field( $availability['button_text'] ) : __( 'Activate', 'polanger-admin-menu-manager' );
    $availability['fact_text']   = isset( $availability['fact_text'] ) ? sanitize_text_field( $availability['fact_text'] ) : '';

    return $availability;
  }

  /**
   * Toggle addon activation from addons page.
   *
   * @return void
   */
  public function maybe_handle_activation_toggle() {
    if ( ! current_user_can( 'manage_options' ) ) {
      return;
    }

    if ( ! isset( $_POST['pdt_addons_toggle_submit'] ) ) {
      return;
    }

    if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'pdt_toggle_addon' ) ) {
      return;
    }

    $addon_slug = isset( $_POST['addon_slug'] ) ? sanitize_key( wp_unslash( $_POST['addon_slug'] ) ) : '';
    $action     = isset( $_POST['toggle_action'] ) ? sanitize_key( wp_unslash( $_POST['toggle_action'] ) ) : '';
    $addons     = $this->get_addons();

    if ( empty( $addon_slug ) || ! isset( $addons[ $addon_slug ] ) ) {
      return;
    }

    $availability = $this->get_addon_availability( $addon_slug, $addons[ $addon_slug ] );

    if ( 'activate' === $action && ! empty( $availability ) && empty( $availability['available'] ) ) {
      wp_safe_redirect(
        add_query_arg(
          array(
            'page'   => 'polanger-addons',
            'status' => 'addon-unavailable',
            'addon'  => $addon_slug,
          ),
          admin_url( 'admin.php' )
        )
      );
      exit;
    }

    $active_addons = $this->get_active_addons();

    if ( 'activate' === $action && ! in_array( $addon_slug, $active_addons, true ) ) {
      $active_addons[] = $addon_slug;
    }

    if ( 'deactivate' === $action ) {
      $active_addons = array_values( array_diff( $active_addons, array( $addon_slug ) ) );
    }

    $this->update_active_addons( $active_addons );

    wp_safe_redirect(
      add_query_arg(
        array(
          'page'   => 'polanger-addons',
          'status' => ( 'activate' === $action ) ? 'addon-activated' : 'addon-deactivated',
          'addon'  => $addon_slug,
        ),
        admin_url( 'admin.php' )
      )
    );
    exit;
  }

  /**
   * Render addons page.
   *
   * @return void
   */
  public function render_page() {
    $addons = $this->get_addons();
    $total_addons = count( $addons );
    $active_count = $this->count_active_addons( $addons );
    $core_count = 0;
    $screen_count = 0;
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $status = isset( $_GET['status'] ) ? sanitize_text_field( wp_unslash( $_GET['status'] ) ) : '';
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $status_addon = isset( $_GET['addon'] ) ? sanitize_key( wp_unslash( $_GET['addon'] ) ) : '';
    $status_availability = array();

    if ( ! empty( $status_addon ) && isset( $addons[ $status_addon ] ) ) {
      $status_availability = $this->get_addon_availability( $status_addon, $addons[ $status_addon ] );
    }

    foreach ( $addons as $addon ) {
      if ( ! empty( $addon['is_core'] ) ) {
        $core_count++;
      }
      if ( ! empty( $addon['slug'] ) ) {
        $screen_count++;
      }
    }
    ?>
    <div class="pdt-addons-page-shell">
      <div class="pdt-addons-notice-stack">
        <?php if ( 'addon-deactivated' === $status ) : ?>
          <div class="notice notice-success is-dismissible">
            <p><?php esc_html_e( 'Addon state updated successfully.', 'polanger-admin-menu-manager' ); ?></p>
          </div>
        <?php elseif ( 'addon-activated' === $status && ( empty( $status_addon ) || ( isset( $addons[ $status_addon ] ) && ! empty( $status_availability['available'] ) ) ) ) : ?>
          <div class="notice notice-success is-dismissible">
            <p><?php esc_html_e( 'Addon state updated successfully.', 'polanger-admin-menu-manager' ); ?></p>
          </div>
        <?php elseif ( 'addon-unavailable' === $status && ! empty( $status_addon ) && isset( $addons[ $status_addon ] ) ) : ?>
          <div class="notice notice-warning is-dismissible">
            <p>
              <?php
              echo esc_html(
                ! empty( $status_availability['reason'] )
                  ? $status_availability['reason']
                  : __( 'This addon cannot be activated until its required dependency is available.', 'polanger-admin-menu-manager' )
              );
              ?>
            </p>
          </div>
        <?php endif; ?>
      </div>

      <div class="wrap pdt-addons-wrap">
        <div class="pdt-page-header">
          <div class="pdt-page-header__content">
            <span class="pdt-page-header__eyebrow"><?php esc_html_e( 'Module Library', 'polanger-admin-menu-manager' ); ?></span>
            <div class="pdt-page-header__title-row">
              <span class="dashicons dashicons-admin-plugins"></span>
              <h1><?php esc_html_e( 'Addons', 'polanger-admin-menu-manager' ); ?></h1>
            </div>
            <p><?php esc_html_e( 'Activate the modules you need, keep the admin clean, and open each addon from one central workspace.', 'polanger-admin-menu-manager' ); ?></p>

            <div class="pdt-addon-summary">
              <div class="pdt-addon-summary__item">
                <span class="pdt-addon-summary__value"><?php echo esc_html( number_format_i18n( $total_addons ) ); ?></span>
                <span class="pdt-addon-summary__label"><?php esc_html_e( 'Available addons', 'polanger-admin-menu-manager' ); ?></span>
              </div>
              <div class="pdt-addon-summary__item">
                <span class="pdt-addon-summary__value"><?php echo esc_html( number_format_i18n( $active_count ) ); ?></span>
                <span class="pdt-addon-summary__label"><?php esc_html_e( 'Currently active', 'polanger-admin-menu-manager' ); ?></span>
              </div>
              <div class="pdt-addon-summary__item">
                <span class="pdt-addon-summary__value"><?php echo esc_html( number_format_i18n( $core_count ) ); ?></span>
                <span class="pdt-addon-summary__label"><?php esc_html_e( 'Built into core', 'polanger-admin-menu-manager' ); ?></span>
              </div>
            </div>
          </div>

          <div class="pdt-page-header__panel">
            <div class="pdt-page-header__panel-badge"><?php esc_html_e( 'One-click workflow', 'polanger-admin-menu-manager' ); ?></div>
            <h2><?php esc_html_e( 'Use only what the site actually needs', 'polanger-admin-menu-manager' ); ?></h2>
            <p><?php esc_html_e( 'Core modules stay available out of the box. Optional addons can be turned on individually so each admin panel stays lighter, clearer, and easier to maintain.', 'polanger-admin-menu-manager' ); ?></p>
            <div class="pdt-page-header__panel-meta">
              <span><?php echo esc_html( number_format_i18n( $screen_count ) ); ?> <?php esc_html_e( 'configurable screens', 'polanger-admin-menu-manager' ); ?></span>
              <span><?php esc_html_e( 'No code editing required', 'polanger-admin-menu-manager' ); ?></span>
            </div>
          </div>
        </div>

        <div class="pdt-addons-grid">
          <?php if ( empty( $addons ) ) : ?>
            <div class="pdt-addon-card is-empty">
              <h2><?php esc_html_e( 'No addons registered yet', 'polanger-admin-menu-manager' ); ?></h2>
              <p><?php esc_html_e( 'New addon modules will appear here automatically.', 'polanger-admin-menu-manager' ); ?></p>
            </div>
          <?php else : ?>
            <?php foreach ( $addons as $addon_key => $addon ) : ?>
              <?php
              $title       = isset( $addon['title'] ) ? $addon['title'] : __( 'Unnamed Addon', 'polanger-admin-menu-manager' );
              $description = isset( $addon['description'] ) ? $addon['description'] : '';
              $is_active   = $this->is_addon_currently_active( $addon_key );
              $page_slug   = isset( $addon['slug'] ) ? $addon['slug'] : '';
              $is_core     = ! empty( $addon['is_core'] );
              $availability = $is_core ? array(
                'available'   => true,
                'reason'      => '',
                'status_text' => __( 'Core', 'polanger-admin-menu-manager' ),
                'button_text' => '',
                'fact_text'   => '',
              ) : $this->get_addon_availability( $addon_key, $addon );
              $is_unavailable = ! $is_core && empty( $availability['available'] );
              $status      = $is_core ? 'core' : ( $is_unavailable ? 'unavailable' : ( $is_active ? 'active' : 'inactive' ) );
              $status_text = 'active' === $status
                ? __( 'Active', 'polanger-admin-menu-manager' )
                : ( 'unavailable' === $status ? $availability['status_text'] : __( 'Inactive', 'polanger-admin-menu-manager' ) );
              $card_class  = $is_core ? 'pdt-addon-card--core' : ( $is_unavailable ? 'pdt-addon-card--unavailable' : ( $is_active ? 'pdt-addon-card--active' : 'pdt-addon-card--inactive' ) );
              $card_note   = $is_core
                ? __( 'Included with the suite and ready to use.', 'polanger-admin-menu-manager' )
                : ( $is_unavailable
                  ? ( $is_active ? __( 'This addon is enabled, but its required dependency is currently unavailable.', 'polanger-admin-menu-manager' ) : __( 'This addon is locked until its required dependency is available.', 'polanger-admin-menu-manager' ) )
                  : ( $is_active
                    ? __( 'Currently enabled on this site.', 'polanger-admin-menu-manager' )
                    : __( 'Optional module you can enable when needed.', 'polanger-admin-menu-manager' ) ) );
              $icon_class = $this->get_addon_icon_class( $addon_key );
              ?>
              <article class="pdt-addon-card <?php echo esc_attr( $card_class ); ?>">
                <div class="pdt-addon-card__accent" aria-hidden="true"></div>
                <div class="pdt-addon-card__head">
                  <span class="pdt-addon-card__icon" aria-hidden="true">
                    <span class="dashicons <?php echo esc_attr( $icon_class ); ?>"></span>
                  </span>

                  <div class="pdt-addon-meta">
                    <div class="pdt-addon-meta__text">
                      <h2><?php echo esc_html( $title ); ?></h2>
                      <p class="pdt-addon-card__note"><?php echo esc_html( $card_note ); ?></p>
                    </div>

                    <?php if ( $is_core ) : ?>
                      <span class="pdt-addon-status pdt-addon-status-core">
                        <?php esc_html_e( 'Core', 'polanger-admin-menu-manager' ); ?>
                      </span>
                    <?php else : ?>
                      <span class="pdt-addon-status pdt-addon-status-<?php echo esc_attr( $status ); ?>">
                        <?php echo esc_html( $status_text ); ?>
                      </span>
                    <?php endif; ?>
                  </div>
                </div>

                <?php if ( ! empty( $description ) ) : ?>
                  <p class="pdt-addon-card__description"><?php echo esc_html( $description ); ?></p>
                <?php endif; ?>

                <?php if ( ! empty( $availability['reason'] ) ) : ?>
                  <p class="pdt-addon-card__warning"><?php echo esc_html( $availability['reason'] ); ?></p>
                <?php endif; ?>

                <?php
                $card_facts = array(
                  $is_core
                    ? __( 'Built-in module', 'polanger-admin-menu-manager' )
                    : __( 'Optional addon', 'polanger-admin-menu-manager' ),
                );

                if ( ! empty( $page_slug ) ) {
                  $card_facts[] = __( 'Settings screen available', 'polanger-admin-menu-manager' );
                }

                if ( ! empty( $availability['fact_text'] ) ) {
                  $card_facts[] = $availability['fact_text'];
                }

                $card_facts = array_values( array_unique( array_filter( array_map( 'strval', $card_facts ) ) ) );
                ?>
                <div class="pdt-addon-card__facts">
                  <?php foreach ( $card_facts as $card_fact ) : ?>
                    <span class="pdt-addon-fact"><?php echo esc_html( $card_fact ); ?></span>
                  <?php endforeach; ?>
                </div>

                <div class="pdt-addon-actions">
                  <?php if ( ! $is_core ) : ?>
                    <?php if ( $is_active || ! $is_unavailable ) : ?>
                      <form method="post">
                        <?php wp_nonce_field( 'pdt_toggle_addon' ); ?>
                        <input type="hidden" name="addon_slug" value="<?php echo esc_attr( $addon_key ); ?>" />
                        <input type="hidden" name="toggle_action" value="<?php echo esc_attr( $is_active ? 'deactivate' : 'activate' ); ?>" />
                        <button type="submit" name="pdt_addons_toggle_submit" class="button <?php echo $is_active ? 'button-secondary' : 'button-primary'; ?>">
                          <?php echo esc_html( $is_active ? __( 'Deactivate', 'polanger-admin-menu-manager' ) : __( 'Activate', 'polanger-admin-menu-manager' ) ); ?>
                        </button>
                      </form>
                    <?php else : ?>
                      <button type="button" class="button button-secondary" disabled="disabled" aria-disabled="true">
                        <?php echo esc_html( $availability['button_text'] ); ?>
                      </button>
                    <?php endif; ?>
                  <?php endif; ?>
                  <?php if ( ( $is_core || $is_active ) && ! empty( $page_slug ) ) : ?>
                    <a class="button button-secondary" href="<?php echo esc_url( admin_url( 'admin.php?page=' . $page_slug ) ); ?>">
                      <?php esc_html_e( 'Open Addon', 'polanger-admin-menu-manager' ); ?>
                    </a>
                  <?php endif; ?>
                </div>
              </article>
            <?php endforeach; ?>
          <?php endif; ?>
        </div>
      </div>
    </div>
    <?php
  }

  /**
   * Resolve a presentational icon class for the addon card.
   *
   * @param string $addon_key Addon registry key.
   * @return string
   */
  private function get_addon_icon_class( $addon_key ) {
    $icons = array(
      'admin-activity-log'     => 'dashicons-visibility',
      'dashboard-widgets'      => 'dashicons-screenoptions',
      'custom-admin-menu'      => 'dashicons-menu-alt3',
      'design-system'          => 'dashicons-art',
      'comment-security'       => 'dashicons-shield-alt',
      'maintenance-center'     => 'dashicons-admin-tools',
      'firewall'               => 'dashicons-shield-alt',
      'polanger-shield'        => 'dashicons-shield',
      'recaptcha'              => 'dashicons-lock',
      'woocommerce-security'   => 'dashicons-cart',
      'polanger-authenticator' => 'dashicons-smartphone',
      'multisite-control'      => 'dashicons-networking',
    );

    return isset( $icons[ $addon_key ] ) ? $icons[ $addon_key ] : 'dashicons-admin-generic';
  }

  /**
   * Legacy compatibility shim.
   *
   * All supported addons are now managed from inside the suite, so this
   * always returns false.
   *
   * @param string $addon_key Addon slug.
   * @return bool
   */
  private function is_externally_managed_addon( $addon_key ) {
    unset( $addon_key );

    return false;
  }

  /**
   * Determine whether the addon is currently active.
   *
   * @param string $addon_key Addon slug.
   * @return bool
   */
  private function is_addon_currently_active( $addon_key ) {
    return function_exists( 'pdt_is_addon_active' )
      ? pdt_is_addon_active( $addon_key )
      : in_array( sanitize_key( $addon_key ), $this->get_active_addons(), true );
  }

  /**
   * Count active addons across internal modules and standalone companion plugins.
   *
   * @param array $addons Registered addons.
   * @return int
   */
  private function count_active_addons( $addons ) {
    $count = 0;

    foreach ( array_keys( $addons ) as $addon_key ) {
      if ( $this->is_addon_currently_active( $addon_key ) ) {
        $count++;
      }
    }

    return $count;
  }

  /**
   * Toggle a standalone companion plugin from the Addons screen.
   *
   * @param string $addon_slug Addon slug.
   * @param string $action     Requested action.
   * @return void
   */
  private function handle_external_addon_toggle( $addon_slug, $action ) {
    unset( $addon_slug, $action );
  }
}
