<?php
/**
 * Global Shield demo mode settings integration.
 *
 * @package Polanger_Shield
 */

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

class Polanger_Shield_Global_Demo_Settings {

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

  /**
   * Get singleton instance.
   *
   * @return Polanger_Shield_Global_Demo_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_action( 'admin_init', array( $this, 'maybe_handle_save' ), 26 );
    add_action( 'admin_init', array( $this, 'maybe_redirect_legacy_tab' ), 27 );
    add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
  }

  /**
   * Register tab label.
   *
   * @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-demo'] = __( 'Shield Demo Mode', 'polanger-admin-menu-manager' );
    return $tabs;
  }

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

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

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

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

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

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

    if ( ! $this->current_user_can_save() ) {
      return;
    }

    $this->save_from_combined_form();

    wp_safe_redirect(
      add_query_arg(
        array(
          'page'                    => 'polanger-settings',
          'tab'                     => 'shield',
          'pdt_shield_global_demo'  => 'saved',
        ),
        admin_url( 'admin.php' )
      )
    );
    exit;
  }

  /**
   * Save Global Demo settings when embedded inside the main Shield tab.
   *
   * @return bool
   */
  public function save_from_combined_form() {
    if ( ! $this->current_user_can_save() ) {
      return false;
    }

    $raw_settings = isset( $_POST['pdt_shield_global_demo'] ) ? wp_unslash( $_POST['pdt_shield_global_demo'] ) : array();
    $settings     = Polanger_Shield_Global_Demo::instance()->sanitize_settings( $raw_settings );

    if ( empty( $settings['target_user_ids'] ) ) {
      $settings['enabled'] = false;
    }

    Polanger_Shield_Global_Demo::instance()->update_settings( $settings );

    Polanger_Shield_Activity::log(
      'shield_global_demo_settings_updated',
      array(
        'object_type' => 'shield_global_demo',
        'object_name' => 'Global Demo Mode',
        'meta'        => array(
          'enabled'          => ! empty( $settings['enabled'] ),
          'protection_level' => sanitize_key( $settings['protection_level'] ),
          'target_count'     => count( $settings['target_user_ids'] ),
        ),
      )
    );

    return true;
  }

  /**
   * Redirect the retired Shield Demo tab back to the main Shield tab.
   *
   * @return void
   */
  public function maybe_redirect_legacy_tab() {
    if ( ! $this->is_shield_enabled() || 'POST' === strtoupper( isset( $_SERVER['REQUEST_METHOD'] ) ? (string) $_SERVER['REQUEST_METHOD'] : 'GET' ) ) {
      return;
    }

    $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    $tab  = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';

    if ( 'polanger-settings' !== $page || 'shield-demo' !== $tab ) {
      return;
    }

    wp_safe_redirect( Polanger_Shield_Global_Demo::get_settings_url() );
    exit;
  }

