<?php
/**
 * Name: Switchboard Access Control
 * Description: Control which user roles can access Switchboard plugin with view-only or full edit permissions and hide plugin from roles for white-label experience
 * Category: Admin
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "View-Only Access",
 *     "description": "Give Editors or custom roles view-only access to Switchboard - they can see all modules and settings but cannot make any changes."
 *   },
 *   {
 *     "title": "White Label & Hide Plugin",
 *     "description": "Hide Switchboard from specific roles' plugins list and admin menu for a cleaner, white-label experience for clients or team members."
 *   }
 * ]
 * Tags: roles, permissions, access-control, security, visibility, view-only
 * Added: 2025-10-19
 * Disabled: true
 * WhereToFind: {
 *   "location": "Switchboard Settings",
 *   "url": "admin.php?page=switchboard",
 *   "instructions": "Test access with different user roles",
 *   "newTab": false
 * }
 */

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

class SwitchboardPluginRoleControl {

    private $settings = [];

    public function __construct() {
        $this->settings = get_option('switchboard_plugin-role-control_settings', []);

        // Control access to Switchboard pages
        add_action('admin_init', [$this, 'enforce_role_access'], 1);
        add_action('admin_menu', [$this, 'modify_menu_for_viewers'], 999);

        // Hide plugin from plugins list
        add_filter('all_plugins', [$this, 'hide_plugin_from_list']);

        // Block edit actions for view-only users
        add_action('wp_ajax_switchboard_save_module_settings', [$this, 'block_edit_actions'], 1);
        add_action('wp_ajax_switchboard_save_modules', [$this, 'block_edit_actions'], 1);
        add_action('wp_ajax_switchboard_import_preset', [$this, 'block_edit_actions'], 1);

        // Add visual indicators for view-only mode
        add_action('admin_enqueue_scripts', [$this, 'enqueue_view_only_scripts']);
        
        // Register with data registry
        $this->register_with_data_registry();
    }
    
    private function register_with_data_registry() {
        if (class_exists('Switchboard_Data_Registry')) {
            $registry = Switchboard_Data_Registry::get_instance();
            $registry->auto_register($this, __FILE__);
        }
    }
    
    public function register_data_locations() {
        return [
            'options' => [
                'switchboard_plugin-role-control_settings'
            ],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
            'term_meta' => [],
            'transients' => []
        ];
    }
    
