<?php
/**
 * User Role Editor Module
 *
 * Manage user roles and capabilities.
 *
 * @package BlaminhorEssentials
 */

// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * User Role Editor module class
 */
class Blaminhor_Essentials_Module_User_Role_Editor extends Blaminhor_Essentials_Module {

	/**
	 * Module ID
	 *
	 * @var string
	 */
	protected $id = 'user-role-editor';

	/**
	 * Module name
	 *
	 * @var string
	 */
	protected $name = 'User Role Editor';

	/**
	 * Capability groups cache
	 *
	 * @var array|null
	 */
	private $capability_groups = null;

	/**
	 * Initialize module
	 */
	protected function init() {
		$this->name        = __( 'User Role Editor', 'blaminhor-essentials' );
		$this->description = __( 'Manage user roles and capabilities.', 'blaminhor-essentials' );
	}

	/**
	 * Get default settings
	 *
	 * @return array
	 */
	protected function get_default_settings() {
		return array(
			'show_deprecated_caps'    => false,
			'allow_admin_role_edit'   => false,
			'custom_capabilities'     => array(),
			'label_display_mode'      => 'both',
		);
	}

	/**
	 * Get human-readable labels for capabilities
	 *
	 * @return array
	 */
	private function get_capability_labels() {
		return array(
			// Core.
			'read'                   => __( 'Read content', 'blaminhor-essentials' ),
			'level_10'               => __( 'Access level 10 (Admin)', 'blaminhor-essentials' ),
			'level_9'                => __( 'Access level 9', 'blaminhor-essentials' ),
			'level_8'                => __( 'Access level 8', 'blaminhor-essentials' ),
			'level_7'                => __( 'Access level 7 (Editor)', 'blaminhor-essentials' ),
			'level_6'                => __( 'Access level 6', 'blaminhor-essentials' ),
			'level_5'                => __( 'Access level 5', 'blaminhor-essentials' ),
			'level_4'                => __( 'Access level 4', 'blaminhor-essentials' ),
			'level_3'                => __( 'Access level 3', 'blaminhor-essentials' ),
			'level_2'                => __( 'Access level 2 (Author)', 'blaminhor-essentials' ),
			'level_1'                => __( 'Access level 1 (Contributor)', 'blaminhor-essentials' ),
			'level_0'                => __( 'Access level 0 (Subscriber)', 'blaminhor-essentials' ),

			// Posts.
			'edit_posts'             => __( 'Edit own posts', 'blaminhor-essentials' ),
			'edit_others_posts'      => __( 'Edit others\' posts', 'blaminhor-essentials' ),
			'edit_published_posts'   => __( 'Edit published posts', 'blaminhor-essentials' ),
			'edit_private_posts'     => __( 'Edit private posts', 'blaminhor-essentials' ),
			'publish_posts'          => __( 'Publish posts', 'blaminhor-essentials' ),
			'read_private_posts'     => __( 'Read private posts', 'blaminhor-essentials' ),
			'delete_posts'           => __( 'Delete own posts', 'blaminhor-essentials' ),
			'delete_others_posts'    => __( 'Delete others\' posts', 'blaminhor-essentials' ),
			'delete_published_posts' => __( 'Delete published posts', 'blaminhor-essentials' ),
			'delete_private_posts'   => __( 'Delete private posts', 'blaminhor-essentials' ),

			// Pages.
			'edit_pages'             => __( 'Edit own pages', 'blaminhor-essentials' ),
			'edit_others_pages'      => __( 'Edit others\' pages', 'blaminhor-essentials' ),
			'edit_published_pages'   => __( 'Edit published pages', 'blaminhor-essentials' ),
			'edit_private_pages'     => __( 'Edit private pages', 'blaminhor-essentials' ),
			'publish_pages'          => __( 'Publish pages', 'blaminhor-essentials' ),
			'read_private_pages'     => __( 'Read private pages', 'blaminhor-essentials' ),
			'delete_pages'           => __( 'Delete own pages', 'blaminhor-essentials' ),
			'delete_others_pages'    => __( 'Delete others\' pages', 'blaminhor-essentials' ),
			'delete_published_pages' => __( 'Delete published pages', 'blaminhor-essentials' ),
			'delete_private_pages'   => __( 'Delete private pages', 'blaminhor-essentials' ),

			// Media.
			'upload_files'           => __( 'Upload files', 'blaminhor-essentials' ),
			'unfiltered_upload'      => __( 'Upload any file type', 'blaminhor-essentials' ),

			// Users.
			'list_users'             => __( 'View user list', 'blaminhor-essentials' ),
			'create_users'           => __( 'Create new users', 'blaminhor-essentials' ),
			'edit_users'             => __( 'Edit user profiles', 'blaminhor-essentials' ),
			'delete_users'           => __( 'Delete users', 'blaminhor-essentials' ),
			'promote_users'          => __( 'Change user roles', 'blaminhor-essentials' ),
			'remove_users'           => __( 'Remove users from site', 'blaminhor-essentials' ),

			// Appearance.
			'switch_themes'          => __( 'Switch themes', 'blaminhor-essentials' ),
			'edit_themes'            => __( 'Edit theme files', 'blaminhor-essentials' ),
			'install_themes'         => __( 'Install new themes', 'blaminhor-essentials' ),
			'update_themes'          => __( 'Update themes', 'blaminhor-essentials' ),
			'delete_themes'          => __( 'Delete themes', 'blaminhor-essentials' ),
			'edit_theme_options'     => __( 'Customize theme & menus', 'blaminhor-essentials' ),
			'customize'              => __( 'Access Customizer', 'blaminhor-essentials' ),

			// Plugins.
			'activate_plugins'       => __( 'Activate/deactivate plugins', 'blaminhor-essentials' ),
			'edit_plugins'           => __( 'Edit plugin files', 'blaminhor-essentials' ),
			'install_plugins'        => __( 'Install new plugins', 'blaminhor-essentials' ),
			'update_plugins'         => __( 'Update plugins', 'blaminhor-essentials' ),
			'delete_plugins'         => __( 'Delete plugins', 'blaminhor-essentials' ),

			// Settings & Administration.
			'manage_options'         => __( 'Manage site settings', 'blaminhor-essentials' ),
			'manage_links'           => __( 'Manage blogroll links', 'blaminhor-essentials' ),
			'manage_categories'      => __( 'Manage categories', 'blaminhor-essentials' ),
			'moderate_comments'      => __( 'Moderate comments', 'blaminhor-essentials' ),
			'edit_comment'           => __( 'Edit comments', 'blaminhor-essentials' ),
			'unfiltered_html'        => __( 'Post unfiltered HTML', 'blaminhor-essentials' ),
			'import'                 => __( 'Import content', 'blaminhor-essentials' ),
			'export'                 => __( 'Export content', 'blaminhor-essentials' ),
			'update_core'            => __( 'Update WordPress core', 'blaminhor-essentials' ),
		);
	}

