<?php
/**
 * Frontend content visibility editor integrations.
 *
 * @package Polanger_Dashboard_Tools
 */

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

class PDT_Content_Visibility_Meta_Box {

  /**
   * Register editor hooks.
   *
   * @return void
   */
  public function register_hooks() {
    add_action( 'add_meta_boxes', array( $this, 'register_meta_boxes' ) );
    add_action( 'save_post', array( $this, 'save_meta_box' ) );
    add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
  }

  /**
   * Register the classic editor side meta box.
   *
   * @return void
   */
  public function register_meta_boxes() {
    foreach ( PDT_Content_Visibility::get_supported_post_types() as $post_type ) {
      if ( function_exists( 'use_block_editor_for_post_type' ) && use_block_editor_for_post_type( $post_type ) ) {
        continue;
      }

      add_meta_box(
        'pdt-content-visibility',
        __( 'Content Visibility', 'polanger-admin-menu-manager' ),
        array( $this, 'render_meta_box' ),
        $post_type,
        'side',
        'default'
      );
    }
  }

  /**
   * Render the classic editor meta box.
   *
   * @param WP_Post $post Current post object.
   * @return void
   */
  public function render_meta_box( $post ) {
    $rule                  = PDT_Content_Visibility::get_post_rule( $post->ID );
    $visibility_options    = PDT_Content_Visibility::get_editor_visibility_mode_options( $rule['mode'] );
    $behavior_options      = PDT_Content_Visibility::get_denied_behavior_options( true );
    $compatibility_options = PDT_Content_Visibility::get_compatibility_mode_options( true );
    $roles                 = PDT_Content_Visibility::get_role_labels();
    $default_settings_url  = PDT_Content_Visibility::get_default_settings_url();

    wp_nonce_field( 'pdt_content_visibility_save', 'pdt_content_visibility_nonce' );
    ?>
    <div class="pdt-content-visibility-metabox">
      <p class="pdt-content-visibility-metabox__intro">
        <?php esc_html_e( 'Choose whether this content stays public, is limited to signed-in users, or is hidden from specific roles on the public site.', 'polanger-admin-menu-manager' ); ?>
      </p>
      <p class="pdt-content-visibility-metabox__defaults">
        <a href="<?php echo esc_url( $default_settings_url ); ?>" target="_blank" rel="noopener noreferrer">
          <?php esc_html_e( 'Default Settings', 'polanger-admin-menu-manager' ); ?>
        </a>
      </p>

      <p class="pdt-content-visibility-field">
        <label for="pdt_content_visibility_mode"><strong><?php esc_html_e( 'Access rule', 'polanger-admin-menu-manager' ); ?></strong></label>
        <select id="pdt_content_visibility_mode" name="pdt_content_visibility_mode" class="widefat">
          <?php foreach ( $visibility_options as $value => $label ) : ?>
            <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $rule['mode'], $value ); ?>>
              <?php echo esc_html( $label ); ?>
            </option>
          <?php endforeach; ?>
        </select>
        <span
          class="description pdt-content-visibility-mode-help"
          data-default-text="<?php echo esc_attr__( 'Use "Hide from selected roles" when you want to block this content for specific user roles only.', 'polanger-admin-menu-manager' ); ?>"
          data-legacy-text="<?php echo esc_attr__( 'This content is using a legacy allowlist rule from an older version. New rules now focus on hiding content from selected roles to keep the workflow clearer.', 'polanger-admin-menu-manager' ); ?>"
        >
          <?php echo esc_html( 'show_roles' === $rule['mode'] ? __( 'This content is using a legacy allowlist rule from an older version. New rules now focus on hiding content from selected roles to keep the workflow clearer.', 'polanger-admin-menu-manager' ) : __( 'Use "Hide from selected roles" when you want to block this content for specific user roles only.', 'polanger-admin-menu-manager' ) ); ?>
        </span>
      </p>

      <div class="pdt-content-visibility-field pdt-content-visibility-role-field">
        <span class="pdt-content-visibility-field__label"><strong><?php esc_html_e( 'Roles', 'polanger-admin-menu-manager' ); ?></strong></span>
        <div class="pdt-content-visibility-roles">
          <?php foreach ( $roles as $role_slug => $role_label ) : ?>
            <label class="pdt-content-visibility-role">
              <input
                type="checkbox"
                name="pdt_content_visibility_roles[]"
                value="<?php echo esc_attr( $role_slug ); ?>"
                <?php checked( in_array( $role_slug, $rule['roles'], true ) ); ?>
              />
              <span><?php echo esc_html( $role_label ); ?></span>
            </label>
          <?php endforeach; ?>
        </div>
        <span
          class="description pdt-content-visibility-role-help"
          data-default-text="<?php echo esc_attr__( 'Selected roles will be blocked from viewing this content on the frontend.', 'polanger-admin-menu-manager' ); ?>"
          data-legacy-text="<?php echo esc_attr__( 'Legacy rule: only the selected roles can view this content. Guests and all other roles are blocked.', 'polanger-admin-menu-manager' ); ?>"
        >
          <?php echo esc_html( 'show_roles' === $rule['mode'] ? __( 'Legacy rule: only the selected roles can view this content. Guests and all other roles are blocked.', 'polanger-admin-menu-manager' ) : __( 'Selected roles will be blocked from viewing this content on the frontend.', 'polanger-admin-menu-manager' ) ); ?>
        </span>
      </div>