    /**
     * Render settings panel for Switchboard Access Control
     * 
     * Displays role-based access control interface with:
     * - View-only access roles (can see but not edit)
     * - Full edit access roles (can modify settings)
     * - Hide plugin roles (Switchboard hidden from plugins list)
     * - Visual role selection with tag selector
     * 
     * @param array $settings Current module settings
     * @return void Outputs HTML directly
     */
    public function render_settings($settings = []) {
        $view_roles = isset($settings['view_roles']) ? explode(',', $settings['view_roles']) : [];
        $view_roles = array_map('trim', $view_roles);
        $edit_roles = isset($settings['edit_roles']) ? explode(',', $settings['edit_roles']) : [];
        $edit_roles = array_map('trim', $edit_roles);
        $hide_plugin_roles = isset($settings['hide_plugin_roles']) ? explode(',', $settings['hide_plugin_roles']) : [];
        $hide_plugin_roles = array_map('trim', $hide_plugin_roles);

        $all_roles = wp_roles()->get_names();
        ?>
        <input type="hidden" name="module" value="plugin-role-control">

        <div class="sb-sp-alert-info">
            <strong><?php esc_html_e('About Switchboard Role Control:', 'wpswitchboard'); ?></strong><br>
            <?php echo '• <strong>' . esc_html__('View Roles:', 'wpswitchboard') . '</strong> ' . esc_html__('Users with these roles can see Switchboard but cannot modify settings', 'wpswitchboard'); ?><br>
            <?php echo '• <strong>' . esc_html__('Edit Roles:', 'wpswitchboard') . '</strong> ' . esc_html__('Users with these roles have full access to modify Switchboard settings', 'wpswitchboard'); ?><br>
            <?php echo '• <strong>' . esc_html__('Hide Switchboard:', 'wpswitchboard') . '</strong> ' . esc_html__('Switchboard will be hidden from the plugins list for these roles', 'wpswitchboard'); ?><br>
            <?php echo '• ' . esc_html__('Leave empty to allow all administrators', 'wpswitchboard'); ?>
        </div>

        <!-- View Access Roles -->
        <input type="hidden" name="setting_view_roles" id="setting_view_roles" value="<?php echo esc_attr(implode(',', $view_roles)); ?>">
        <label class="sb-sp-text-semibold"><?php esc_html_e('View-Only Access Roles', 'wpswitchboard'); ?></label>
        <div class="switchboard-tag-selector sb-sp-mb">
            <div class="switchboard-selected-tags" id="selected-view-roles">
                <?php foreach ($view_roles as $role_slug):
                    if (isset($all_roles[$role_slug])): ?>
                        <span class="switchboard-tag" data-value="<?php echo esc_attr($role_slug); ?>" data-type="view">
                            <?php echo esc_html($all_roles[$role_slug]); ?> <span class="remove-tag">×</span>
                        </span>
                <?php endif; endforeach; ?>
            </div>
            <div class="switchboard-available-tags" id="available-view-roles">
                <?php foreach ($all_roles as $role_slug => $role_name):
                    $is_selected = in_array($role_slug, $view_roles) ? 'selected' : ''; ?>
                    <span class="switchboard-tag-option <?php echo $is_selected; ?>" data-value="<?php echo esc_attr($role_slug); ?>" data-type="view">
                        <?php echo esc_html($role_name); ?>
                    </span>
                <?php endforeach; ?>
            </div>
        </div>
        <p class="sb-sp-description"><?php esc_html_e('Users with these roles can view Switchboard settings but cannot make changes.', 'wpswitchboard'); ?></p>

        <!-- Edit Access Roles -->
        <input type="hidden" name="setting_edit_roles" id="setting_edit_roles" value="<?php echo esc_attr(implode(',', $edit_roles)); ?>">
        <label class="sb-sp-text-semibold"><?php esc_html_e('Full Edit Access Roles', 'wpswitchboard'); ?></label>
        <div class="switchboard-tag-selector sb-sp-mb">
            <div class="switchboard-selected-tags" id="selected-edit-roles">
                <?php foreach ($edit_roles as $role_slug):
                    if (isset($all_roles[$role_slug])): ?>
                        <span class="switchboard-tag" data-value="<?php echo esc_attr($role_slug); ?>" data-type="edit">
                            <?php echo esc_html($all_roles[$role_slug]); ?> <span class="remove-tag">×</span>
                        </span>
                <?php endif; endforeach; ?>
            </div>
            <div class="switchboard-available-tags" id="available-edit-roles">
                <?php foreach ($all_roles as $role_slug => $role_name):
                    $is_selected = in_array($role_slug, $edit_roles) ? 'selected' : ''; ?>
                    <span class="switchboard-tag-option <?php echo $is_selected; ?>" data-value="<?php echo esc_attr($role_slug); ?>" data-type="edit">
                        <?php echo esc_html($role_name); ?>
                    </span>
                <?php endforeach; ?>
            </div>
        </div>
        <p class="sb-sp-description"><?php esc_html_e('Users with these roles can fully modify Switchboard settings.', 'wpswitchboard'); ?></p>

        <!-- Hide Plugin Roles -->
        <input type="hidden" name="setting_hide_plugin_roles" id="setting_hide_plugin_roles" value="<?php echo esc_attr(implode(',', $hide_plugin_roles)); ?>">
        <label class="sb-sp-text-semibold"><?php esc_html_e('Hide Switchboard From These Roles', 'wpswitchboard'); ?></label>
        <div class="switchboard-tag-selector sb-sp-mb">
            <div class="switchboard-selected-tags" id="selected-hide-roles">
                <?php foreach ($hide_plugin_roles as $role_slug):
                    if (isset($all_roles[$role_slug])): ?>
                        <span class="switchboard-tag" data-value="<?php echo esc_attr($role_slug); ?>" data-type="hide">
                            <?php echo esc_html($all_roles[$role_slug]); ?> <span class="remove-tag">×</span>
                        </span>
                <?php endif; endforeach; ?>
            </div>
            <div class="switchboard-available-tags" id="available-hide-roles">
                <?php foreach ($all_roles as $role_slug => $role_name):
                    $is_selected = in_array($role_slug, $hide_plugin_roles) ? 'selected' : ''; ?>
                    <span class="switchboard-tag-option <?php echo $is_selected; ?>" data-value="<?php echo esc_attr($role_slug); ?>" data-type="hide">
                        <?php echo esc_html($role_name); ?>
                    </span>
                <?php endforeach; ?>
            </div>
        </div>
        <p class="sb-sp-description"><?php esc_html_e('Switchboard will not appear in the plugins list for users with these roles.', 'wpswitchboard'); ?></p>

        <script>
        jQuery(document).ready(function($) {
            // Handle role selection for all three types
            $(".switchboard-tag-option").on("click", function() {
                const $this = $(this);
                const value = $this.data("value");
                const type = $this.data("type");

                if ($this.hasClass("selected")) {
                    // Remove role
                    $this.removeClass("selected");
                    $("#selected-" + type + "-roles .switchboard-tag[data-value=\"" + value + "\"]").remove();
                } else {
                    // Add role
                    $this.addClass("selected");
                    const label = $this.text();
                    $("#selected-" + type + "-roles").append(
                        "<span class=\"switchboard-tag\" data-value=\"" + value + "\" data-type=\"" + type + "\">" +
                        label + " <span class=\"remove-tag\">×</span></span>"
                    );
                }

                updateRoles(type);
            });

            // Remove role tag
            $(document).on("click", ".switchboard-tag .remove-tag", function() {
                const $tag = $(this).parent();
                const value = $tag.data("value");
                const type = $tag.data("type");

                $tag.remove();
                $("#available-" + type + "-roles .switchboard-tag-option[data-value=\"" + value + "\"]").removeClass("selected");

                updateRoles(type);
            });

            // Update hidden input values
            function updateRoles(type) {
                const roles = [];
                $("#selected-" + type + "-roles .switchboard-tag").each(function() {
                    roles.push($(this).data("value"));
                });
                $("#setting_" + type + "_roles").val(roles.join(","));
            }
        });
        </script>
        <?php
    }