	/**
	 * Register hooks
	 */
	protected function register_hooks() {
		add_action( 'admin_init', array( $this, 'handle_settings_submission' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );

		// AJAX handlers - Roles.
		add_action( 'wp_ajax_ap_ure_get_roles', array( $this, 'ajax_get_roles' ) );
		add_action( 'wp_ajax_ap_ure_get_role', array( $this, 'ajax_get_role' ) );
		add_action( 'wp_ajax_ap_ure_create_role', array( $this, 'ajax_create_role' ) );
		add_action( 'wp_ajax_ap_ure_clone_role', array( $this, 'ajax_clone_role' ) );
		add_action( 'wp_ajax_ap_ure_delete_role', array( $this, 'ajax_delete_role' ) );
		add_action( 'wp_ajax_ap_ure_rename_role', array( $this, 'ajax_rename_role' ) );
		add_action( 'wp_ajax_ap_ure_update_caps', array( $this, 'ajax_update_caps' ) );

		// AJAX handlers - Users.
		add_action( 'wp_ajax_ap_ure_get_users', array( $this, 'ajax_get_users' ) );
		add_action( 'wp_ajax_ap_ure_get_user_caps', array( $this, 'ajax_get_user_caps' ) );
		add_action( 'wp_ajax_ap_ure_update_user_caps', array( $this, 'ajax_update_user_caps' ) );

		// AJAX handlers - Import/Export.
		add_action( 'wp_ajax_ap_ure_export', array( $this, 'ajax_export' ) );
		add_action( 'wp_ajax_ap_ure_import', array( $this, 'ajax_import' ) );
		add_action( 'wp_ajax_ap_ure_reset', array( $this, 'ajax_reset' ) );

		// AJAX handlers - Custom capabilities.
		add_action( 'wp_ajax_ap_ure_add_custom_cap', array( $this, 'ajax_add_custom_cap' ) );
		add_action( 'wp_ajax_ap_ure_remove_custom_cap', array( $this, 'ajax_remove_custom_cap' ) );
	}

	/**
	 * Enqueue module assets
	 *
	 * @param string $hook Admin page hook.
	 */
	public function enqueue_assets( $hook ) {
		if ( strpos( $hook, 'blaminhor-essentials-user-role-editor' ) === false ) {
			return;
		}

		$config = array(
			'nonce'            => wp_create_nonce( 'blaminhor_essentials_admin' ),
			'ajaxurl'          => admin_url( 'admin-ajax.php' ),
			'labelDisplayMode' => $this->get_setting( 'label_display_mode', 'both' ),
			'capLabels'        => $this->get_capability_labels(),
			'strings'          => array(
				'loading'            => __( 'Loading...', 'blaminhor-essentials' ),
				'saving'             => __( 'Saving...', 'blaminhor-essentials' ),
				'saved'              => __( 'Saved', 'blaminhor-essentials' ),
				'error'              => __( 'An error occurred.', 'blaminhor-essentials' ),
				'confirmDelete'      => __( 'Are you sure you want to delete this role? This action cannot be undone.', 'blaminhor-essentials' ),
				'confirmReset'       => __( 'Are you sure you want to reset all roles to WordPress defaults? This will remove all custom roles and restore default capabilities.', 'blaminhor-essentials' ),
				'roleCreated'        => __( 'Role created successfully.', 'blaminhor-essentials' ),
				'roleCloned'         => __( 'Role cloned successfully.', 'blaminhor-essentials' ),
				'roleDeleted'        => __( 'Role deleted successfully.', 'blaminhor-essentials' ),
				'roleRenamed'        => __( 'Role renamed successfully.', 'blaminhor-essentials' ),
				'capsUpdated'        => __( 'Capabilities updated successfully.', 'blaminhor-essentials' ),
				'userCapsUpdated'    => __( 'User capabilities updated successfully.', 'blaminhor-essentials' ),
				'importSuccess'      => __( 'Import completed successfully.', 'blaminhor-essentials' ),
				'resetSuccess'       => __( 'Roles reset to WordPress defaults.', 'blaminhor-essentials' ),
				'noRoleSelected'     => __( 'Please select a role.', 'blaminhor-essentials' ),
				'enterRoleName'      => __( 'Please enter a role name.', 'blaminhor-essentials' ),
				'enterRoleSlug'      => __( 'Please enter a role slug.', 'blaminhor-essentials' ),
				'selectFile'         => __( 'Please select a file to import.', 'blaminhor-essentials' ),
				'invalidJson'        => __( 'Invalid JSON file.', 'blaminhor-essentials' ),
				'protectedRole'      => __( 'This role is protected and cannot be deleted.', 'blaminhor-essentials' ),
				'addCustomCap'       => __( 'Add Custom Capability', 'blaminhor-essentials' ),
				'enterCapName'       => __( 'Please enter a capability name.', 'blaminhor-essentials' ),
				'capAdded'           => __( 'Capability added successfully.', 'blaminhor-essentials' ),
				'capRemoved'         => __( 'Capability removed successfully.', 'blaminhor-essentials' ),
				'usersWithRole'      => __( 'users with this role', 'blaminhor-essentials' ),
				'noUsers'            => __( 'No users found.', 'blaminhor-essentials' ),
				'searchUsers'        => __( 'Search users...', 'blaminhor-essentials' ),
				'edit'               => __( 'Edit', 'blaminhor-essentials' ),
				'close'              => __( 'Close', 'blaminhor-essentials' ),
				'cancel'             => __( 'Cancel', 'blaminhor-essentials' ),
				'save'               => __( 'Save', 'blaminhor-essentials' ),
				'delete'             => __( 'Delete', 'blaminhor-essentials' ),
				'clone'              => __( 'Clone', 'blaminhor-essentials' ),
				'cloneRole'          => __( 'Clone Role', 'blaminhor-essentials' ),
				'rename'             => __( 'Rename', 'blaminhor-essentials' ),
				'create'             => __( 'Create', 'blaminhor-essentials' ),
				'createRole'         => __( 'Create Role', 'blaminhor-essentials' ),
				'selectAll'          => __( 'Select All', 'blaminhor-essentials' ),
				'deselectAll'        => __( 'Deselect All', 'blaminhor-essentials' ),
			),
		);

		wp_add_inline_script(
			'blaminhor-essentials-modules',
			'jQuery(document).ready(function($) { if(window.BlaminhorEssentialsUserRoleEditor) BlaminhorEssentialsUserRoleEditor.init(' . wp_json_encode( $config ) . '); });'
		);
	}

	/**
	 * Get all roles with their capabilities
	 *
	 * @return array
	 */
	private function get_all_roles() {
		global $wp_roles;

		if ( ! isset( $wp_roles ) ) {
			$wp_roles = new WP_Roles();
		}

		$roles = array();
		foreach ( $wp_roles->roles as $slug => $role ) {
			$user_count = count( get_users( array( 'role' => $slug, 'fields' => 'ID' ) ) );
			$roles[ $slug ] = array(
				'name'         => translate_user_role( $role['name'] ),
				'capabilities' => $role['capabilities'],
				'user_count'   => $user_count,
				'is_protected' => $this->is_protected_role( $slug ),
			);
		}

		return $roles;
	}

	/**
	 * Get capability groups
	 *
	 * @return array
	 */
	private function get_capability_groups() {
		if ( null !== $this->capability_groups ) {
			return $this->capability_groups;
		}

		// Build core capabilities - include level_* only if show_deprecated_caps is enabled.
		$core_caps = array( 'read' );
		if ( $this->get_setting( 'show_deprecated_caps', false ) ) {
			$core_caps = array_merge( $core_caps, array( 'level_10', 'level_9', 'level_8', 'level_7', 'level_6', 'level_5', 'level_4', 'level_3', 'level_2', 'level_1', 'level_0' ) );
		}

		$this->capability_groups = array(
			'core' => array(
				'label' => __( 'Core', 'blaminhor-essentials' ),
				'caps'  => $core_caps,
			),
			'posts' => array(
				'label' => __( 'Posts', 'blaminhor-essentials' ),
				'caps'  => array(
					'edit_posts', 'edit_others_posts', 'edit_published_posts', 'edit_private_posts',
					'publish_posts', 'read_private_posts',
					'delete_posts', 'delete_others_posts', 'delete_published_posts', 'delete_private_posts',
				),
			),
			'pages' => array(
				'label' => __( 'Pages', 'blaminhor-essentials' ),
				'caps'  => array(
					'edit_pages', 'edit_others_pages', 'edit_published_pages', 'edit_private_pages',
					'publish_pages', 'read_private_pages',
					'delete_pages', 'delete_others_pages', 'delete_published_pages', 'delete_private_pages',
				),
			),
			'media' => array(
				'label' => __( 'Media', 'blaminhor-essentials' ),
				'caps'  => array( 'upload_files', 'unfiltered_upload' ),
			),
			'users' => array(
				'label' => __( 'Users', 'blaminhor-essentials' ),
				'caps'  => array(
					'list_users', 'create_users', 'edit_users', 'delete_users',
					'promote_users', 'remove_users',
				),
			),
			'appearance' => array(
				'label' => __( 'Appearance', 'blaminhor-essentials' ),
				'caps'  => array(
					'switch_themes', 'edit_themes', 'install_themes', 'update_themes', 'delete_themes',
					'edit_theme_options', 'customize',
				),
			),
			'plugins' => array(
				'label' => __( 'Plugins', 'blaminhor-essentials' ),
				'caps'  => array(
					'activate_plugins', 'edit_plugins', 'install_plugins', 'update_plugins', 'delete_plugins',
				),
			),
			'settings' => array(
				'label' => __( 'Settings & Administration', 'blaminhor-essentials' ),
				'caps'  => array(
					'manage_options', 'manage_links', 'manage_categories',
					'moderate_comments', 'edit_comment',
					'unfiltered_html', 'import', 'export',
					'update_core',
				),
			),
			'custom' => array(
				'label' => __( 'Custom Capabilities', 'blaminhor-essentials' ),
				'caps'  => $this->get_setting( 'custom_capabilities', array() ),
			),
		);

		return $this->capability_groups;
	}

	/**
	 * Get all known capabilities
	 *
	 * @return array
	 */
	private function get_all_capabilities() {
		$groups = $this->get_capability_groups();
		$caps   = array();

		foreach ( $groups as $group ) {
			$caps = array_merge( $caps, $group['caps'] );
		}

		// Also get capabilities from existing roles.
		global $wp_roles;
		if ( isset( $wp_roles ) ) {
			foreach ( $wp_roles->roles as $role ) {
				$caps = array_merge( $caps, array_keys( $role['capabilities'] ) );
			}
		}

		return array_unique( $caps );
	}

	/**
	 * Check if role is protected
	 *
	 * @param string $slug Role slug.
	 * @return bool
	 */
	private function is_protected_role( $slug ) {
		$protected = array( 'administrator' );

		// Don't allow editing administrator unless explicitly allowed.
		if ( ! $this->get_setting( 'allow_admin_role_edit', false ) && 'administrator' === $slug ) {
			return true;
		}

		return in_array( $slug, $protected, true );
	}

	/**
	 * Create a new role
	 *
	 * @param string $slug Role slug.
	 * @param string $name Role display name.
	 * @param array  $caps Capabilities.
	 * @return WP_Role|null
	 */
	private function create_role( $slug, $name, $caps = array() ) {
		$slug = sanitize_key( $slug );
		$name = sanitize_text_field( $name );

		if ( empty( $slug ) || empty( $name ) ) {
			return null;
		}

		// Check if role already exists.
		if ( get_role( $slug ) ) {
			return null;
		}

		$capabilities = array();
		foreach ( $caps as $cap ) {
			$capabilities[ sanitize_key( $cap ) ] = true;
		}

		return add_role( $slug, $name, $capabilities );
	}

	/**
	 * Clone an existing role
	 *
	 * @param string $source_slug Source role slug.
	 * @param string $new_slug    New role slug.
	 * @param string $new_name    New role name.
	 * @return WP_Role|null
	 */
	private function clone_role( $source_slug, $new_slug, $new_name ) {
		$source_role = get_role( $source_slug );
		if ( ! $source_role ) {
			return null;
		}

		return $this->create_role( $new_slug, $new_name, array_keys( $source_role->capabilities ) );
	}

	/**
	 * Delete a role
	 *
	 * @param string $slug Role slug.
	 * @return bool
	 */
	private function delete_role( $slug ) {
		if ( $this->is_protected_role( $slug ) ) {
			return false;
		}

		$role = get_role( $slug );
		if ( ! $role ) {
			return false;
		}

		remove_role( $slug );
		return true;
	}

	/**
	 * Rename a role
	 *
	 * @param string $slug     Role slug.
	 * @param string $new_name New display name.
	 * @return bool
	 */
	private function rename_role( $slug, $new_name ) {
		global $wp_roles;

		if ( ! isset( $wp_roles->roles[ $slug ] ) ) {
			return false;
		}

		$wp_roles->roles[ $slug ]['name'] = sanitize_text_field( $new_name );
		update_option( $wp_roles->role_key, $wp_roles->roles );

		return true;
	}

	/**
	 * Update role capabilities
	 *
	 * @param string $slug Role slug.
	 * @param array  $caps Capabilities array (cap => bool).
	 * @return bool
	 */
	private function update_role_capabilities( $slug, $caps ) {
		$role = get_role( $slug );
		if ( ! $role ) {
			return false;
		}

		// Check protection.
		if ( 'administrator' === $slug && ! $this->get_setting( 'allow_admin_role_edit', false ) ) {
			return false;
		}

		// Get all known capabilities.
		$all_caps = $this->get_all_capabilities();

		foreach ( $all_caps as $cap ) {
			if ( isset( $caps[ $cap ] ) && $caps[ $cap ] ) {
				$role->add_cap( $cap );
			} else {
				$role->remove_cap( $cap );
			}
		}

		return true;
	}

	/**
	 * Get user-specific capabilities
	 *
	 * @param int $user_id User ID.
	 * @return array
	 */
	private function get_user_capabilities( $user_id ) {
		$user = get_userdata( $user_id );
		if ( ! $user ) {
			return array();
		}

		// Get capabilities directly assigned to the user (not from roles).
		$user_caps = array();
		$all_caps  = $user->allcaps;
		$role_caps = array();

		// Get all capabilities from user's roles.
		foreach ( $user->roles as $role_slug ) {
			$role = get_role( $role_slug );
			if ( $role ) {
				$role_caps = array_merge( $role_caps, array_keys( $role->capabilities ) );
			}
		}

		// Find capabilities that are directly assigned to user.
		foreach ( $all_caps as $cap => $granted ) {
			if ( ! in_array( $cap, $role_caps, true ) && ! in_array( $cap, $user->roles, true ) ) {
				$user_caps[ $cap ] = $granted;
			}
		}

		return $user_caps;
	}

	/**
	 * Add capability to user
	 *
	 * @param int    $user_id User ID.
	 * @param string $cap     Capability.
	 * @return bool
	 */
	private function add_user_capability( $user_id, $cap ) {
		$user = get_userdata( $user_id );
		if ( ! $user ) {
			return false;
		}

		$user->add_cap( sanitize_key( $cap ) );
		return true;
	}

	/**
	 * Remove capability from user
	 *
	 * @param int    $user_id User ID.
	 * @param string $cap     Capability.
	 * @return bool
	 */
	private function remove_user_capability( $user_id, $cap ) {
		$user = get_userdata( $user_id );
		if ( ! $user ) {
			return false;
		}

		$user->remove_cap( sanitize_key( $cap ) );
		return true;
	}

	/**
	 * Export roles to JSON
	 *
	 * @return array
	 */
	private function export_roles_json() {
		global $wp_roles;

		return array(
			'version'     => BLAMINHOR_ESSENTIALS_VERSION,
			'export_date' => gmdate( 'Y-m-d H:i:s' ),
			'site_url'    => home_url(),
			'roles'       => $wp_roles->roles,
		);
	}

	/**
	 * Import roles from JSON
	 *
	 * @param array  $data Import data.
	 * @param string $mode Import mode (merge or replace).
	 * @return array Result with counts.
	 */
	private function import_roles_json( $data, $mode = 'merge' ) {
		global $wp_roles;

		if ( ! isset( $data['roles'] ) || ! is_array( $data['roles'] ) ) {
			return array( 'success' => false, 'message' => __( 'Invalid import data.', 'blaminhor-essentials' ) );
		}

		$imported = 0;
		$updated  = 0;
		$skipped  = 0;

		if ( 'replace' === $mode ) {
			// Remove all non-protected roles first.
			foreach ( array_keys( $wp_roles->roles ) as $slug ) {
				if ( ! $this->is_protected_role( $slug ) ) {
					remove_role( $slug );
				}
			}
		}

		foreach ( $data['roles'] as $slug => $role_data ) {
			$slug = sanitize_key( $slug );

			// Skip administrator in replace mode.
			if ( 'administrator' === $slug && ! $this->get_setting( 'allow_admin_role_edit', false ) ) {
				++$skipped;
				continue;
			}

			$existing = get_role( $slug );
			$caps     = isset( $role_data['capabilities'] ) ? $role_data['capabilities'] : array();
			$name     = isset( $role_data['name'] ) ? sanitize_text_field( $role_data['name'] ) : $slug;

			if ( $existing ) {
				// Update existing role.
				foreach ( $caps as $cap => $granted ) {
					if ( $granted ) {
						$existing->add_cap( $cap );
					} else {
						$existing->remove_cap( $cap );
					}
				}
				$this->rename_role( $slug, $name );
				++$updated;
			} else {
				// Create new role.
				$granted_caps = array();
				foreach ( $caps as $cap => $granted ) {
					if ( $granted ) {
						$granted_caps[] = $cap;
					}
				}
				$this->create_role( $slug, $name, $granted_caps );
				++$imported;
			}
		}

		return array(
			'success'  => true,
			'imported' => $imported,
			'updated'  => $updated,
			'skipped'  => $skipped,
		);
	}

	/**
	 * Get WordPress default roles
	 *
	 * @return array
	 */
	private function get_wordpress_default_roles() {
		return array(
			'administrator' => array(
				'name' => 'Administrator',
				'capabilities' => array(
					'switch_themes' => true, 'edit_themes' => true, 'activate_plugins' => true,
					'edit_plugins' => true, 'edit_users' => true, 'edit_files' => true,
					'manage_options' => true, 'moderate_comments' => true, 'manage_categories' => true,
					'manage_links' => true, 'upload_files' => true, 'import' => true,
					'unfiltered_html' => true, 'edit_posts' => true, 'edit_others_posts' => true,
					'edit_published_posts' => true, 'publish_posts' => true, 'edit_pages' => true,
					'read' => true, 'level_10' => true, 'level_9' => true, 'level_8' => true,
					'level_7' => true, 'level_6' => true, 'level_5' => true, 'level_4' => true,
					'level_3' => true, 'level_2' => true, 'level_1' => true, 'level_0' => true,
					'edit_others_pages' => true, 'edit_published_pages' => true, 'publish_pages' => true,
					'delete_pages' => true, 'delete_others_pages' => true, 'delete_published_pages' => true,
					'delete_posts' => true, 'delete_others_posts' => true, 'delete_published_posts' => true,
					'delete_private_posts' => true, 'edit_private_posts' => true, 'read_private_posts' => true,
					'delete_private_pages' => true, 'edit_private_pages' => true, 'read_private_pages' => true,
					'delete_users' => true, 'create_users' => true, 'unfiltered_upload' => true,
					'edit_dashboard' => true, 'update_plugins' => true, 'delete_plugins' => true,
					'install_plugins' => true, 'update_themes' => true, 'install_themes' => true,
					'update_core' => true, 'list_users' => true, 'remove_users' => true,
					'promote_users' => true, 'edit_theme_options' => true, 'delete_themes' => true,
					'export' => true,
				),
			),
			'editor' => array(
				'name' => 'Editor',
				'capabilities' => array(
					'moderate_comments' => true, 'manage_categories' => true, 'manage_links' => true,
					'upload_files' => true, 'unfiltered_html' => true, 'edit_posts' => true,
					'edit_others_posts' => true, 'edit_published_posts' => true, 'publish_posts' => true,
					'edit_pages' => true, 'read' => true, 'level_7' => true, 'level_6' => true,
					'level_5' => true, 'level_4' => true, 'level_3' => true, 'level_2' => true,
					'level_1' => true, 'level_0' => true, 'edit_others_pages' => true,
					'edit_published_pages' => true, 'publish_pages' => true, 'delete_pages' => true,
					'delete_others_pages' => true, 'delete_published_pages' => true, 'delete_posts' => true,
					'delete_others_posts' => true, 'delete_published_posts' => true, 'delete_private_posts' => true,
					'edit_private_posts' => true, 'read_private_posts' => true, 'delete_private_pages' => true,
					'edit_private_pages' => true, 'read_private_pages' => true,
				),
			),
			'author' => array(
				'name' => 'Author',
				'capabilities' => array(
					'upload_files' => true, 'edit_posts' => true, 'edit_published_posts' => true,
					'publish_posts' => true, 'read' => true, 'level_2' => true, 'level_1' => true,
					'level_0' => true, 'delete_posts' => true, 'delete_published_posts' => true,
				),
			),
			'contributor' => array(
				'name' => 'Contributor',
				'capabilities' => array(
					'edit_posts' => true, 'read' => true, 'level_1' => true, 'level_0' => true,
					'delete_posts' => true,
				),
			),
			'subscriber' => array(
				'name' => 'Subscriber',
				'capabilities' => array(
					'read' => true, 'level_0' => true,
				),
			),
		);
	}

	/**
	 * Reset roles to WordPress defaults
	 *
	 * @return bool
	 */
	private function reset_to_defaults() {
		global $wp_roles;

		// Remove all roles except administrator.
		foreach ( array_keys( $wp_roles->roles ) as $slug ) {
			if ( 'administrator' !== $slug ) {
				remove_role( $slug );
			}
		}

		// Restore default roles.
		$defaults = $this->get_wordpress_default_roles();
		foreach ( $defaults as $slug => $role_data ) {
			if ( 'administrator' === $slug ) {
				// Just update administrator capabilities.
				$admin_role = get_role( 'administrator' );
				if ( $admin_role && $this->get_setting( 'allow_admin_role_edit', false ) ) {
					foreach ( $role_data['capabilities'] as $cap => $granted ) {
						if ( $granted ) {
							$admin_role->add_cap( $cap );
						}
					}
				}
			} else {
				add_role( $slug, $role_data['name'], $role_data['capabilities'] );
			}
		}

		return true;
	}

	/**
	 * Process settings form
	 *
	 * @param array $data Form data.
	 */
	protected function process_settings( $data ) {
		$valid_modes = array( 'technical', 'friendly', 'both' );
		$label_mode  = isset( $data['label_display_mode'] ) && in_array( $data['label_display_mode'], $valid_modes, true )
			? $data['label_display_mode']
			: 'both';

		$settings = array(
			'show_deprecated_caps'  => isset( $data['show_deprecated_caps'] ),
			'allow_admin_role_edit' => isset( $data['allow_admin_role_edit'] ),
			'custom_capabilities'   => $this->get_setting( 'custom_capabilities', array() ),
			'label_display_mode'    => $label_mode,
		);

		$this->save_settings( $settings );

		// Reset capability groups cache to apply new settings.
		$this->capability_groups = null;

		add_action( 'admin_notices', function () {
			blaminhor_essentials_admin_notice( __( 'Settings saved.', 'blaminhor-essentials' ), 'success' );
		} );
	}

	// =========================================================================
	// AJAX Handlers - Roles
	// =========================================================================

	/**
	 * AJAX: Get all roles
	 */
	public function ajax_get_roles() {
		$this->verify_ajax_request();

		wp_send_json_success( array(
			'roles'  => $this->get_all_roles(),
			'groups' => $this->get_capability_groups(),
		) );
	}

	/**
	 * AJAX: Get single role details
	 */
	public function ajax_get_role() {
		$this->verify_ajax_request();

		$slug = $this->get_post_value( 'role', '', 'key' );
		$role = get_role( $slug );

		if ( ! $role ) {
			wp_send_json_error( __( 'Role not found.', 'blaminhor-essentials' ) );
		}

		global $wp_roles;
		$role_data = $wp_roles->roles[ $slug ];

		wp_send_json_success( array(
			'slug'         => $slug,
			'name'         => translate_user_role( $role_data['name'] ),
			'capabilities' => $role->capabilities,
			'user_count'   => count( get_users( array( 'role' => $slug, 'fields' => 'ID' ) ) ),
			'is_protected' => $this->is_protected_role( $slug ),
		) );
	}

	/**
	 * AJAX: Create role
	 */
	public function ajax_create_role() {
		$this->verify_ajax_request();

		$slug = $this->get_post_value( 'slug', '', 'key' );
		$name = $this->get_post_value( 'name', '', 'text' );
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in verify_ajax_request()
		$caps = isset( $_POST['caps'] ) && is_array( $_POST['caps'] ) ? array_map( 'sanitize_key', wp_unslash( $_POST['caps'] ) ) : array();

		if ( empty( $slug ) || empty( $name ) ) {
			wp_send_json_error( __( 'Role slug and name are required.', 'blaminhor-essentials' ) );
		}

		if ( get_role( $slug ) ) {
			wp_send_json_error( __( 'A role with this slug already exists.', 'blaminhor-essentials' ) );
		}

		$role = $this->create_role( $slug, $name, $caps );

		if ( ! $role ) {
			wp_send_json_error( __( 'Failed to create role.', 'blaminhor-essentials' ) );
		}

		wp_send_json_success( array(
			'message' => __( 'Role created successfully.', 'blaminhor-essentials' ),
			'role'    => $slug,
		) );
	}

	/**
	 * AJAX: Clone role
	 */
	public function ajax_clone_role() {
		$this->verify_ajax_request();

		$source   = $this->get_post_value( 'source', '', 'key' );
		$new_slug = $this->get_post_value( 'slug', '', 'key' );
		$new_name = $this->get_post_value( 'name', '', 'text' );

		if ( empty( $source ) || empty( $new_slug ) || empty( $new_name ) ) {
			wp_send_json_error( __( 'All fields are required.', 'blaminhor-essentials' ) );
		}

		if ( get_role( $new_slug ) ) {
			wp_send_json_error( __( 'A role with this slug already exists.', 'blaminhor-essentials' ) );
		}

		$role = $this->clone_role( $source, $new_slug, $new_name );

		if ( ! $role ) {
			wp_send_json_error( __( 'Failed to clone role.', 'blaminhor-essentials' ) );
		}

		wp_send_json_success( array(
			'message' => __( 'Role cloned successfully.', 'blaminhor-essentials' ),
			'role'    => $new_slug,
		) );
	}

	/**
	 * AJAX: Delete role
	 */
	public function ajax_delete_role() {
		$this->verify_ajax_request();

		$slug = $this->get_post_value( 'role', '', 'key' );

		if ( empty( $slug ) ) {
			wp_send_json_error( __( 'Role slug is required.', 'blaminhor-essentials' ) );
		}

		if ( $this->is_protected_role( $slug ) ) {
			wp_send_json_error( __( 'This role is protected and cannot be deleted.', 'blaminhor-essentials' ) );
		}

		if ( ! $this->delete_role( $slug ) ) {
			wp_send_json_error( __( 'Failed to delete role.', 'blaminhor-essentials' ) );
		}

		wp_send_json_success( array(
			'message' => __( 'Role deleted successfully.', 'blaminhor-essentials' ),
		) );
	}

	/**
	 * AJAX: Rename role
	 */
	public function ajax_rename_role() {
		$this->verify_ajax_request();

		$slug     = $this->get_post_value( 'role', '', 'key' );
		$new_name = $this->get_post_value( 'name', '', 'text' );

		if ( empty( $slug ) || empty( $new_name ) ) {
			wp_send_json_error( __( 'Role slug and new name are required.', 'blaminhor-essentials' ) );
		}

		if ( ! $this->rename_role( $slug, $new_name ) ) {
			wp_send_json_error( __( 'Failed to rename role.', 'blaminhor-essentials' ) );
		}

		wp_send_json_success( array(
			'message' => __( 'Role renamed successfully.', 'blaminhor-essentials' ),
		) );
	}

	/**
	 * AJAX: Update role capabilities
	 */
	public function ajax_update_caps() {
		$this->verify_ajax_request();

		$slug = $this->get_post_value( 'role', '', 'key' );
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in verify_ajax_request()
		$raw_caps = isset( $_POST['caps'] ) && is_array( $_POST['caps'] ) ? map_deep( wp_unslash( $_POST['caps'] ), 'sanitize_text_field' ) : array();

		if ( empty( $slug ) ) {
			wp_send_json_error( __( 'Role slug is required.', 'blaminhor-essentials' ) );
		}

		// Build capabilities array.
		$capabilities = array();
		foreach ( $raw_caps as $cap => $value ) {
			$capabilities[ sanitize_key( $cap ) ] = (bool) $value;
		}

		if ( ! $this->update_role_capabilities( $slug, $capabilities ) ) {
			wp_send_json_error( __( 'Failed to update capabilities.', 'blaminhor-essentials' ) );
		}

		wp_send_json_success( array(
			'message' => __( 'Capabilities updated successfully.', 'blaminhor-essentials' ),
		) );
	}

	// =========================================================================
	// AJAX Handlers - Users
	// =========================================================================

	/**
	 * AJAX: Get users list
	 */
	public function ajax_get_users() {
		$this->verify_ajax_request();

		$page     = $this->get_post_value( 'page', 1, 'int' );
		$search   = $this->get_post_value( 'search', '', 'text' );
		$per_page = 20;

		$args = array(
			'number' => $per_page,
			'offset' => ( $page - 1 ) * $per_page,
			'orderby' => 'display_name',
			'order'   => 'ASC',
		);

		if ( ! empty( $search ) ) {
			$args['search']         = '*' . $search . '*';
			$args['search_columns'] = array( 'user_login', 'user_email', 'display_name' );
		}

		$user_query = new WP_User_Query( $args );
		$users      = array();

		foreach ( $user_query->get_results() as $user ) {
			$user_caps = $this->get_user_capabilities( $user->ID );
			$users[] = array(
				'id'           => $user->ID,
				'login'        => $user->user_login,
				'email'        => $user->user_email,
				'display_name' => $user->display_name,
				'roles'        => $user->roles,
				'custom_caps'  => count( $user_caps ),
			);
		}

		// Get total count.
		$count_args = array( 'count_total' => true );
		if ( ! empty( $search ) ) {
			$count_args['search']         = '*' . $search . '*';
			$count_args['search_columns'] = array( 'user_login', 'user_email', 'display_name' );
		}
		$total_query = new WP_User_Query( $count_args );

		wp_send_json_success( array(
			'users'        => $users,
			'total'        => $total_query->get_total(),
			'pages'        => ceil( $total_query->get_total() / $per_page ),
			'current_page' => $page,
		) );
	}

	/**
	 * AJAX: Get user capabilities
	 */
	public function ajax_get_user_caps() {
		$this->verify_ajax_request();

		$user_id = $this->get_post_value( 'user_id', 0, 'int' );

		if ( ! $user_id ) {
			wp_send_json_error( __( 'User ID is required.', 'blaminhor-essentials' ) );
		}

		$user = get_userdata( $user_id );
		if ( ! $user ) {
			wp_send_json_error( __( 'User not found.', 'blaminhor-essentials' ) );
		}

		$user_caps = $this->get_user_capabilities( $user_id );
		$all_caps  = $this->get_all_capabilities();

		// Get capabilities inherited from roles.
		$role_caps = array();
		foreach ( $user->roles as $role_slug ) {
			$role = get_role( $role_slug );
			if ( $role ) {
				foreach ( array_keys( $role->capabilities ) as $cap ) {
					$role_caps[ $cap ] = true;
				}
			}
		}

		wp_send_json_success( array(
			'user'       => array(
				'id'           => $user->ID,
				'display_name' => $user->display_name,
				'roles'        => $user->roles,
			),
			'user_caps'  => $user_caps,
			'role_caps'  => $role_caps,
			'all_caps'   => $all_caps,
			'groups'     => $this->get_capability_groups(),
		) );
	}

	/**
	 * AJAX: Update user capabilities
	 */
	public function ajax_update_user_caps() {
		$this->verify_ajax_request();

		$user_id = $this->get_post_value( 'user_id', 0, 'int' );
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in verify_ajax_request()
		$caps = isset( $_POST['caps'] ) && is_array( $_POST['caps'] ) ? map_deep( wp_unslash( $_POST['caps'] ), 'sanitize_text_field' ) : array();

		if ( ! $user_id ) {
			wp_send_json_error( __( 'User ID is required.', 'blaminhor-essentials' ) );
		}

		$user = get_userdata( $user_id );
		if ( ! $user ) {
			wp_send_json_error( __( 'User not found.', 'blaminhor-essentials' ) );
		}

		// Get current user-specific caps.
		$current_caps = $this->get_user_capabilities( $user_id );

		// Remove all current user-specific caps.
		foreach ( array_keys( $current_caps ) as $cap ) {
			$user->remove_cap( $cap );
		}

		// Add new caps.
		foreach ( $caps as $cap => $granted ) {
			$cap = sanitize_key( $cap );
			if ( $granted ) {
				$user->add_cap( $cap );
			}
		}

		wp_send_json_success( array(
			'message' => __( 'User capabilities updated successfully.', 'blaminhor-essentials' ),
		) );
	}

	// =========================================================================
	// AJAX Handlers - Import/Export
	// =========================================================================

	/**
	 * AJAX: Export roles
	 */
	public function ajax_export() {
		$this->verify_ajax_request();

		$data = $this->export_roles_json();

		wp_send_json_success( array(
			'data'     => $data,
			'filename' => 'roles-export-' . gmdate( 'Y-m-d' ) . '.json',
		) );
	}

	/**
	 * AJAX: Import roles
	 */
	public function ajax_import() {
		$this->verify_ajax_request();

		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in verify_ajax_request()
		$json = isset( $_POST['data'] ) ? sanitize_textarea_field( wp_unslash( $_POST['data'] ) ) : '';
		$mode = $this->get_post_value( 'mode', 'merge', 'key' );

		if ( empty( $json ) ) {
			wp_send_json_error( __( 'No import data provided.', 'blaminhor-essentials' ) );
		}

		$data = json_decode( $json, true );
		if ( null === $data ) {
			wp_send_json_error( __( 'Invalid JSON data.', 'blaminhor-essentials' ) );
		}

		$result = $this->import_roles_json( $data, $mode );

		if ( ! $result['success'] ) {
			wp_send_json_error( $result['message'] );
		}

		wp_send_json_success( array(
			'message'  => __( 'Import completed successfully.', 'blaminhor-essentials' ),
			'imported' => $result['imported'],
			'updated'  => $result['updated'],
			'skipped'  => $result['skipped'],
		) );
	}

	/**
	 * AJAX: Reset to defaults
	 */
	public function ajax_reset() {
		$this->verify_ajax_request();

		if ( ! $this->reset_to_defaults() ) {
			wp_send_json_error( __( 'Failed to reset roles.', 'blaminhor-essentials' ) );
		}

		wp_send_json_success( array(
			'message' => __( 'Roles reset to WordPress defaults.', 'blaminhor-essentials' ),
		) );
	}

	// =========================================================================
	// AJAX Handlers - Custom Capabilities
	// =========================================================================

	/**
	 * AJAX: Add custom capability
	 */
	public function ajax_add_custom_cap() {
		$this->verify_ajax_request();

		$cap = $this->get_post_value( 'cap', '', 'key' );

		if ( empty( $cap ) ) {
			wp_send_json_error( __( 'Capability name is required.', 'blaminhor-essentials' ) );
		}

		$custom_caps = $this->get_setting( 'custom_capabilities', array() );

		if ( in_array( $cap, $custom_caps, true ) ) {
			wp_send_json_error( __( 'This capability already exists.', 'blaminhor-essentials' ) );
		}

		$custom_caps[] = $cap;

		$settings = $this->settings;
		$settings['custom_capabilities'] = $custom_caps;
		$this->save_settings( $settings );

		// Reset cache.
		$this->capability_groups = null;

		wp_send_json_success( array(
			'message' => __( 'Capability added successfully.', 'blaminhor-essentials' ),
			'cap'     => $cap,
		) );
	}

	/**
	 * AJAX: Remove custom capability
	 */
	public function ajax_remove_custom_cap() {
		$this->verify_ajax_request();

		$cap = $this->get_post_value( 'cap', '', 'key' );

		if ( empty( $cap ) ) {
			wp_send_json_error( __( 'Capability name is required.', 'blaminhor-essentials' ) );
		}

		$custom_caps = $this->get_setting( 'custom_capabilities', array() );
		$custom_caps = array_diff( $custom_caps, array( $cap ) );

		$settings = $this->settings;
		$settings['custom_capabilities'] = array_values( $custom_caps );
		$this->save_settings( $settings );

		// Reset cache.
		$this->capability_groups = null;

		wp_send_json_success( array(
			'message' => __( 'Capability removed successfully.', 'blaminhor-essentials' ),
		) );
	}

	// =========================================================================
	// Settings Page Rendering
	// =========================================================================

	/**
	 * Render settings page
	 */
	public function render_settings_page() {
		$roles      = $this->get_all_roles();
		$groups     = $this->get_capability_groups();
		$cap_labels = $this->get_capability_labels();
		$label_mode = $this->get_setting( 'label_display_mode', 'both' );
		?>
		<div class="wrap blaminhor-essentials-wrap">
			<div class="blaminhor-essentials-header">
				<h1><?php esc_html_e( 'User Role Editor', 'blaminhor-essentials' ); ?></h1>
				<p class="blaminhor-essentials-tagline">
					<?php esc_html_e( 'Manage user roles and capabilities.', 'blaminhor-essentials' ); ?>
				</p>
			</div>

			<div class="blaminhor-essentials-section">
				<div class="blaminhor-essentials-tabs-wrapper">
					<div class="blaminhor-essentials-tabs">
						<button type="button" class="blaminhor-essentials-tab active" data-tab="roles"><?php esc_html_e( 'Roles', 'blaminhor-essentials' ); ?></button>
						<button type="button" class="blaminhor-essentials-tab" data-tab="users"><?php esc_html_e( 'Users', 'blaminhor-essentials' ); ?></button>
						<button type="button" class="blaminhor-essentials-tab" data-tab="import-export"><?php esc_html_e( 'Import / Export', 'blaminhor-essentials' ); ?></button>
						<button type="button" class="blaminhor-essentials-tab" data-tab="settings"><?php esc_html_e( 'Settings', 'blaminhor-essentials' ); ?></button>
					</div>

					<!-- Roles Tab -->
					<div class="blaminhor-essentials-tab-content active" data-tab-content="roles">
						<div class="ap-ure-layout">
							<!-- Sidebar: Role List -->
							<div class="ap-ure-sidebar">
								<div class="ap-ure-sidebar-header">
									<input type="text" id="ap-ure-role-search" class="regular-text" placeholder="<?php esc_attr_e( 'Search roles...', 'blaminhor-essentials' ); ?>">
								</div>
								<div class="ap-ure-role-list" id="ap-ure-role-list">
									<?php foreach ( $roles as $slug => $role ) : ?>
										<div class="ap-ure-role-item" data-role="<?php echo esc_attr( $slug ); ?>">
											<div class="ap-ure-role-info">
												<span class="ap-ure-role-name">
													<?php if ( $role['is_protected'] ) : ?>
														<span class="dashicons dashicons-lock" title="<?php esc_attr_e( 'Protected', 'blaminhor-essentials' ); ?>"></span>
													<?php endif; ?>
													<?php echo esc_html( $role['name'] ); ?>
												</span>
												<span class="ap-ure-role-count"><?php echo esc_html( $role['user_count'] ); ?></span>
											</div>
										</div>
									<?php endforeach; ?>
								</div>
								<div class="ap-ure-sidebar-actions">
									<button type="button" id="ap-ure-add-role" class="button">
										<span class="dashicons dashicons-plus-alt2"></span>
										<?php esc_html_e( 'Add Role', 'blaminhor-essentials' ); ?>
									</button>
									<button type="button" id="ap-ure-clone-role" class="button" disabled>
										<span class="dashicons dashicons-admin-page"></span>
										<?php esc_html_e( 'Clone', 'blaminhor-essentials' ); ?>
									</button>
								</div>
							</div>

							<!-- Main: Capability Editor -->
							<div class="ap-ure-main">
								<div id="ap-ure-no-selection" class="ap-ure-placeholder">
									<span class="dashicons dashicons-admin-users"></span>
									<p><?php esc_html_e( 'Select a role to edit its capabilities.', 'blaminhor-essentials' ); ?></p>
								</div>

								<div id="ap-ure-role-editor" class="ap-hidden">
									<div class="ap-ure-editor-header">
										<h3 id="ap-ure-current-role-name"></h3>
										<div class="ap-ure-editor-actions">
											<button type="button" id="ap-ure-rename-role" class="button button-secondary">
												<span class="dashicons dashicons-edit"></span>
												<?php esc_html_e( 'Rename', 'blaminhor-essentials' ); ?>
											</button>
											<button type="button" id="ap-ure-delete-role" class="button button-secondary ap-btn-danger">
												<span class="dashicons dashicons-trash"></span>
												<?php esc_html_e( 'Delete', 'blaminhor-essentials' ); ?>
											</button>
										</div>
									</div>

									<div class="ap-ure-caps-toolbar">
										<input type="text" id="ap-ure-cap-search" class="regular-text" placeholder="<?php esc_attr_e( 'Search capabilities...', 'blaminhor-essentials' ); ?>">
										<button type="button" class="button button-small ap-ure-select-all"><?php esc_html_e( 'Select All', 'blaminhor-essentials' ); ?></button>
										<button type="button" class="button button-small ap-ure-deselect-all"><?php esc_html_e( 'Deselect All', 'blaminhor-essentials' ); ?></button>
									</div>

									<div id="ap-ure-caps-container">
										<?php foreach ( $groups as $group_id => $group ) : ?>
											<?php if ( empty( $group['caps'] ) ) continue; ?>
											<div class="ap-ure-cap-group" data-group="<?php echo esc_attr( $group_id ); ?>">
												<div class="ap-ure-cap-group-header">
													<span class="ap-ure-group-toggle dashicons dashicons-arrow-down-alt2"></span>
													<?php echo esc_html( $group['label'] ); ?>
													<span class="ap-ure-group-count">0</span>
												</div>
												<div class="ap-ure-cap-list">
													<?php foreach ( $group['caps'] as $cap ) :
														$friendly_label = isset( $cap_labels[ $cap ] ) ? $cap_labels[ $cap ] : '';
													?>
														<label class="ap-ure-cap-item" data-label-mode="<?php echo esc_attr( $label_mode ); ?>">
															<input type="checkbox" name="caps[<?php echo esc_attr( $cap ); ?>]" value="1">
															<span class="ap-ure-cap-label">
																<?php if ( 'technical' === $label_mode ) : ?>
																	<span class="ap-ure-cap-technical"><?php echo esc_html( $cap ); ?></span>
																<?php elseif ( 'friendly' === $label_mode && $friendly_label ) : ?>
																	<span class="ap-ure-cap-friendly"><?php echo esc_html( $friendly_label ); ?></span>
																<?php elseif ( 'both' === $label_mode && $friendly_label ) : ?>
																	<span class="ap-ure-cap-friendly"><?php echo esc_html( $friendly_label ); ?></span>
																	<span class="ap-ure-cap-technical"><?php echo esc_html( $cap ); ?></span>
																<?php else : ?>
																	<span class="ap-ure-cap-technical"><?php echo esc_html( $cap ); ?></span>
																<?php endif; ?>
															</span>
														</label>
													<?php endforeach; ?>
												</div>
											</div>
										<?php endforeach; ?>
									</div>

									<div class="ap-ure-editor-footer">
										<div id="ap-ure-save-notice" class="ap-ure-save-notice ap-hidden"></div>
										<button type="button" id="ap-ure-save-caps" class="button button-primary">
											<span class="dashicons dashicons-saved"></span>
											<?php esc_html_e( 'Save Changes', 'blaminhor-essentials' ); ?>
										</button>
									</div>
								</div>
							</div>
						</div>
					</div>

					<!-- Users Tab -->
					<div class="blaminhor-essentials-tab-content" data-tab-content="users">
						<div class="ap-ure-users-header">
							<input type="text" id="ap-ure-user-search" class="regular-text" placeholder="<?php esc_attr_e( 'Search users...', 'blaminhor-essentials' ); ?>">
							<button type="button" id="ap-ure-refresh-users" class="button button-secondary">
								<span class="dashicons dashicons-update"></span>
							</button>
						</div>

						<table class="wp-list-table widefat fixed striped" id="ap-ure-users-table">
							<thead>
								<tr>
									<th style="width: 25%;"><?php esc_html_e( 'User', 'blaminhor-essentials' ); ?></th>
									<th style="width: 25%;"><?php esc_html_e( 'Email', 'blaminhor-essentials' ); ?></th>
									<th style="width: 20%;"><?php esc_html_e( 'Roles', 'blaminhor-essentials' ); ?></th>
									<th style="width: 15%;"><?php esc_html_e( 'Custom Caps', 'blaminhor-essentials' ); ?></th>
									<th style="width: 15%;"><?php esc_html_e( 'Actions', 'blaminhor-essentials' ); ?></th>
								</tr>
							</thead>
							<tbody id="ap-ure-users-tbody">
								<tr>
									<td colspan="5" class="ap-table-empty">
										<span class="dashicons dashicons-update spin"></span>
										<?php esc_html_e( 'Loading...', 'blaminhor-essentials' ); ?>
									</td>
								</tr>
							</tbody>
						</table>

						<div id="ap-ure-users-pagination" class="ap-pagination"></div>
					</div>

					<!-- Import/Export Tab -->
					<div class="blaminhor-essentials-tab-content" data-tab-content="import-export">
						<div class="ap-ure-import-export-grid">
							<!-- Export Section -->
							<div class="ap-ure-section">
								<h3><?php esc_html_e( 'Export Roles', 'blaminhor-essentials' ); ?></h3>
								<p class="description"><?php esc_html_e( 'Download all roles and capabilities as a JSON file.', 'blaminhor-essentials' ); ?></p>
								<p>
									<button type="button" id="ap-ure-export-btn" class="button button-primary ap-btn-icon">
										<span class="dashicons dashicons-download"></span>
										<?php esc_html_e( 'Export Roles', 'blaminhor-essentials' ); ?>
									</button>
								</p>
							</div>

							<!-- Import Section -->
							<div class="ap-ure-section">
								<h3><?php esc_html_e( 'Import Roles', 'blaminhor-essentials' ); ?></h3>
								<p class="description"><?php esc_html_e( 'Import roles from a JSON file.', 'blaminhor-essentials' ); ?></p>

								<div class="ap-ure-import-options">
									<p>
										<label>
											<input type="radio" name="ap_ure_import_mode" value="merge" checked>
											<?php esc_html_e( 'Merge with existing roles', 'blaminhor-essentials' ); ?>
										</label>
									</p>
									<p>
										<label>
											<input type="radio" name="ap_ure_import_mode" value="replace">
											<?php esc_html_e( 'Replace all roles (except administrator)', 'blaminhor-essentials' ); ?>
										</label>
									</p>
								</div>

								<p>
									<input type="file" id="ap-ure-import-file" accept=".json">
								</p>
								<p>
									<button type="button" id="ap-ure-import-btn" class="button button-primary ap-btn-icon">
										<span class="dashicons dashicons-upload"></span>
										<?php esc_html_e( 'Import Roles', 'blaminhor-essentials' ); ?>
									</button>
								</p>
								<div id="ap-ure-import-result" class="ap-hidden ap-mt-md"></div>
							</div>

							<!-- Reset Section -->
							<div class="ap-ure-section ap-ure-section-danger">
								<h3><?php esc_html_e( 'Reset to Defaults', 'blaminhor-essentials' ); ?></h3>
								<p class="description"><?php esc_html_e( 'Reset all roles to WordPress default values. This will remove all custom roles.', 'blaminhor-essentials' ); ?></p>
								<p>
									<button type="button" id="ap-ure-reset-btn" class="button button-secondary ap-btn-danger ap-btn-icon">
										<span class="dashicons dashicons-image-rotate"></span>
										<?php esc_html_e( 'Reset to Defaults', 'blaminhor-essentials' ); ?>
									</button>
								</p>
							</div>
						</div>
					</div>

					<!-- Settings Tab -->
					<div class="blaminhor-essentials-tab-content" data-tab-content="settings">
						<form method="post">
							<?php $this->render_nonce_field(); ?>

							<table class="form-table">
								<tr>
									<th scope="row"><?php esc_html_e( 'Capability Labels', 'blaminhor-essentials' ); ?></th>
									<td>
										<?php $label_mode = $this->get_setting( 'label_display_mode', 'both' ); ?>
										<fieldset>
											<label>
												<input type="radio" name="label_display_mode" value="technical" <?php checked( $label_mode, 'technical' ); ?>>
												<?php esc_html_e( 'Technical names only', 'blaminhor-essentials' ); ?>
												<span class="description">(edit_posts, delete_others_pages...)</span>
											</label><br>
											<label>
												<input type="radio" name="label_display_mode" value="friendly" <?php checked( $label_mode, 'friendly' ); ?>>
												<?php esc_html_e( 'Human-readable labels only', 'blaminhor-essentials' ); ?>
											</label><br>
											<label>
												<input type="radio" name="label_display_mode" value="both" <?php checked( $label_mode, 'both' ); ?>>
												<?php esc_html_e( 'Both (human-readable + technical)', 'blaminhor-essentials' ); ?>
											</label>
										</fieldset>
										<p class="description"><?php esc_html_e( 'Choose how capability names are displayed in the editor.', 'blaminhor-essentials' ); ?></p>
									</td>
								</tr>
								<tr>
									<th scope="row"><?php esc_html_e( 'Deprecated Capabilities', 'blaminhor-essentials' ); ?></th>
									<td>
										<label>
											<input type="checkbox" name="show_deprecated_caps" <?php checked( $this->get_setting( 'show_deprecated_caps', false ) ); ?>>
											<?php esc_html_e( 'Show deprecated capabilities (level_0 to level_10)', 'blaminhor-essentials' ); ?>
										</label>
										<p class="description"><?php esc_html_e( 'These capabilities are from older WordPress versions and are rarely needed.', 'blaminhor-essentials' ); ?></p>
									</td>
								</tr>
								<tr>
									<th scope="row"><?php esc_html_e( 'Administrator Role', 'blaminhor-essentials' ); ?></th>
									<td>
										<label>
											<input type="checkbox" name="allow_admin_role_edit" <?php checked( $this->get_setting( 'allow_admin_role_edit', false ) ); ?>>
											<?php esc_html_e( 'Allow editing the Administrator role capabilities', 'blaminhor-essentials' ); ?>
										</label>
										<p class="description ap-desc-danger"><?php esc_html_e( 'Warning: Modifying administrator capabilities can lock you out of your site.', 'blaminhor-essentials' ); ?></p>
									</td>
								</tr>
							</table>

							<hr>

							<h3><?php esc_html_e( 'Custom Capabilities', 'blaminhor-essentials' ); ?></h3>
							<p class="description"><?php esc_html_e( 'Add custom capabilities that can be assigned to roles.', 'blaminhor-essentials' ); ?></p>

							<div id="ap-ure-custom-caps-list" style="margin: 15px 0;">
								<?php
								$custom_caps = $this->get_setting( 'custom_capabilities', array() );
								if ( empty( $custom_caps ) ) :
								?>
									<p class="description"><?php esc_html_e( 'No custom capabilities defined.', 'blaminhor-essentials' ); ?></p>
								<?php else : ?>
									<?php foreach ( $custom_caps as $cap ) : ?>
										<span class="ap-ure-custom-cap-tag">
											<?php echo esc_html( $cap ); ?>
											<button type="button" class="ap-ure-remove-custom-cap" data-cap="<?php echo esc_attr( $cap ); ?>">&times;</button>
										</span>
									<?php endforeach; ?>
								<?php endif; ?>
							</div>

							<div style="display: flex; gap: 10px; align-items: center;">
								<input type="text" id="ap-ure-new-custom-cap" class="regular-text" placeholder="<?php esc_attr_e( 'new_capability_name', 'blaminhor-essentials' ); ?>">
								<button type="button" id="ap-ure-add-custom-cap" class="button button-secondary">
									<?php esc_html_e( 'Add Capability', 'blaminhor-essentials' ); ?>
								</button>
							</div>

							<p class="submit">
								<button type="submit" class="button button-primary">
									<?php esc_html_e( 'Save Settings', 'blaminhor-essentials' ); ?>
								</button>
							</p>
						</form>
					</div>
				</div>
			</div>
		</div>

		<!-- Modals -->
		<!-- Add/Clone Role Modal -->
		<div id="ap-ure-role-modal" class="ap-db-modal ap-hidden">
			<div class="ap-db-modal-overlay"></div>
			<div class="ap-db-modal-content" style="max-width: 400px;">
				<div class="ap-db-modal-header">
					<h3 id="ap-ure-modal-title"><?php esc_html_e( 'Add New Role', 'blaminhor-essentials' ); ?></h3>
					<button type="button" class="ap-modal-close">&times;</button>
				</div>
				<div class="ap-db-modal-body">
					<input type="hidden" id="ap-ure-modal-action" value="create">
					<input type="hidden" id="ap-ure-modal-source" value="">

					<p>
						<label for="ap-ure-modal-name"><?php esc_html_e( 'Role Name', 'blaminhor-essentials' ); ?></label>
						<input type="text" id="ap-ure-modal-name" class="large-text" placeholder="<?php esc_attr_e( 'My Custom Role', 'blaminhor-essentials' ); ?>">
					</p>
					<p>
						<label for="ap-ure-modal-slug"><?php esc_html_e( 'Role Slug', 'blaminhor-essentials' ); ?></label>
						<input type="text" id="ap-ure-modal-slug" class="large-text" placeholder="<?php esc_attr_e( 'my_custom_role', 'blaminhor-essentials' ); ?>">
						<span class="description"><?php esc_html_e( 'Lowercase letters, numbers and underscores only.', 'blaminhor-essentials' ); ?></span>
					</p>
				</div>
				<div class="ap-db-modal-footer">
					<button type="button" class="button button-secondary ap-modal-close"><?php esc_html_e( 'Cancel', 'blaminhor-essentials' ); ?></button>
					<button type="button" id="ap-ure-modal-submit" class="button button-primary"><?php esc_html_e( 'Create Role', 'blaminhor-essentials' ); ?></button>
				</div>
			</div>
		</div>

		<!-- Rename Role Modal -->
		<div id="ap-ure-rename-modal" class="ap-db-modal ap-hidden">
			<div class="ap-db-modal-overlay"></div>
			<div class="ap-db-modal-content" style="max-width: 400px;">
				<div class="ap-db-modal-header">
					<h3><?php esc_html_e( 'Rename Role', 'blaminhor-essentials' ); ?></h3>
					<button type="button" class="ap-modal-close">&times;</button>
				</div>
				<div class="ap-db-modal-body">
					<input type="hidden" id="ap-ure-rename-role-slug" value="">
					<p>
						<label for="ap-ure-rename-name"><?php esc_html_e( 'New Name', 'blaminhor-essentials' ); ?></label>
						<input type="text" id="ap-ure-rename-name" class="large-text">
					</p>
				</div>
				<div class="ap-db-modal-footer">
					<button type="button" class="button button-secondary ap-modal-close"><?php esc_html_e( 'Cancel', 'blaminhor-essentials' ); ?></button>
					<button type="button" id="ap-ure-rename-submit" class="button button-primary"><?php esc_html_e( 'Rename', 'blaminhor-essentials' ); ?></button>
				</div>
			</div>
		</div>

		<!-- User Capabilities Modal -->
		<div id="ap-ure-user-caps-modal" class="ap-db-modal ap-hidden">
			<div class="ap-db-modal-overlay"></div>
			<div class="ap-db-modal-content" style="max-width: 600px;">
				<div class="ap-db-modal-header">
					<h3><?php esc_html_e( 'Edit User Capabilities', 'blaminhor-essentials' ); ?></h3>
					<button type="button" class="ap-modal-close">&times;</button>
				</div>
				<div class="ap-db-modal-body">
					<input type="hidden" id="ap-ure-user-modal-id" value="">
					<p id="ap-ure-user-modal-info"></p>
					<p class="description"><?php esc_html_e( 'These are additional capabilities specific to this user (beyond their role).', 'blaminhor-essentials' ); ?></p>
					<input type="text" id="ap-ure-user-cap-search" class="regular-text" placeholder="<?php esc_attr_e( 'Search capabilities...', 'blaminhor-essentials' ); ?>" style="display: none; width: 100%; margin-top: 10px;">
					<div id="ap-ure-user-caps-list" style="max-height: 300px; overflow-y: auto; margin-top: 15px;"></div>
				</div>
				<div class="ap-db-modal-footer">
					<button type="button" class="button button-secondary ap-modal-close"><?php esc_html_e( 'Cancel', 'blaminhor-essentials' ); ?></button>
					<button type="button" id="ap-ure-user-caps-save" class="button button-primary"><?php esc_html_e( 'Save Changes', 'blaminhor-essentials' ); ?></button>
				</div>
			</div>
		</div>
		<?php
	}
}