  /**
   * Render tab body.
   *
   * @param bool $is_readonly Read-only mode flag from core settings page.
   * @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 Global Demo Mode.', 'polanger-admin-menu-manager' ) . '</p></div>';
      return;
    }

    $settings = Polanger_Shield_Global_Demo::instance()->get_settings();
    $target_users = Polanger_Shield_Global_Demo::instance()->get_target_users();
    $get_actions_value  = implode( "\n", (array) $settings['allowed_get_actions'] );
    $ajax_actions_value = implode( "\n", (array) $settings['allowed_ajax_actions'] );
    $rest_routes_value  = implode( "\n", (array) $settings['allowed_rest_routes'] );
    ?>
    <div class="pdt-settings-section polanger-shield-global-demo-settings" data-polanger-shield-global-demo-settings="1" id="polanger-shield-global-demo">
      <h2><?php esc_html_e( 'Global Demo Mode', 'polanger-admin-menu-manager' ); ?></h2>
      <p class="description">
        <?php esc_html_e( 'Configure how aggressively Shield blocks write operations when Global Demo Mode automatically applies to administrator accounts that are not selected above as Shield managers.', 'polanger-admin-menu-manager' ); ?>
      </p>

      <div class="pdt-form-row">
        <label class="pdt-toggle-switch">
          <input
            type="checkbox"
            name="pdt_shield_global_demo[enabled]"
            value="1"
            id="pdt-shield-global-demo-enabled"
            <?php checked( ! empty( $settings['enabled'] ) ); ?>
          />
          <span class="pdt-toggle-slider"></span>
          <span class="pdt-toggle-label"><?php esc_html_e( 'Enable Global Demo Mode', 'polanger-admin-menu-manager' ); ?></span>
        </label>
        <p class="description">
          <?php esc_html_e( 'When enabled, every administrator account that is not selected above as a Shield manager enters a read-only admin session automatically. Shield managers and the protected recovery administrator always bypass this mode so the site is never stranded.', 'polanger-admin-menu-manager' ); ?>
        </p>
      </div>

      <div
        id="polanger-shield-global-demo-config"
        class="polanger-shield-global-demo-settings__config<?php echo ! empty( $settings['enabled'] ) ? ' is-visible' : ''; ?>"
      >
          <div class="polanger-shield-global-demo-settings__intro-grid">
            <article class="polanger-shield-global-demo-mode-card">
              <span class="polanger-shield-global-demo-mode-card__eyebrow"><?php esc_html_e( 'Balanced Mode', 'polanger-admin-menu-manager' ); ?></span>
              <h3><?php esc_html_e( 'Best for live product demos and client walkthroughs.', 'polanger-admin-menu-manager' ); ?></h3>
              <p><?php esc_html_e( 'Adds a clear banner, visually disables risky controls, and blocks classic form submissions plus REST writes and non-GET AJAX requests by default. Normal page rendering stays as stable as possible while the session feels safely read-only.', 'polanger-admin-menu-manager' ); ?></p>
            </article>

            <article class="polanger-shield-global-demo-mode-card is-strict">
              <span class="polanger-shield-global-demo-mode-card__eyebrow"><?php esc_html_e( 'Strict Mode', 'polanger-admin-menu-manager' ); ?></span>
              <h3><?php esc_html_e( 'Adds last-line backstops for harder demo environments.', 'polanger-admin-menu-manager' ); ?></h3>
              <p><?php esc_html_e( 'Keeps the balanced protections and can also stop database writes, outgoing emails, external requests, and uploads during mutation-like requests. Use this when demos must stay exceptionally clean even if a plugin tries something unexpected.', 'polanger-admin-menu-manager' ); ?></p>
            </article>
          </div>

          <div class="pdt-form-row">
            <p class="description">
              <?php esc_html_e( 'Global Demo Mode now follows the Shield managers list above. Any administrator who is not selected there is treated as a demo user automatically.', 'polanger-admin-menu-manager' ); ?>
            </p>
            <?php if ( empty( $target_users ) ) : ?>
              <p class="description">
                <?php esc_html_e( 'No additional administrator accounts are currently eligible. Add another admin or remove a manager assignment first if you want to target a demo user.', 'polanger-admin-menu-manager' ); ?>
              </p>
            <?php endif; ?>
          </div>

          <div class="pdt-form-row">
            <label><?php esc_html_e( 'Protection level', 'polanger-admin-menu-manager' ); ?></label>
            <p class="description">
              <?php esc_html_e( 'Balanced mode is the recommended default. Strict mode adds deeper write-side protections for higher-risk demo environments.', 'polanger-admin-menu-manager' ); ?>
            </p>

            <div class="polanger-shield-global-demo-level-grid">
              <label class="polanger-shield-global-demo-level-option <?php echo 'balanced' === $settings['protection_level'] ? 'is-selected' : ''; ?>">
                <input type="radio" name="pdt_shield_global_demo[protection_level]" value="balanced" <?php checked( $settings['protection_level'], 'balanced' ); ?> />
                <span class="polanger-shield-global-demo-level-option__body">
                  <strong><?php esc_html_e( 'Balanced', 'polanger-admin-menu-manager' ); ?></strong>
                  <small><?php esc_html_e( 'Stable browsing, blocked saves, and minimal demo friction.', 'polanger-admin-menu-manager' ); ?></small>
                </span>
              </label>

              <label class="polanger-shield-global-demo-level-option <?php echo 'strict' === $settings['protection_level'] ? 'is-selected' : ''; ?>">
                <input type="radio" name="pdt_shield_global_demo[protection_level]" value="strict" <?php checked( $settings['protection_level'], 'strict' ); ?> />
                <span class="polanger-shield-global-demo-level-option__body">
                  <strong><?php esc_html_e( 'Strict', 'polanger-admin-menu-manager' ); ?></strong>
                  <small><?php esc_html_e( 'Adds database and side-effect backstops on top of the balanced guardrails.', 'polanger-admin-menu-manager' ); ?></small>
                </span>
              </label>
            </div>
          </div>

          <div class="polanger-shield-global-demo-settings__option-grid">
            <label class="polanger-shield-global-demo-toggle-card">
              <input type="checkbox" name="pdt_shield_global_demo[show_banner]" value="1" <?php checked( ! empty( $settings['show_banner'] ) ); ?> />
              <span>
                <strong><?php esc_html_e( 'Show demo banner', 'polanger-admin-menu-manager' ); ?></strong>
                <small><?php esc_html_e( 'Explain clearly that the account is browsing a protected read-only session.', 'polanger-admin-menu-manager' ); ?></small>
              </span>
            </label>

            <label class="polanger-shield-global-demo-toggle-card">
              <input type="checkbox" name="pdt_shield_global_demo[disable_controls]" value="1" <?php checked( ! empty( $settings['disable_controls'] ) ); ?> />
              <span>
                <strong><?php esc_html_e( 'Visually dim risky controls', 'polanger-admin-menu-manager' ); ?></strong>
                <small><?php esc_html_e( 'Marks save, publish, delete, import, reset, and similar actions as unavailable before they are clicked.', 'polanger-admin-menu-manager' ); ?></small>
              </span>
            </label>

            <label class="polanger-shield-global-demo-toggle-card">
              <input type="checkbox" name="pdt_shield_global_demo[block_post_requests]" value="1" <?php checked( ! empty( $settings['block_post_requests'] ) ); ?> />
              <span>
                <strong><?php esc_html_e( 'Block classic form submissions', 'polanger-admin-menu-manager' ); ?></strong>
                <small><?php esc_html_e( 'Prevents settings forms, classic editor saves, and other direct POST-based writes from finishing.', 'polanger-admin-menu-manager' ); ?></small>
              </span>
            </label>

            <label class="polanger-shield-global-demo-toggle-card">
              <input type="checkbox" name="pdt_shield_global_demo[block_ajax_requests]" value="1" <?php checked( ! empty( $settings['block_ajax_requests'] ) ); ?> />
              <span>
                <strong><?php esc_html_e( 'Block AJAX write actions', 'polanger-admin-menu-manager' ); ?></strong>
                <small><?php esc_html_e( 'Blocks non-GET admin-ajax requests by default and only allows explicitly approved actions such as heartbeat.', 'polanger-admin-menu-manager' ); ?></small>
              </span>
            </label>

            <label class="polanger-shield-global-demo-toggle-card">
              <input type="checkbox" name="pdt_shield_global_demo[block_rest_requests]" value="1" <?php checked( ! empty( $settings['block_rest_requests'] ) ); ?> />
              <span>
                <strong><?php esc_html_e( 'Block REST write requests', 'polanger-admin-menu-manager' ); ?></strong>
                <small><?php esc_html_e( 'Protects block editor, modern settings screens, and other interfaces that save through the WordPress REST API.', 'polanger-admin-menu-manager' ); ?></small>
              </span>
            </label>
          </div>

          <div
            id="polanger-shield-global-demo-strict-options"
            class="polanger-shield-global-demo-settings__strict<?php echo 'strict' === $settings['protection_level'] ? ' is-visible' : ''; ?>"
          >
            <h3><?php esc_html_e( 'Strict mode backstops', 'polanger-admin-menu-manager' ); ?></h3>
            <p class="description">
              <?php esc_html_e( 'These guards run only when Strict mode is selected and Shield detects a mutation-like request. They are designed as a last line of defense rather than a replacement for the balanced guards above.', 'polanger-admin-menu-manager' ); ?>
            </p>

            <div class="polanger-shield-global-demo-settings__option-grid">
              <label class="polanger-shield-global-demo-toggle-card">
                <input type="checkbox" name="pdt_shield_global_demo[block_database_writes]" value="1" <?php checked( ! empty( $settings['block_database_writes'] ) ); ?> />
                <span>
                  <strong><?php esc_html_e( 'Block database writes', 'polanger-admin-menu-manager' ); ?></strong>
                  <small><?php esc_html_e( 'Acts as a low-level safety net against INSERT, UPDATE, DELETE, CREATE, DROP, and similar write queries.', 'polanger-admin-menu-manager' ); ?></small>
                </span>
              </label>

              <label class="polanger-shield-global-demo-toggle-card">
                <input type="checkbox" name="pdt_shield_global_demo[block_emails]" value="1" <?php checked( ! empty( $settings['block_emails'] ) ); ?> />
                <span>
                  <strong><?php esc_html_e( 'Block outgoing emails', 'polanger-admin-menu-manager' ); ?></strong>
                  <small><?php esc_html_e( 'Useful when demo actions should never send transactional or notification emails to real recipients.', 'polanger-admin-menu-manager' ); ?></small>
                </span>
              </label>

              <label class="polanger-shield-global-demo-toggle-card">
                <input type="checkbox" name="pdt_shield_global_demo[block_http_requests]" value="1" <?php checked( ! empty( $settings['block_http_requests'] ) ); ?> />
                <span>
                  <strong><?php esc_html_e( 'Block external HTTP requests', 'polanger-admin-menu-manager' ); ?></strong>
                  <small><?php esc_html_e( 'Prevents save flows from pushing data to webhooks, remote APIs, or third-party services during a protected session.', 'polanger-admin-menu-manager' ); ?></small>
                </span>
              </label>

              <label class="polanger-shield-global-demo-toggle-card">
                <input type="checkbox" name="pdt_shield_global_demo[block_media_uploads]" value="1" <?php checked( ! empty( $settings['block_media_uploads'] ) ); ?> />
                <span>
                  <strong><?php esc_html_e( 'Block uploads', 'polanger-admin-menu-manager' ); ?></strong>
                  <small><?php esc_html_e( 'Stops new files from landing in uploads while the demo account is trying to change content.', 'polanger-admin-menu-manager' ); ?></small>
                </span>
              </label>
            </div>
          </div>

          <div class="polanger-shield-global-demo-settings__allowlists">
            <div class="pdt-form-row">
              <label for="polanger-shield-global-demo-get-actions"><?php esc_html_e( 'Allowed GET actions', 'polanger-admin-menu-manager' ); ?></label>
              <p class="description">
                <?php esc_html_e( 'One action per line. Leave empty to block risky GET-based actions such as activate, deactivate, delete, trash, or reset whenever Shield detects them.', 'polanger-admin-menu-manager' ); ?>
              </p>
              <textarea
                id="polanger-shield-global-demo-get-actions"
                name="pdt_shield_global_demo[allowed_get_actions]"
                class="large-text code"
                rows="5"
              ><?php echo esc_textarea( $get_actions_value ); ?></textarea>
            </div>

            <div class="pdt-form-row">
              <label for="polanger-shield-global-demo-ajax-actions"><?php esc_html_e( 'Allowed AJAX actions', 'polanger-admin-menu-manager' ); ?></label>
              <p class="description">
                <?php esc_html_e( 'One admin-ajax action per line. Heartbeat is allowed by default so routine admin pings do not feel broken.', 'polanger-admin-menu-manager' ); ?>
              </p>
              <textarea
                id="polanger-shield-global-demo-ajax-actions"
                name="pdt_shield_global_demo[allowed_ajax_actions]"
                class="large-text code"
                rows="5"
              ><?php echo esc_textarea( $ajax_actions_value ); ?></textarea>
            </div>

            <div class="pdt-form-row">
              <label for="polanger-shield-global-demo-rest-routes"><?php esc_html_e( 'Allowed REST route fragments', 'polanger-admin-menu-manager' ); ?></label>
              <p class="description">
                <?php esc_html_e( 'One route fragment per line if a specific REST endpoint must keep working during a demo. Use sparingly and only when you understand the write behavior it enables.', 'polanger-admin-menu-manager' ); ?>
              </p>
              <textarea
                id="polanger-shield-global-demo-rest-routes"
                name="pdt_shield_global_demo[allowed_rest_routes]"
                class="large-text code"
                rows="5"
              ><?php echo esc_textarea( $rest_routes_value ); ?></textarea>
            </div>
          </div>
      </div>
    </div>
    <?php
  }

  /**
   * Render the embedded Global Demo section inside the main Shield tab.
   *
   * @param bool $is_readonly Read-only mode flag from core settings page.
   * @return void
   */
  public function render_embedded_section( $is_readonly ) {
    $this->render_tab( $is_readonly );
  }