    /**
     * Check if current user has view access
     */
    private function has_view_access() {
        if (!is_user_logged_in()) {
            return false;
        }

        $user = wp_get_current_user();
        $user_roles = (array) $user->roles;

        // Get allowed roles for viewing
        $view_roles = $this->get_roles_array('view_roles');
        $edit_roles = $this->get_roles_array('edit_roles');

        // If no roles configured, allow all admins
        if (empty($view_roles) && empty($edit_roles)) {
            return current_user_can('manage_options');
        }

        // Check if user has view or edit access
        foreach ($user_roles as $role) {
            if (in_array($role, $view_roles, true) || in_array($role, $edit_roles, true)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if current user has edit access
     */
    private function has_edit_access() {
        if (!is_user_logged_in()) {
            return false;
        }

        $user = wp_get_current_user();
        $user_roles = (array) $user->roles;

        // Get allowed roles for editing
        $edit_roles = $this->get_roles_array('edit_roles');

        // If no edit roles configured, allow all admins
        if (empty($edit_roles)) {
            return current_user_can('manage_options');
        }

        // Check if user has edit access
        foreach ($user_roles as $role) {
            if (in_array($role, $edit_roles, true)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if plugin should be hidden from current user
     */
    private function should_hide_plugin() {
        if (!is_user_logged_in()) {
            return false;
        }

        $user = wp_get_current_user();
        $user_roles = (array) $user->roles;

        // Get roles to hide plugin from
        $hide_roles = $this->get_roles_array('hide_plugin_roles');

        // Check if user's role is in hide list
        foreach ($user_roles as $role) {
            if (in_array($role, $hide_roles, true)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Get roles array from settings
     */
    private function get_roles_array($key) {
        $roles_string = isset($this->settings[$key]) ? $this->settings[$key] : '';
        if (empty($roles_string) || !is_string($roles_string)) {
            return [];
        }
        return array_map('trim', explode(',', $roles_string));
    }

    /**
     * Enforce role-based access control
     */
    public function enforce_role_access() {
        // Check if trying to access Switchboard page
        $page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : '';
        if ($page && strpos($page, 'switchboard') === 0) {
            if (!$this->has_view_access()) {
                wp_die(
                    '<h1>' . esc_html__('Access Denied', 'wpswitchboard') . '</h1><p>' . esc_html__('You do not have permission to access Switchboard.', 'wpswitchboard') . '</p>',
                    esc_html__('Access Denied', 'wpswitchboard'),
                    ['response' => 403, 'back_link' => true]
                );
            }
        }
    }

    /**
     * Modify menu for view-only users
     */
    public function modify_menu_for_viewers() {
        // If user has view but not edit access, modify menu
        if ($this->has_view_access() && !$this->has_edit_access()) {
            global $submenu;
            // Add indicator to menu that it's view-only
            if (isset($submenu['switchboard']) && is_array($submenu['switchboard'])) {
                foreach ($submenu['switchboard'] as &$item) {
                    if (isset($item[2]) && $item[2] === 'switchboard') {
                        $item[0] .= ' <span style="color: #f0ad4e;">(' . esc_html__('View Only', 'wpswitchboard') . ')</span>';
                    }
                }
            }
        }
    }

    /**
     * Hide plugin from plugins list for specified roles
     */
    public function hide_plugin_from_list($plugins) {
        if ($this->should_hide_plugin()) {
            // Find and remove Switchboard plugin from list
            foreach ($plugins as $plugin_file => $plugin_data) {
                if (strpos($plugin_file, 'switchboard.php') !== false ||
                    (isset($plugin_data['Name']) && strpos($plugin_data['Name'], 'Switchboard') !== false)) {
                    unset($plugins[$plugin_file]);
                }
            }
        }

        return $plugins;
    }

    /**
     * Block edit actions for view-only users
     */
    public function block_edit_actions() {
        if (!$this->has_edit_access()) {
            wp_send_json_error([
                'message' => esc_html__('You have view-only access to Switchboard. Contact an administrator for edit permissions.', 'wpswitchboard')
            ]);
            exit;
        }
    }

    /**
     * Enqueue scripts for view-only mode
     */
    public function enqueue_view_only_scripts($hook) {
        if (strpos($hook, 'switchboard') === false) {
            return;
        }

        if ($this->has_view_access() && !$this->has_edit_access()) {
            // Localize strings for JavaScript
            $i18n = [
                'viewOnlyBanner' => __('View-Only Mode:', 'wpswitchboard'),
                'viewOnlyMessage' => __('You have read-only access to Switchboard. Contact an administrator to request edit permissions.', 'wpswitchboard'),
                'viewOnlyAlert' => __('You have view-only access. Contact an administrator to make changes.', 'wpswitchboard')
            ];

            // Add inline script to disable form controls
            $script = "
            jQuery(document).ready(function($) {
                const i18n = " . json_encode($i18n) . ";

                // Add view-only banner
                $('.switchboard-container').prepend('<div class=\"notice notice-warning\" style=\"margin: 20px 0; padding: 15px;\"><strong>' + i18n.viewOnlyBanner + '</strong> ' + i18n.viewOnlyMessage + '</div>');

                // Disable all form inputs
                $('.switchboard-container input, .switchboard-container select, .switchboard-container textarea, .switchboard-container button').prop('disabled', true).css('opacity', '0.6');

                // Disable toggle switches
                $('.module-toggle').off('change').on('change', function(e) {
                    e.preventDefault();
                    alert(i18n.viewOnlyAlert);
                    return false;
                });

                // Prevent form submissions
                $('.switchboard-container form').on('submit', function(e) {
                    e.preventDefault();
                    alert(i18n.viewOnlyAlert);
                    return false;
                });
            });
            ";

            wp_add_inline_script('jquery', $script);
        }
    }
}

// Initialize and register with data system
$switchboard_instance = new SwitchboardPluginRoleControl();
Switchboard_Data_Registry::get_instance()->auto_register($switchboard_instance, __FILE__);
