<?php
/**
 * Admin UI (menu page + floating trigger markup).
 *
 * @package Polanger_Shield
 */

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

class Polanger_Shield_Admin_UI {

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

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

    return self::$instance;
  }

  /**
   * Register hooks.
   *
   * @return void
   */
  public function register_hooks() {
    add_action( 'pdt_admin_menu_after_dashboard_center', array( $this, 'register_page' ), 12 );
    add_action( 'admin_post_polanger_shield_rule_action', array( $this, 'handle_rule_action' ) );
    add_action( 'admin_post_polanger_shield_bulk_action', array( $this, 'handle_bulk_action' ) );
    add_action( 'admin_footer', array( $this, 'render_floating_markup' ) );
    add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_page_assets' ) );
  }

  /**
   * Register Shield page under Polanger menu.
   *
   * @return void
   */
  public function register_page() {
    if ( ! current_user_can( 'manage_options' ) ) {
      return;
    }

    add_submenu_page(
      'polanger-dashboard',
      __( 'Polanger Shield', 'polanger-admin-menu-manager' ),
      __( 'Shield', 'polanger-admin-menu-manager' ),
      'manage_options',
      'polanger-shield',
      array( $this, 'render_page' )
    );
  }

  /**
   * Render Shield dashboard.
   *
   * @return void
   */
  public function render_page() {
    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      wp_die( esc_html__( 'You are not allowed to access Shield.', 'polanger-admin-menu-manager' ) );
    }

    $rules = Polanger_Shield_Rules::get_latest_rules( 150 );
    $safe_mode_active = Polanger_Shield_Safe_Mode::is_active();
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $focused_rule_id = isset( $_GET['rule_id'] ) ? absint( wp_unslash( $_GET['rule_id'] ) ) : 0;
    ?>
    <div class="wrap">
      <h1><?php esc_html_e( 'Polanger Shield', 'polanger-admin-menu-manager' ); ?></h1>
      <p><?php esc_html_e( 'Create page blocks, demo locks, hidden areas, and contextual notes from any admin screen via the floating shield icon. This page helps you review and disable rules safely.', 'polanger-admin-menu-manager' ); ?></p>
      <?php
      // phpcs:ignore WordPress.Security.NonceVerification.Recommended
      $status = isset( $_GET['shield_status'] ) ? sanitize_key( wp_unslash( $_GET['shield_status'] ) ) : '';
      if ( in_array( $status, array( 'updated', 'bulk-updated' ), true ) ) :
      ?>
        <div class="notice notice-success is-dismissible">
          <p><?php esc_html_e( 'Shield rules updated.', 'polanger-admin-menu-manager' ); ?></p>
        </div>
      <?php endif; ?>
      <p>
        <a class="button button-secondary" href="<?php echo esc_url( admin_url( 'admin.php?page=polanger-settings&tab=shield' ) ); ?>">
          <?php esc_html_e( 'Open Shield Settings', 'polanger-admin-menu-manager' ); ?>
        </a>
        <a
          class="button <?php echo $safe_mode_active ? 'button-primary' : 'button-secondary'; ?>"
          href="<?php echo esc_url( $safe_mode_active ? Polanger_Shield_Safe_Mode::get_disable_url( admin_url( 'admin.php?page=polanger-shield' ) ) : Polanger_Shield_Safe_Mode::get_enable_url( admin_url() ) ); ?>"
        >
          <?php echo esc_html( $safe_mode_active ? __( 'Exit Safe Mode', 'polanger-admin-menu-manager' ) : __( 'Open Safe Mode (temporary)', 'polanger-admin-menu-manager' ) ); ?>
        </a>
      </p>

      <?php if ( class_exists( 'Polanger_Shield_Global_Demo' ) ) : ?>
        <?php Polanger_Shield_Global_Demo::instance()->render_dashboard_summary(); ?>
      <?php endif; ?>

      <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
        <?php wp_nonce_field( 'polanger_shield_bulk_action' ); ?>
        <input type="hidden" name="action" value="polanger_shield_bulk_action" />

        <div class="polanger-shield-bulk-actions">
          <label for="polanger-shield-bulk-select"><?php esc_html_e( 'Bulk action:', 'polanger-admin-menu-manager' ); ?></label>
          <select id="polanger-shield-bulk-select" name="bulk_action">
            <option value=""><?php esc_html_e( 'Choose action', 'polanger-admin-menu-manager' ); ?></option>
            <option value="disable"><?php esc_html_e( 'Disable selected', 'polanger-admin-menu-manager' ); ?></option>
            <option value="delete"><?php esc_html_e( 'Delete selected', 'polanger-admin-menu-manager' ); ?></option>
          </select>
          <button type="submit" class="button button-secondary"><?php esc_html_e( 'Apply', 'polanger-admin-menu-manager' ); ?></button>
        </div>

        <table class="widefat striped">
          <thead>
            <tr>
              <th class="check-column">
                <input type="checkbox" id="polanger-shield-select-all" />
              </th>
              <th><?php esc_html_e( 'Type', 'polanger-admin-menu-manager' ); ?></th>
              <th><?php esc_html_e( 'Target', 'polanger-admin-menu-manager' ); ?></th>
              <th><?php esc_html_e( 'Users', 'polanger-admin-menu-manager' ); ?></th>
              <th><?php esc_html_e( 'Status', 'polanger-admin-menu-manager' ); ?></th>
              <th><?php esc_html_e( 'Created', 'polanger-admin-menu-manager' ); ?></th>
              <th><?php esc_html_e( 'Actions', 'polanger-admin-menu-manager' ); ?></th>
            </tr>
          </thead>
          <tbody>
            <?php if ( empty( $rules ) ) : ?>
              <tr>
                <td colspan="7"><?php esc_html_e( 'No rules yet.', 'polanger-admin-menu-manager' ); ?></td>
              </tr>
            <?php else : ?>
              <?php foreach ( $rules as $rule ) : ?>
                <tr class="<?php echo ( $focused_rule_id && (int) $rule->id === $focused_rule_id ) ? 'polanger-shield-row-focus' : ''; ?>" data-rule-id="<?php echo esc_attr( (string) $rule->id ); ?>">
                  <th class="check-column">
                    <input type="checkbox" name="rule_ids[]" value="<?php echo esc_attr( $rule->id ); ?>" />
                  </th>
                  <td><strong><?php echo esc_html( $this->human_rule_type( $rule->rule_type ) ); ?></strong></td>
                  <td>
                    <?php if ( ! empty( $rule->page_slug ) ) : ?>
                      <code><?php echo esc_html( $rule->page_slug ); ?></code>
                    <?php elseif ( ! empty( $rule->screen_id ) ) : ?>
                      <code><?php echo esc_html( $rule->screen_id ); ?></code>
                    <?php else : ?>
                      <code><?php echo esc_html( $rule->request_uri ); ?></code>
                    <?php endif; ?>
                    <?php if ( ! empty( $rule->selector ) ) : ?>
                      <div><code><?php echo esc_html( $rule->selector ); ?></code></div>
                    <?php endif; ?>
                    <?php $rule_description = $this->get_rule_secondary_description( $rule ); ?>
                    <?php if ( '' !== $rule_description ) : ?>
                      <div class="description"><?php echo esc_html( $rule_description ); ?></div>
                    <?php endif; ?>
                  </td>
                  <td><?php echo esc_html( $this->format_user_list( $rule->target_user_ids, $rule->note_visible_user_ids ) ); ?></td>
                  <td><?php echo esc_html( ucfirst( (string) $rule->status ) ); ?></td>
                  <td><?php echo esc_html( (string) $rule->created_at ); ?></td>
                  <td>
                    <a class="button button-secondary polanger-shield-inline-form <?php echo ( 'disabled' === $rule->status ) ? 'disabled' : ''; ?>" href="<?php echo esc_url( $this->build_row_action_url( $rule->id, 'disable' ) ); ?>">
                      <?php esc_html_e( 'Disable', 'polanger-admin-menu-manager' ); ?>
                    </a>
                    <a class="button button-secondary polanger-shield-inline-form" href="<?php echo esc_url( $this->get_rule_test_url( $rule ) ); ?>">
                      <?php esc_html_e( 'Test', 'polanger-admin-menu-manager' ); ?>
                    </a>
                    <a class="button button-link-delete polanger-shield-inline-form" href="<?php echo esc_url( $this->build_row_action_url( $rule->id, 'delete' ) ); ?>">
                      <?php esc_html_e( 'Delete', 'polanger-admin-menu-manager' ); ?>
                    </a>
                  </td>
                </tr>
              <?php endforeach; ?>
            <?php endif; ?>
          </tbody>
        </table>
      </form>
    </div>
    <?php
  }

  /**
   * Handle disable/delete actions from Shield page.
   *
   * @return void
   */
  public function handle_rule_action() {
    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      wp_die( esc_html__( 'Permission denied.', 'polanger-admin-menu-manager' ) );
    }

    check_admin_referer( 'polanger_shield_rule_action' );

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $rule_id = isset( $_REQUEST['rule_id'] ) ? absint( wp_unslash( $_REQUEST['rule_id'] ) ) : 0;
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $rule_action = isset( $_REQUEST['rule_action'] ) ? sanitize_key( wp_unslash( $_REQUEST['rule_action'] ) ) : '';
    if ( ! $rule_id ) {
      wp_safe_redirect( admin_url( 'admin.php?page=polanger-shield' ) );
      exit;
    }

    if ( 'disable' === $rule_action ) {
      Polanger_Shield_Rules::disable( $rule_id );
      Polanger_Shield_Activity::log(
        'shield_rule_disabled',
        array(
          'object_type' => 'shield_rule',
          'object_id'   => $rule_id,
        )
      );
    } elseif ( 'delete' === $rule_action ) {
      Polanger_Shield_Rules::delete( $rule_id );
      Polanger_Shield_Activity::log(
        'shield_rule_deleted',
        array(
          'object_type' => 'shield_rule',
          'object_id'   => $rule_id,
        )
      );
    }

    wp_safe_redirect( add_query_arg( 'shield_status', 'updated', admin_url( 'admin.php?page=polanger-shield' ) ) );
    exit;
  }

  /**
   * Handle bulk actions on Shield management page.
   *
   * @return void
   */
  public function handle_bulk_action() {
    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      wp_die( esc_html__( 'Permission denied.', 'polanger-admin-menu-manager' ) );
    }

    check_admin_referer( 'polanger_shield_bulk_action' );

    $bulk_action = isset( $_POST['bulk_action'] ) ? sanitize_key( wp_unslash( $_POST['bulk_action'] ) ) : '';
    $rule_ids = isset( $_POST['rule_ids'] ) ? array_values( array_unique( array_map( 'absint', (array) wp_unslash( $_POST['rule_ids'] ) ) ) ) : array();

    if ( empty( $rule_ids ) || ! in_array( $bulk_action, array( 'disable', 'delete' ), true ) ) {
      wp_safe_redirect( admin_url( 'admin.php?page=polanger-shield' ) );
      exit;
    }

    foreach ( $rule_ids as $rule_id ) {
      if ( 'disable' === $bulk_action ) {
        Polanger_Shield_Rules::disable( $rule_id );
        Polanger_Shield_Activity::log(
          'shield_rule_disabled',
          array(
            'object_type' => 'shield_rule',
            'object_id'   => $rule_id,
          )
        );
      } else {
        Polanger_Shield_Rules::delete( $rule_id );
        Polanger_Shield_Activity::log(
          'shield_rule_deleted',
          array(
            'object_type' => 'shield_rule',
            'object_id'   => $rule_id,
          )
        );
      }
    }

    wp_safe_redirect( add_query_arg( 'shield_status', 'bulk-updated', admin_url( 'admin.php?page=polanger-shield' ) ) );
    exit;
  }

  /**
   * Enqueue Shield admin page assets.
   *
   * @return void
   */
  public function enqueue_page_assets() {
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    if ( 'polanger-shield' !== $page ) {
      return;
    }

    wp_enqueue_script(
      'polanger-shield-admin-script',
      POLANGER_SHIELD_URL . 'assets/js/shield-admin.js',
      array( 'jquery' ),
      POLANGER_SHIELD_VERSION,
      true
    );

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

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

  /**
   * Render floating trigger skeleton.
   *
   * @return void
   */
  public function render_floating_markup() {
    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      return;
    }

    if ( Polanger_Shield_Safe_Mode::is_active() ) {
      return;
    }

    // Keep Shield controls outside own settings page where they are not useful.
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    if ( 'polanger-settings' === $page && isset( $_GET['tab'] ) ) {
      $settings_tab = sanitize_key( wp_unslash( $_GET['tab'] ) );

      if ( in_array( $settings_tab, array( 'shield', 'shield-demo' ), true ) ) {
        return;
      }
    }
    $active_count = Polanger_Shield_Rules::count_active();
    ?>
    <button
      type="button"
      id="polanger-shield-trigger"
      class="polanger-shield-trigger"
      aria-label="<?php esc_attr_e( 'Open Shield tools', 'polanger-admin-menu-manager' ); ?>"
      aria-controls="polanger-shield-panel"
      aria-expanded="false"
    >
      <span class="polanger-shield-trigger__icon">
        <span class="dashicons dashicons-shield-alt" aria-hidden="true"></span>
      </span>
      <span class="polanger-shield-pulse" aria-hidden="true"></span>
      <span class="polanger-shield-count"><?php echo esc_html( (string) $active_count ); ?></span>
    </button>

    <div id="polanger-shield-panel" class="polanger-shield-panel" hidden>
      <div class="polanger-shield-panel__header">
        <div class="polanger-shield-panel__intro">
          <span class="polanger-shield-panel__badge">
            <span class="dashicons dashicons-shield-alt" aria-hidden="true"></span>
          </span>
          <div class="polanger-shield-panel__copy">
            <strong><?php esc_html_e( 'Shield Tools', 'polanger-admin-menu-manager' ); ?></strong>
            <p><?php esc_html_e( 'Block pages, lock demo screens, hide sensitive UI, or pin clear internal notes for selected administrators.', 'polanger-admin-menu-manager' ); ?></p>
          </div>
        </div>
        <button type="button" class="polanger-shield-panel__close" aria-label="<?php esc_attr_e( 'Close Shield panel', 'polanger-admin-menu-manager' ); ?>">
          <span class="dashicons dashicons-no-alt" aria-hidden="true"></span>
        </button>
      </div>

      <div class="polanger-shield-panel__actions">
        <button type="button" class="polanger-shield-action-card" data-shield-action="page_block">
          <span class="polanger-shield-action-card__icon dashicons dashicons-hidden" aria-hidden="true"></span>
          <span class="polanger-shield-action-card__content">
            <span class="polanger-shield-action-card__title"><?php esc_html_e( 'Hide This Page', 'polanger-admin-menu-manager' ); ?></span>
            <span class="polanger-shield-action-card__text"><?php esc_html_e( 'Prevent selected admins from opening this screen or reaching it directly by URL.', 'polanger-admin-menu-manager' ); ?></span>
          </span>
        </button>

        <button type="button" class="polanger-shield-action-card" data-shield-action="element_hide">
          <span class="polanger-shield-action-card__icon dashicons dashicons-editor-contract" aria-hidden="true"></span>
          <span class="polanger-shield-action-card__content">
            <span class="polanger-shield-action-card__title"><?php esc_html_e( 'Select & Hide Area', 'polanger-admin-menu-manager' ); ?></span>
            <span class="polanger-shield-action-card__text"><?php esc_html_e( 'Pick a visible section on the page and hide only that area for selected administrators.', 'polanger-admin-menu-manager' ); ?></span>
          </span>
        </button>

        <div class="polanger-shield-action-row">
          <button type="button" class="polanger-shield-action-card" data-shield-action="demo_lock">
            <span class="polanger-shield-action-card__icon dashicons dashicons-lock" aria-hidden="true"></span>
            <span class="polanger-shield-action-card__content">
              <span class="polanger-shield-action-card__title"><?php esc_html_e( 'Lock This Page for Demo', 'polanger-admin-menu-manager' ); ?></span>
              <span class="polanger-shield-action-card__text"><?php esc_html_e( 'Let selected administrators browse this screen while Shield blocks saving, publishing, and live write requests.', 'polanger-admin-menu-manager' ); ?></span>
            </span>
          </button>

          <?php if ( class_exists( 'Polanger_Shield_Global_Demo' ) ) : ?>
            <a
              class="polanger-shield-action-settings"
              href="<?php echo esc_url( Polanger_Shield_Global_Demo::get_settings_url() ); ?>"
              title="<?php esc_attr_e( 'Open Global Demo Mode settings', 'polanger-admin-menu-manager' ); ?>"
              aria-label="<?php esc_attr_e( 'Open Global Demo Mode settings', 'polanger-admin-menu-manager' ); ?>"
            >
              <span class="dashicons dashicons-admin-generic" aria-hidden="true"></span>
            </a>
          <?php endif; ?>
        </div>

        <button type="button" class="polanger-shield-action-card" data-shield-action="note">
          <span class="polanger-shield-action-card__icon dashicons dashicons-edit-page" aria-hidden="true"></span>
          <span class="polanger-shield-action-card__content">
            <span class="polanger-shield-action-card__title"><?php esc_html_e( 'Leave Note', 'polanger-admin-menu-manager' ); ?></span>
            <span class="polanger-shield-action-card__text"><?php esc_html_e( 'Attach a contextual note to any admin element so selected users immediately understand what matters there.', 'polanger-admin-menu-manager' ); ?></span>
          </span>
        </button>
      </div>

      <a class="polanger-shield-manage-link" href="<?php echo esc_url( admin_url( 'admin.php?page=polanger-shield' ) ); ?>">
        <span class="polanger-shield-manage-copy">
          <span class="polanger-shield-manage-title"><?php esc_html_e( 'Manage Rules', 'polanger-admin-menu-manager' ); ?></span>
          <span class="polanger-shield-manage-text"><?php esc_html_e( 'Review active rules, test targets, or disable anything safely from one place.', 'polanger-admin-menu-manager' ); ?></span>
        </span>
        <span class="polanger-shield-manage-count"><?php echo esc_html( (string) $active_count ); ?></span>
      </a>
    </div>
    <?php
  }

  /**
   * Human-readable rule type.
   *
   * @param string $rule_type Rule type.
   * @return string
   */
  private function human_rule_type( $rule_type ) {
    switch ( $rule_type ) {
      case 'page_block':
        return __( 'Page Block', 'polanger-admin-menu-manager' );
      case 'element_hide':
        return __( 'Element Hide', 'polanger-admin-menu-manager' );
      case 'demo_lock':
        return __( 'Demo Lock', 'polanger-admin-menu-manager' );
      case 'note':
        return __( 'Note', 'polanger-admin-menu-manager' );
      default:
        return __( 'Unknown', 'polanger-admin-menu-manager' );
    }
  }

  /**
   * Format rule users for display.
   *
   * @param string $target_json Target users JSON.
   * @param string $visible_json Note visibility users JSON.
   * @return string
   */
  private function format_user_list( $target_json, $visible_json ) {
    $ids = json_decode( (string) $target_json, true );
    if ( ! is_array( $ids ) || empty( $ids ) ) {
      $ids = json_decode( (string) $visible_json, true );
      if ( ! is_array( $ids ) ) {
        $ids = array();
      }
    }

    $ids = array_values( array_unique( array_map( 'absint', $ids ) ) );
    if ( empty( $ids ) ) {
      return __( 'No users selected', 'polanger-admin-menu-manager' );
    }

    $users = get_users(
      array(
        'include' => $ids,
        'orderby' => 'display_name',
      )
    );
    if ( empty( $users ) ) {
      return __( 'Unknown users', 'polanger-admin-menu-manager' );
    }

    $names = wp_list_pluck( $users, 'display_name' );
    return implode( ', ', array_map( 'sanitize_text_field', $names ) );
  }

  /**
   * Build a short descriptive sentence for a rule row.
   *
   * @param object $rule Rule record.
   * @return string
   */
  private function get_rule_secondary_description( $rule ) {
    $rule_type = isset( $rule->rule_type ) ? sanitize_key( (string) $rule->rule_type ) : '';
    if ( 'demo_lock' !== $rule_type || ! class_exists( 'Polanger_Shield_Demo_Lock' ) ) {
      return '';
    }

    $meta = Polanger_Shield_Demo_Lock::get_rule_meta( $rule );
    $features = array();

    if ( ! empty( $meta['disable_controls'] ) ) {
      $features[] = __( 'visual save lock', 'polanger-admin-menu-manager' );
    }
    if ( ! empty( $meta['block_form_submissions'] ) ) {
      $features[] = __( 'form submits blocked', 'polanger-admin-menu-manager' );
    }
    if ( ! empty( $meta['block_ajax_requests'] ) ) {
      $features[] = __( 'AJAX writes blocked', 'polanger-admin-menu-manager' );
    }
    if ( ! empty( $meta['block_rest_requests'] ) ) {
      $features[] = __( 'REST writes blocked', 'polanger-admin-menu-manager' );
    }

    if ( empty( $features ) ) {
      return __( 'Demo lock keeps this screen view-only for selected users.', 'polanger-admin-menu-manager' );
    }

    return sprintf(
      /* translators: %s comma-separated lock capabilities */
      __( 'Demo lock keeps this screen view-only with %s.', 'polanger-admin-menu-manager' ),
      implode( ', ', $features )
    );
  }

  /**
   * Build row action URL.
   *
   * @param int    $rule_id Rule ID.
   * @param string $action Action name.
   * @return string
   */
  private function build_row_action_url( $rule_id, $action ) {
    $url = add_query_arg(
      array(
        'action'      => 'polanger_shield_rule_action',
        'rule_id'     => absint( $rule_id ),
        'rule_action' => sanitize_key( $action ),
      ),
      admin_url( 'admin-post.php' )
    );

    return wp_nonce_url( $url, 'polanger_shield_rule_action' );
  }

  /**
   * Resolve URL for testing a rule on its target page.
   *
   * @param object $rule Rule record.
   * @return string
   */
  private function get_rule_test_url( $rule ) {
    $rule_id = absint( $rule->id ?? 0 );
    $page_slug = sanitize_text_field( $rule->page_slug ?? '' );
    $request_uri = sanitize_text_field( $rule->request_uri ?? '' );

    if ( '' !== $page_slug ) {
      return add_query_arg(
        array(
          'page'                    => $page_slug,
          'polanger_shield_test_rule' => $rule_id,
        ),
        admin_url( 'admin.php' )
      );
    }

    if ( '' !== $request_uri ) {
      $relative = ltrim( preg_replace( '#^/wp-admin/#', '', $request_uri ), '/' );
      if ( '' !== $relative ) {
        return add_query_arg(
          'polanger_shield_test_rule',
          $rule_id,
          admin_url( $relative )
        );
      }
    }

    return add_query_arg(
      'polanger_shield_test_rule',
      $rule_id,
      admin_url()
    );
  }
}
