<?php
/**
 * Shield settings and Settings tab integration.
 *
 * @package Polanger_Shield
 */

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

class Polanger_Shield_Settings {

  /**
   * Option key.
   *
   * @var string
   */
  const OPTION_NAME = 'pdt_shield_settings';
  const NOTICE_DISMISSED_META = 'polanger_shield_notice_dismissed';

  /**
   * Singleton.
   *
   * @var Polanger_Shield_Settings|null
   */
  private static $instance = null;

  /**
   * Get singleton.
   *
   * @return Polanger_Shield_Settings
   */
  public static function instance() {
    if ( null === self::$instance ) {
      self::$instance = new self();
    }

    return self::$instance;
  }

  /**
   * Register hooks.
   *
   * @return void
   */
  public function register_hooks() {
    add_filter( 'pdt_settings_tabs', array( $this, 'register_tab' ) );
    add_filter( 'pdt_settings_tab_icons', array( $this, 'register_tab_icon' ) );
    add_action( 'pdt_settings_render_tab_shield', array( $this, 'render_tab' ) );
    add_action( 'admin_init', array( $this, 'maybe_sync_activity_log_setting' ), 20 );
    add_action( 'admin_init', array( $this, 'maybe_handle_save' ), 25 );
    add_action( 'admin_notices', array( $this, 'render_config_notice' ) );
    add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
    add_action( 'wp_ajax_polanger_shield_dismiss_notice', array( $this, 'ajax_dismiss_notice' ) );
  }

  /**
   * Get settings.
   *
   * @return array
   */
  public function get_settings() {
    $defaults = array(
      'manager_user_ids' => array(),
      'configured'       => false,
      'enable_activity_log' => true,
    );

    $settings = get_option( self::OPTION_NAME, array() );
    $settings = is_array( $settings ) ? $settings : array();
    $settings = wp_parse_args( $settings, $defaults );

    $settings['manager_user_ids'] = Polanger_Shield_Permissions::normalize_user_ids( $settings['manager_user_ids'] );
    $settings['configured'] = ! empty( $settings['configured'] );
    $settings['enable_activity_log'] = ! empty( $settings['enable_activity_log'] );

    return $settings;
  }

  /**
   * Update settings.
   *
   * @param array $settings Settings payload.
   * @return bool
   */
  public function update_settings( $settings ) {
    return update_option( self::OPTION_NAME, $settings );
  }

  /**
   * Keep Shield activity-log forwarding disabled when its dependency is unavailable.
   *
   * @return void
   */
  public function maybe_sync_activity_log_setting() {
    if ( ! $this->is_shield_enabled() || $this->is_activity_log_integration_available() ) {
      return;
    }

    $settings = get_option( self::OPTION_NAME, array() );
    if ( ! is_array( $settings ) || empty( $settings['enable_activity_log'] ) ) {
      return;
    }

    $settings['enable_activity_log'] = false;
    update_option( self::OPTION_NAME, $settings );
  }

  /**
   * Whether Shield has at least one manager configured.
   *
   * @return bool
   */
  public function is_configured() {
    $settings = $this->get_settings();
    return ! empty( $settings['manager_user_ids'] );
  }

  /**
   * Register Settings tab.
   *
   * @param array $tabs Existing tabs.
   * @return array
   */
  public function register_tab( $tabs ) {
    if ( ! $this->is_shield_enabled() ) {
      return $tabs;
    }

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

    $tabs['shield'] = __( 'Shield', 'polanger-admin-menu-manager' );
    return $tabs;
  }

  /**
   * Register Shield tab icon.
   *
   * @param array $icons Tab icon map.
   * @return array
   */
  public function register_tab_icon( $icons ) {
    if ( ! $this->is_shield_enabled() ) {
      return $icons;
    }

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

    $icons['shield'] = 'dashicons-shield-alt';
    return $icons;
  }