      <p class="pdt-content-visibility-field">
        <label for="pdt_content_visibility_denied_behavior"><strong><?php esc_html_e( 'When access is denied', 'polanger-admin-menu-manager' ); ?></strong></label>
        <select id="pdt_content_visibility_denied_behavior" name="pdt_content_visibility_denied_behavior" class="widefat">
          <?php foreach ( $behavior_options as $value => $label ) : ?>
            <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $rule['denied'], $value ); ?>>
              <?php echo esc_html( $label ); ?>
            </option>
          <?php endforeach; ?>
        </select>
      </p>

      <div class="pdt-content-visibility-field pdt-content-visibility-message-field">
        <label for="pdt_content_visibility_message"><strong><?php esc_html_e( 'Custom access denied message', 'polanger-admin-menu-manager' ); ?></strong></label>
        <?php
        wp_editor(
          $rule['message'],
          'pdt_content_visibility_message_editor',
          array(
            'textarea_name' => 'pdt_content_visibility_message',
            'textarea_rows' => 5,
            'media_buttons' => false,
            'teeny'         => true,
            'quicktags'     => true,
            'tinymce'       => array(
              'toolbar1' => 'bold,italic,bullist,numlist,link,unlink,undo,redo',
              'wpautop'  => true,
            ),
          )
        );
        ?>
        <span class="description"><?php esc_html_e( 'Optional per-content override. HTML and shortcodes are supported. Leave empty to use the default message from settings.', 'polanger-admin-menu-manager' ); ?></span>
      </div>

      <p class="pdt-content-visibility-field pdt-content-visibility-redirect-field" <?php echo ( 'custom_redirect' === $rule['denied'] ) ? '' : 'style="display:none;"'; ?>>
        <label for="pdt_content_visibility_redirect_url"><strong><?php esc_html_e( 'Custom redirect URL', 'polanger-admin-menu-manager' ); ?></strong></label>
        <input
          type="url"
          id="pdt_content_visibility_redirect_url"
          name="pdt_content_visibility_redirect_url"
          class="widefat"
          value="<?php echo esc_attr( $rule['redirect_url'] ); ?>"
          placeholder="<?php echo esc_attr( home_url( '/members-only/' ) ); ?>"
        />
      </p>

      <p class="pdt-content-visibility-field pdt-content-visibility-compatibility-field">
        <label for="pdt_content_visibility_compatibility"><strong><?php esc_html_e( 'Compatibility mode', 'polanger-admin-menu-manager' ); ?></strong></label>
        <select id="pdt_content_visibility_compatibility" name="pdt_content_visibility_compatibility" class="widefat">
          <?php foreach ( $compatibility_options as $value => $label ) : ?>
            <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $rule['compatibility'], $value ); ?>>
              <?php echo esc_html( $label ); ?>
            </option>
          <?php endforeach; ?>
        </select>
        <span class="description"><?php esc_html_e( 'Theme-friendly replacement keeps the current theme layout. Full access denied page is safer for builders or templates that bypass the standard content flow.', 'polanger-admin-menu-manager' ); ?></span>
      </p>
    </div>
    <?php
  }

  /**
   * Persist classic editor values.
   *
   * @param int $post_id Post ID.
   * @return void
   */
  public function save_meta_box( $post_id ) {
    if ( ! isset( $_POST['pdt_content_visibility_nonce'] ) ) {
      return;
    }

    if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pdt_content_visibility_nonce'] ) ), 'pdt_content_visibility_save' ) ) {
      return;
    }

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
      return;
    }

    if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
      return;
    }

    if ( ! current_user_can( 'edit_post', $post_id ) || ! PDT_Content_Visibility::is_supported_post( $post_id ) ) {
      return;
    }

    $roles = array();

    if ( isset( $_POST['pdt_content_visibility_roles'] ) && is_array( $_POST['pdt_content_visibility_roles'] ) ) {
      $roles = wp_unslash( $_POST['pdt_content_visibility_roles'] );
    }

    PDT_Content_Visibility::save_post_rule(
      $post_id,
      array(
        'mode'          => isset( $_POST['pdt_content_visibility_mode'] ) ? wp_unslash( $_POST['pdt_content_visibility_mode'] ) : 'public',
        'roles'         => $roles,
        'denied'        => isset( $_POST['pdt_content_visibility_denied_behavior'] ) ? wp_unslash( $_POST['pdt_content_visibility_denied_behavior'] ) : 'inherit',
        'compatibility' => isset( $_POST['pdt_content_visibility_compatibility'] ) ? wp_unslash( $_POST['pdt_content_visibility_compatibility'] ) : 'inherit',
        'redirect_url'  => isset( $_POST['pdt_content_visibility_redirect_url'] ) ? wp_unslash( $_POST['pdt_content_visibility_redirect_url'] ) : '',
        'message'       => isset( $_POST['pdt_content_visibility_message'] ) ? wp_unslash( $_POST['pdt_content_visibility_message'] ) : '',
      )
    );
  }

  /**
   * Enqueue the block editor sidebar panel.
   *
   * @return void
   */
  public function enqueue_block_editor_assets() {
    $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;

    if ( ! $screen || ! in_array( $screen->post_type, PDT_Content_Visibility::get_supported_post_types(), true ) ) {
      return;
    }

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin screen context detection.
    $current_post_id = isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : 0;
    $current_mode    = $current_post_id ? get_post_meta( $current_post_id, PDT_Content_Visibility::META_MODE, true ) : 'public';

    wp_enqueue_script(
      'pdt-content-visibility-editor',
      plugins_url( 'assets/js/content-visibility-editor.js', PDT_PLUGIN_FILE ),
      array( 'editor', 'quicktags', 'wp-components', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-plugins' ),
      PDT_VERSION,
      true
    );

    wp_localize_script(
      'pdt-content-visibility-editor',
      'pdtContentVisibilityEditor',
      array(
        'metaKeys' => array(
          'mode'          => PDT_Content_Visibility::META_MODE,
          'roles'         => PDT_Content_Visibility::META_ROLES,
          'denied'        => PDT_Content_Visibility::META_BEHAVIOR,
          'compatibility' => PDT_Content_Visibility::META_COMPATIBILITY,
          'redirectUrl'   => PDT_Content_Visibility::META_REDIRECT_URL,
          'message'       => PDT_Content_Visibility::META_MESSAGE,
        ),
        'labels' => array(
          'panelTitle'            => __( 'Content Visibility', 'polanger-admin-menu-manager' ),
          'panelDescription'      => __( 'Protect this content on the public site by keeping it public, limiting it to signed-in users, or hiding it from specific roles.', 'polanger-admin-menu-manager' ),
          'visibility'            => __( 'Access rule', 'polanger-admin-menu-manager' ),
          'roles'                 => __( 'Roles', 'polanger-admin-menu-manager' ),
          'deniedBehavior'        => __( 'When access is denied', 'polanger-admin-menu-manager' ),
          'customMessage'         => __( 'Custom access denied message', 'polanger-admin-menu-manager' ),
          'customMessageHelp'     => __( 'Optional per-content override. HTML and shortcodes are supported. Leave empty to use the default message from settings.', 'polanger-admin-menu-manager' ),
          'defaultSettings'       => __( 'Default Settings', 'polanger-admin-menu-manager' ),
          'defaultSettingsHelp'   => __( 'Open the global Frontend Content Visibility defaults in a new tab.', 'polanger-admin-menu-manager' ),
          'customRedirectUrl'     => __( 'Custom redirect URL', 'polanger-admin-menu-manager' ),
          'compatibility'         => __( 'Compatibility mode', 'polanger-admin-menu-manager' ),
          'compatibilityHelp'     => __( 'Theme-friendly replacement keeps the active layout. Full access denied page is safer when a builder or template bypasses the standard content flow.', 'polanger-admin-menu-manager' ),
          'rolesHelp'             => __( 'Selected roles will be blocked from viewing this content on the frontend.', 'polanger-admin-menu-manager' ),
          'accessRuleHelp'        => __( 'Use "Hide from selected roles" when you want to block this content for specific user roles only.', 'polanger-admin-menu-manager' ),
          'legacyShowRolesHelp'   => __( 'This content is using a legacy allowlist rule from an older version. Only the selected roles can view it until you replace this rule.', 'polanger-admin-menu-manager' ),
        ),
        'visibilityModes'       => PDT_Content_Visibility::get_editor_visibility_mode_options( $current_mode ),
        'deniedBehaviors'       => PDT_Content_Visibility::get_denied_behavior_options( true ),
        'compatibilityModes'    => PDT_Content_Visibility::get_compatibility_mode_options( true ),
        'roles'                 => PDT_Content_Visibility::get_role_choices(),
        'defaultMessage'        => PDT_Content_Visibility::get_default_denied_message(),
        'defaultSettingsUrl'    => PDT_Content_Visibility::get_default_settings_url(),
        'redirectPlaceholder'   => home_url( '/members-only/' ),
      )
    );
  }
}