  /**
   * Enqueue tab assets.
   *
   * @return void
   */
  public function enqueue_assets() {
    if ( ! $this->is_shield_enabled() ) {
      return;
    }

    $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
    $tab  = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';

    if ( 'polanger-settings' !== $page || ! in_array( $tab, array( 'shield', 'shield-demo' ), true ) ) {
      return;
    }

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

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

    wp_enqueue_script(
      'polanger-shield-global-demo-settings',
      POLANGER_SHIELD_URL . 'assets/js/shield-global-demo-settings.js',
      array( 'jquery' ),
      POLANGER_SHIELD_VERSION,
      true
    );
  }

  /**
   * Determine whether Shield integration may register its settings tab.
   *
   * @return bool
   */
  private function is_shield_enabled() {
    return function_exists( 'pdt_get_user_access_level' );
  }

  /**
   * Whether the current user may persist Global Demo settings.
   *
   * Respects both Shield manager assignment and Polanger read-only access.
   *
   * @return bool
   */
  private function current_user_can_save() {
    if ( ! Polanger_Shield_Permissions::current_user_can_manage_shield( true ) ) {
      return false;
    }

    if ( function_exists( 'pdt_current_user_can_manage' ) ) {
      return pdt_current_user_can_manage();
    }

    if ( function_exists( 'pdt_get_user_access_level' ) ) {
      return 'readonly' !== pdt_get_user_access_level();
    }

    return current_user_can( 'manage_options' );
  }

}