  /**
   * Save Settings tab form.
   *
   * @return void
   */
  public function maybe_handle_save() {
    if ( ! $this->is_shield_enabled() ) {
      return;
    }

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

    if ( ! check_admin_referer( 'pdt_shield_settings' ) ) {
      return;
    }

    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      return;
    }

    $manager_user_ids = array();
    if ( isset( $_POST['pdt_shield_manager_user_ids'] ) && is_array( $_POST['pdt_shield_manager_user_ids'] ) ) {
      $manager_user_ids = Polanger_Shield_Permissions::normalize_user_ids( wp_unslash( $_POST['pdt_shield_manager_user_ids'] ) );
    }

    $protected_admin_id = Polanger_Shield_Permissions::get_protected_admin_id();
    if ( $protected_admin_id && ! in_array( $protected_admin_id, $manager_user_ids, true ) ) {
      $manager_user_ids[] = $protected_admin_id;
    }

    $new_settings = $this->get_settings();
    $new_settings['manager_user_ids'] = $manager_user_ids;
    $new_settings['configured'] = ! empty( $manager_user_ids );
    $new_settings['enable_activity_log'] = $this->is_activity_log_integration_available() && isset( $_POST['pdt_shield_enable_activity_log'] );
    $this->update_settings( $new_settings );

    if ( class_exists( 'Polanger_Shield_Global_Demo_Settings' ) ) {
      Polanger_Shield_Global_Demo_Settings::instance()->save_from_combined_form();
    }

    Polanger_Shield_Activity::log(
      'shield_permissions_updated',
      array(
        'object_type' => 'shield_settings',
        'object_name' => 'Shield managers',
        'meta'        => array(
          'manager_count' => count( $manager_user_ids ),
          'activity_log'  => ! empty( $new_settings['enable_activity_log'] ),
        ),
      )
    );

    $redirect_args = array(
      'page'                => 'polanger-settings',
      'tab'                 => 'shield',
      'pdt_shield_settings' => 'saved',
    );

    if ( isset( $_POST['pdt_shield_global_demo'] ) ) {
      $redirect_args['pdt_shield_global_demo'] = 'saved';
    }

    wp_safe_redirect(
      add_query_arg(
        $redirect_args,
        admin_url( 'admin.php' )
      )
    );
    exit;
  }

  /**
   * Render Shield tab.
   *
   * @param bool $is_readonly Whether settings page is in readonly mode.
   * @return void
   */
  public function render_tab( $is_readonly ) {
    if ( ! $this->is_shield_enabled() ) {
      return;
    }

    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      echo '<div class="notice notice-warning"><p>' . esc_html__( 'You are not allowed to configure Shield settings.', 'polanger-admin-menu-manager' ) . '</p></div>';
      return;
    }

    $settings = $this->get_settings();
    $activity_log_available = $this->is_activity_log_integration_available();
    $activity_log_enabled   = $activity_log_available && ! empty( $settings['enable_activity_log'] );
    $activity_log_help      = $this->get_activity_log_dependency_message();
    $admins = get_users(
      array(
        'role__in' => array( 'administrator' ),
        'orderby'  => 'display_name',
        'order'    => 'ASC',
      )
    );
    ?>
    <div class="pdt-settings-section" id="polanger-shield-settings">
      <h2><?php esc_html_e( 'Shield Access & Demo Control', 'polanger-admin-menu-manager' ); ?></h2>
      <p class="description">
        <?php esc_html_e( 'Manage who can operate Shield itself. When Global Demo Mode is enabled below, every other administrator account automatically becomes a read-only demo user.', 'polanger-admin-menu-manager' ); ?>
      </p>

      <?php
      // phpcs:ignore WordPress.Security.NonceVerification.Recommended
      if ( ( isset( $_GET['pdt_shield_settings'] ) && 'saved' === sanitize_text_field( wp_unslash( $_GET['pdt_shield_settings'] ) ) ) || ( isset( $_GET['pdt_shield_global_demo'] ) && 'saved' === sanitize_text_field( wp_unslash( $_GET['pdt_shield_global_demo'] ) ) ) ) :
      ?>
        <div class="notice notice-success is-dismissible">
          <p><?php esc_html_e( 'Shield settings saved.', 'polanger-admin-menu-manager' ); ?></p>
        </div>
      <?php endif; ?>

      <form method="post" class="pdt-settings-form">
        <?php wp_nonce_field( 'pdt_shield_settings' ); ?>
        <div class="pdt-form-row">
          <label><?php esc_html_e( 'Shield managers', 'polanger-admin-menu-manager' ); ?></label>
          <p class="description">
            <?php esc_html_e( 'Only selected administrators can open the Shield panel, create rules, and manage Shield-wide settings.', 'polanger-admin-menu-manager' ); ?>
          </p>
          <div class="polanger-shield-access-grid">
            <?php foreach ( $admins as $admin ) : ?>
              <?php
              $is_selected = in_array( (int) $admin->ID, (array) $settings['manager_user_ids'], true );
              $is_protected = ( (int) $admin->ID === Polanger_Shield_Permissions::get_protected_admin_id() );
              ?>
              <label class="polanger-shield-access-card <?php echo $is_selected ? 'is-selected' : ''; ?>">
                <input
                  type="checkbox"
                  name="pdt_shield_manager_user_ids[]"
                  value="<?php echo esc_attr( $admin->ID ); ?>"
                  <?php checked( $is_selected ); ?>
                  <?php echo $is_protected ? 'disabled' : ''; ?>
                />
                <span class="polanger-shield-access-name"><?php echo esc_html( $admin->display_name ); ?></span>
                <span class="polanger-shield-access-email"><?php echo esc_html( $admin->user_email ); ?></span>
                <?php if ( $is_protected ) : ?>
                  <small class="polanger-shield-access-badge"><?php esc_html_e( 'Protected admin (required)', 'polanger-admin-menu-manager' ); ?></small>
                  <input type="hidden" name="pdt_shield_manager_user_ids[]" value="<?php echo esc_attr( $admin->ID ); ?>" />
                <?php endif; ?>
              </label>
            <?php endforeach; ?>
          </div>
        </div>

        <div class="pdt-form-row">
          <a class="button button-secondary" href="<?php echo esc_url( admin_url( 'admin.php?page=polanger-shield' ) ); ?>">
            <?php esc_html_e( 'Open Shield Dashboard', 'polanger-admin-menu-manager' ); ?>
          </a>
        </div>

        <div class="pdt-form-row">
          <label class="pdt-toggle-switch">
            <input
              type="checkbox"
              name="pdt_shield_enable_activity_log"
              value="1"
              <?php checked( $activity_log_enabled ); ?>
              <?php disabled( ! $activity_log_available ); ?>
            />
            <span class="pdt-toggle-slider"></span>
            <span class="pdt-toggle-label"><?php esc_html_e( 'Send key Shield events to Activity Log', 'polanger-admin-menu-manager' ); ?></span>
          </label>
          <p class="description">
            <?php echo esc_html( $activity_log_help ); ?>
          </p>
        </div>

        <?php if ( class_exists( 'Polanger_Shield_Global_Demo_Settings' ) ) : ?>
          <?php Polanger_Shield_Global_Demo_Settings::instance()->render_embedded_section( $is_readonly ); ?>
        <?php endif; ?>

        <p>
          <button
            type="submit"
            class="button button-primary"
            name="pdt_shield_save"
            <?php disabled( ! empty( $is_readonly ) ); ?>
          >
            <?php esc_html_e( 'Save Shield Settings', 'polanger-admin-menu-manager' ); ?>
          </button>
        </p>
      </form>
    </div>
    <?php
  }

  /**
   * Render setup reminder notice.
   *
   * @return void
   */
  public function render_config_notice() {
    if ( ! $this->should_show_config_notice() ) {
      return;
    }
    ?>
    <div class="notice notice-warning is-dismissible polanger-shield-config-notice">
      <p>
        <?php esc_html_e( 'Polanger Shield is active. Please configure who can use Shield tools from Settings > Shield.', 'polanger-admin-menu-manager' ); ?>
      </p>
    </div>
    <?php
  }

  /**
   * Whether addon is enabled in Polanger Addons page.
   *
   * @return bool
   */
  private function is_shield_enabled() {
    return function_exists( 'pdt_get_user_access_level' );
  }

  /**
   * Whether the Admin Activity Log addon is active.
   *
   * @return bool
   */
  private function is_activity_log_addon_active() {
    return function_exists( 'pdt_is_addon_active' ) && pdt_is_addon_active( 'admin-activity-log' );
  }

  /**
   * Whether Activity Log recording is enabled in its own settings.
   *
   * @return bool
   */
  private function is_activity_log_logging_enabled() {
    $settings = get_option( 'pdt_activity_log_settings', array() );

    return ! empty( $settings['enabled'] );
  }

  /**
   * Whether Shield can currently forward events into Activity Log.
   *
   * @return bool
   */
  private function is_activity_log_integration_available() {
    return $this->is_activity_log_addon_active() && $this->is_activity_log_logging_enabled();
  }

  /**
   * Describe the current dependency state of Shield activity forwarding.
   *
   * @return string
   */
  private function get_activity_log_dependency_message() {
    if ( ! $this->is_activity_log_addon_active() ) {
      return __( 'Enable the Admin Activity Log addon first. Shield can forward events only after that addon is active.', 'polanger-admin-menu-manager' );
    }

    if ( ! $this->is_activity_log_logging_enabled() ) {
      return __( 'Admin Activity Log is active, but its own logging switch is currently off. Turn on logging there first, then you can enable Shield event forwarding here.', 'polanger-admin-menu-manager' );
    }

    return __( 'Shield can forward key events because Admin Activity Log is active and logging is enabled there.', 'polanger-admin-menu-manager' );
  }

  /**
   * Enqueue styles for Shield settings tab.
   *
   * @return void
   */
  public function enqueue_assets() {
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';

    if ( 'polanger-settings' !== $page || 'shield' !== $tab ) {
      if ( $this->should_show_config_notice() ) {
        wp_enqueue_script(
          'polanger-shield-notice',
          POLANGER_SHIELD_URL . 'assets/js/shield-notice.js',
          array( 'jquery' ),
          POLANGER_SHIELD_VERSION,
          true
        );

        wp_localize_script(
          'polanger-shield-notice',
          'polangerShieldNotice',
          array(
            'ajaxUrl' => admin_url( 'admin-ajax.php' ),
            'nonce'   => wp_create_nonce( 'polanger_shield_dismiss_notice' ),
          )
        );
      }

      return;
    }

    wp_enqueue_style(
      'polanger-shield-settings',
      POLANGER_SHIELD_URL . 'assets/css/shield-settings.css',
      array(),
      POLANGER_SHIELD_VERSION
    );
  }

  /**
   * Handle permanent dismiss action for setup notice.
   *
   * @return void
   */
  public function ajax_dismiss_notice() {
    check_ajax_referer( 'polanger_shield_dismiss_notice', 'nonce' );

    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      wp_send_json_error(
        array(
          'message' => __( 'Permission denied.', 'polanger-admin-menu-manager' ),
        ),
        403
      );
    }

    update_user_meta( get_current_user_id(), self::NOTICE_DISMISSED_META, 1 );
    wp_send_json_success();
  }

  /**
   * Check whether setup notice should be visible.
   *
   * @return bool
   */
  private function should_show_config_notice() {
    if ( ! $this->is_shield_enabled() ) {
      return false;
    }

    if ( $this->is_configured() ) {
      return false;
    }

    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      return false;
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    if ( 0 !== strpos( $page, 'polanger-' ) ) {
      return false;
    }

    $dismissed = (int) get_user_meta( get_current_user_id(), self::NOTICE_DISMISSED_META, true );
    return 1 !== $dismissed;
  }
}
