<?php
/**
 * Name: Hide Admin Menu Items
 * Description: Selectively hide specific admin menu items from sidebar navigation by role to simplify dashboard for clients, remove unused features, or create cleaner white-label admin
 * Category: Admin
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "Declutter Admin Sidebar",
 *     "description": "Remove unused menu items like Comments or Tools to create a cleaner, more focused admin experience."
 *   },
 *   {
 *     "title": "White-Label Dashboard",
 *     "description": "Hide plugin menus and unnecessary items to create a streamlined, branded admin interface."
 *   },
 *   {
 *     "title": "Role-Based Menu Control",
 *     "description": "Show different menu items to different user roles - give editors a simplified menu while keeping full access for admins."
 *   }
 * ]
 * Added: 2025-06-20
 * Tags: admin, menu, hide, customize, clean, roles
 * WhereToFind: {
 *   "location": "Admin Sidebar Menu",
 *   "url": "",
 *   "instructions": "Select menu items to hide in module settings. Configure per-role or use default for all users.",
 *   "newTab": false
 * }
 */

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

class SwitchboardHideAdminMenuItems {

    public function __construct() {
        add_action('admin_menu', [$this, 'hide_menu_items'], 999);
    }

    public function register_data_locations() {
        return [
            'options' => [
                'switchboard_hide-admin-menu-items_settings'
            ],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
            'term_meta' => [],
            'transients' => []
        ];
    }

    /**
     * Get all WordPress roles
     */
    private function get_roles() {
        global $wp_roles;
        if (!isset($wp_roles)) {
            $wp_roles = new WP_Roles();
        }
        return $wp_roles->get_names();
    }

    /**
     * Get organized menu items
     */
    private function get_organized_menus() {
        global $menu;

        // Trigger menu build hooks if menu is empty (happens during AJAX)
        static $building_menu = false;
        if (empty($menu) && !$building_menu) {
            $building_menu = true;
            do_action('admin_menu');
            do_action('_admin_menu');
            $building_menu = false;
        }

        $available_menus = [];

        // Get actual menu items from global $menu
        if (!empty($menu)) {
            foreach ($menu as $item) {
                if (isset($item[0]) && isset($item[2]) && !empty($item[0])) {
                    $title = wp_strip_all_tags($item[0]);
                    $title = preg_replace('/\s*<span.*?<\/span>\s*/', '', $title);
                    $title = trim($title);

                    if (!empty($title) && $item[2] !== 'separator' && strpos($item[2], 'separator') === false) {
                        $available_menus[$item[2]] = $title;
                    }
                }
            }
        }

        // Organize menu items by category with separators
        $organized_menus = [
            esc_html__('Core Content', 'wpswitchboard') => [
                'index.php' => esc_html__('Dashboard', 'wpswitchboard'),
                'edit.php' => esc_html__('Posts', 'wpswitchboard'),
                'upload.php' => esc_html__('Media', 'wpswitchboard'),
                'edit.php?post_type=page' => esc_html__('Pages', 'wpswitchboard'),
                'edit-comments.php' => esc_html__('Comments', 'wpswitchboard'),
            ],
            esc_html__('Appearance & Plugins', 'wpswitchboard') => [
                'themes.php' => esc_html__('Appearance', 'wpswitchboard'),
                'plugins.php' => esc_html__('Plugins', 'wpswitchboard'),
            ],
            esc_html__('Users & Settings', 'wpswitchboard') => [
                'users.php' => esc_html__('Users', 'wpswitchboard'),
                'tools.php' => esc_html__('Tools', 'wpswitchboard'),
                'options-general.php' => esc_html__('Settings', 'wpswitchboard'),
            ],
        ];

        // Dynamically detect plugin menus and custom post types from actual menu
        $plugin_menus = [];
        if (!empty($available_menus)) {
            foreach ($available_menus as $slug => $title) {
                // Skip if it's already in core sections
                $in_core = false;
                foreach ($organized_menus as $category => $menus) {
                    if (isset($menus[$slug])) {
                        $in_core = true;
                        break;
                    }
                }

                // If not in core sections, it's a plugin menu or custom post type
                if (!$in_core && $slug !== 'separator' && strpos($slug, 'separator') === false) {
                    $plugin_menus[$slug] = $title;
                }
            }
        }

        // Only add Plugin Menus section if there are any
        if (!empty($plugin_menus)) {
            $organized_menus[esc_html__('Plugin Menus & Custom Post Types', 'wpswitchboard')] = $plugin_menus;
        }

        // Merge with actual menu items
        foreach ($organized_menus as $category => $menus) {
            foreach ($menus as $slug => $title) {
                if (isset($available_menus[$slug])) {
                    $organized_menus[$category][$slug] = $available_menus[$slug];
                }
            }
        }

        return ['organized' => $organized_menus, 'available' => $available_menus];
    }

    /**
     * Render settings panel
     *
     * @param array $settings Current module settings
     * @return void Outputs HTML directly
     */
    public function render_settings($settings = []) {
        // Load settings from database if not passed (backwards compatibility)
        if (empty($settings)) {
            $settings = get_option('switchboard_hide-admin-menu-items_settings', []);
        }

        // Get default (all users) settings - backwards compatible
        $default_items = isset($settings['menu_items']) ? explode(',', $settings['menu_items']) : [];
        $default_items = array_filter(array_map('trim', $default_items));

        // Get role-specific settings
        $role_settings = isset($settings['role_menu_items']) && is_array($settings['role_menu_items'])
            ? $settings['role_menu_items']
            : [];

        // Get all roles
        $roles = $this->get_roles();

        // Get organized menus
        $menu_data = $this->get_organized_menus();
        $organized_menus = $menu_data['organized'];
        $available_menus = $menu_data['available'];

        // Add selected items that might not be in $available_menus (hidden items)
        $all_selected = $default_items;
        foreach ($role_settings as $role_items) {
            if (is_string($role_items)) {
                $all_selected = array_merge($all_selected, explode(',', $role_items));
            }
        }
        $all_selected = array_unique(array_filter($all_selected));

        foreach ($all_selected as $selected_slug) {
            if (empty($selected_slug)) continue;

            $found = false;
            foreach ($organized_menus as $category => $menus) {
                if (isset($menus[$selected_slug])) {
                    $found = true;
                    break;
                }
            }

            if (!$found) {
                $title = $available_menus[$selected_slug] ?? ucwords(str_replace(['-', '_', '.php'], ' ', $selected_slug));
                $plugin_menu_key = esc_html__('Plugin Menus & Custom Post Types', 'wpswitchboard');
                if (!isset($organized_menus[$plugin_menu_key])) {
                    $organized_menus[$plugin_menu_key] = [];
                }
                $organized_menus[$plugin_menu_key][$selected_slug] = $title;
            }
        }
        ?>
        <style>
            .sb-role-tabs {
                display: flex;
                flex-wrap: wrap;
                gap: 8px;
                margin-bottom: 24px;
                padding: 4px;
                background: #f0f0f1;
                border-radius: 8px;
            }
            .sb-role-tab {
                padding: 8px 14px;
                background: transparent;
                border: none;
                border-radius: 6px;
                cursor: pointer;
                font-size: 13px;
                font-weight: 500;
                color: #50575e;
                transition: all 0.15s ease;
                display: inline-flex;
                align-items: center;
                gap: 6px;
            }
            .sb-role-tab:hover {
                background: rgba(255, 255, 255, 0.6);
                color: #1d2327;
            }
            .sb-role-tab.active {
                background: #fff;
                color: #1d2327;
                box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
            }
            .sb-role-tab .sb-tab-count {
                display: inline-flex;
                align-items: center;
                justify-content: center;
                min-width: 20px;
                height: 20px;
                background: #dcdcde;
                color: #50575e;
                font-size: 11px;
                font-weight: 600;
                padding: 0 6px;
                border-radius: 10px;
            }
            .sb-role-tab.active .sb-tab-count {
                background: #3b82f6;
                color: #fff;
            }
            .sb-role-tab:hover:not(.active) .sb-tab-count {
                background: #c3c4c7;
            }
            .sb-role-content {
                display: none;
            }
            .sb-role-content.active {
                display: block;
            }
        </style>

        <input type="hidden" name="module" value="hide-admin-menu-items">
        <input type="hidden" name="setting_menu_items" id="setting_menu_items" value="<?php echo esc_attr(implode(',', $default_items)); ?>">
        <?php foreach ($roles as $role_slug => $role_name):
            $role_items = isset($role_settings[$role_slug]) ? explode(',', $role_settings[$role_slug]) : [];
            $role_items = array_filter(array_map('trim', $role_items));
        ?>
            <input type="hidden" name="setting_role_menu_items[<?php echo esc_attr($role_slug); ?>]"
                   id="setting_role_<?php echo esc_attr($role_slug); ?>"
                   value="<?php echo esc_attr(implode(',', $role_items)); ?>">
        <?php endforeach; ?>

        <div class="sb-sp-info-box sb-sp-info-box-info" style="margin-bottom: 24px;">
            <h4 class="sb-sp-heading-sm"><?php esc_html_e('How It Works', 'wpswitchboard'); ?></h4>
            <p class="sb-sp-description" style="margin: 0;"><?php esc_html_e('Hide menu items globally or per user role. The "All Users" tab sets the default for everyone. Role-specific tabs override the default for that role. Leave a role empty to use the default settings.', 'wpswitchboard'); ?></p>
        </div>

        <!-- Role Tabs -->
        <div class="sb-role-tabs">
            <div class="sb-role-tab active" data-role="default">
                <?php esc_html_e('All Users', 'wpswitchboard'); ?>
                <span class="sb-tab-count" id="count-default"><?php echo count($default_items); ?></span>
            </div>
            <?php foreach ($roles as $role_slug => $role_name):
                $role_items = isset($role_settings[$role_slug]) ? explode(',', $role_settings[$role_slug]) : [];
                $role_items = array_filter(array_map('trim', $role_items));
            ?>
                <div class="sb-role-tab" data-role="<?php echo esc_attr($role_slug); ?>">
                    <?php echo esc_html(translate_user_role($role_name)); ?>
                    <span class="sb-tab-count" id="count-<?php echo esc_attr($role_slug); ?>"><?php echo count($role_items); ?></span>
                </div>
            <?php endforeach; ?>
        </div>

        <!-- All Users (Default) Content -->
        <div class="sb-role-content active" data-role="default">
            <div class="sb-sp-group" style="margin-bottom: 24px;">
                <h3 class="sb-sp-heading"><?php esc_html_e('Menu Items to Hide for All Users', 'wpswitchboard'); ?></h3>
                <p class="sb-sp-description" style="margin-bottom: 12px;"><?php esc_html_e('These items will be hidden for all users unless a role-specific setting overrides it.', 'wpswitchboard'); ?></p>

                <?php $this->render_menu_selector('default', $default_items, $organized_menus); ?>
            </div>
        </div>

        <!-- Role-Specific Content -->
        <?php foreach ($roles as $role_slug => $role_name):
            $role_items = isset($role_settings[$role_slug]) ? explode(',', $role_settings[$role_slug]) : [];
            $role_items = array_filter(array_map('trim', $role_items));
        ?>
            <div class="sb-role-content" data-role="<?php echo esc_attr($role_slug); ?>">
                <div class="sb-sp-group" style="margin-bottom: 24px;">
                    <h3 class="sb-sp-heading">
                        <?php printf(esc_html__('Menu Items to Hide for %s', 'wpswitchboard'), esc_html(translate_user_role($role_name))); ?>
                    </h3>
                    <p class="sb-sp-description" style="margin-bottom: 12px;">
                        <?php if (empty($role_items)): ?>
                            <span style="color: #d63638;"><?php esc_html_e('Not configured - using "All Users" settings.', 'wpswitchboard'); ?></span>
                        <?php else: ?>
                            <?php esc_html_e('These settings override the "All Users" default for this role.', 'wpswitchboard'); ?>
                        <?php endif; ?>
                    </p>

                    <?php $this->render_menu_selector($role_slug, $role_items, $organized_menus); ?>

                    <?php if (!empty($role_items)): ?>
                        <button type="button" class="button sb-clear-role-btn" data-role="<?php echo esc_attr($role_slug); ?>" style="margin-top: 12px;">
                            <?php esc_html_e('Clear & Use Default', 'wpswitchboard'); ?>
                        </button>
                    <?php endif; ?>
                </div>
            </div>
        <?php endforeach; ?>

        <div class="sb-sp-info-box sb-sp-info-box-tip">
            <h4 class="sb-sp-heading-sm"><?php esc_html_e('Important Notes', 'wpswitchboard'); ?></h4>
            <ul class="sb-sp-list">
                <li class="sb-sp-list-item"><?php esc_html_e('Hidden menu items are still accessible via direct URL', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Role-specific settings completely override the default (not additive)', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Users with multiple roles use the first matching role setting', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Plugin menus and custom post types are automatically detected', 'wpswitchboard'); ?></li>
            </ul>
        </div>

        <script>
        jQuery(document).ready(function($) {
            // Tab switching
            $('.sb-role-tab').on('click', function() {
                var role = $(this).data('role');

                $('.sb-role-tab').removeClass('active');
                $(this).addClass('active');

                $('.sb-role-content').removeClass('active');
                $('.sb-role-content[data-role="' + role + '"]').addClass('active');
            });

            // Update counts when tags change
            function updateCounts() {
                // Default count
                var defaultVal = $('#setting_menu_items').val();
                var defaultCount = defaultVal ? defaultVal.split(',').filter(Boolean).length : 0;
                $('#count-default').text(defaultCount);

                // Role counts
                $('input[name^="setting_role_menu_items"]').each(function() {
                    var role = $(this).attr('id').replace('setting_role_', '');
                    var val = $(this).val();
                    var count = val ? val.split(',').filter(Boolean).length : 0;
                    $('#count-' + role).text(count);
                });
            }

            // Clear role button
            $('.sb-clear-role-btn').on('click', function() {
                var role = $(this).data('role');
                var $input = $('#setting_role_' + role);
                var $container = $('.sb-role-content[data-role="' + role + '"]');

                // Clear the hidden input
                $input.val('');

                // Clear selected tags
                $container.find('.switchboard-selected-tags').empty();

                // Unselect all tag options
                $container.find('.switchboard-tag-option').removeClass('selected');

                // Update count
                $('#count-' + role).text('0');

                // Update description
                $container.find('.sb-sp-description').first().html('<span style="color: #d63638;"><?php echo esc_js(__('Not configured - using "All Users" settings.', 'wpswitchboard')); ?></span>');

                // Hide the clear button
                $(this).hide();
            });

            // Watch for changes to update counts
            $(document).on('click', '.switchboard-tag-option, .remove-tag', function() {
                setTimeout(updateCounts, 100);
            });
        });
        </script>
        <?php
    }

    /**
     * Render menu selector for a specific role
     */
    private function render_menu_selector($role_key, $selected_items, $organized_menus) {
        $input_id = $role_key === 'default' ? 'setting_menu_items' : 'setting_role_' . $role_key;
        ?>
        <div class="switchboard-tag-selector" data-input-id="<?php echo esc_attr($input_id); ?>">
            <div class="switchboard-selected-tags" id="selected-<?php echo esc_attr($role_key); ?>">
                <?php foreach ($selected_items as $menu_slug):
                    if (!empty($menu_slug)):
                        $menu_title = $menu_slug;
                        foreach ($organized_menus as $menus) {
                            if (isset($menus[$menu_slug])) {
                                $menu_title = $menus[$menu_slug];
                                break;
                            }
                        } ?>
                        <span class="switchboard-tag" data-value="<?php echo esc_attr($menu_slug); ?>">
                            <?php echo esc_html($menu_title); ?> <span class="remove-tag">×</span>
                        </span>
                <?php endif; endforeach; ?>
            </div>
            <div class="switchboard-available-tags">
                <?php foreach ($organized_menus as $category => $menus): ?>
                    <div class="switchboard-menu-separator"><?php echo esc_html($category); ?></div>
                    <?php foreach ($menus as $menu_slug => $menu_title):
                        $is_selected = in_array($menu_slug, $selected_items) ? 'selected' : ''; ?>
                        <span class="switchboard-tag-option <?php echo $is_selected; ?>" data-value="<?php echo esc_attr($menu_slug); ?>">
                            <?php echo esc_html($menu_title); ?>
                        </span>
                    <?php endforeach; ?>
                <?php endforeach; ?>
            </div>
        </div>
        <?php
    }

    public function hide_menu_items() {
        $settings = get_option('switchboard_hide-admin-menu-items_settings', []);

        // Get current user's roles
        $current_user = wp_get_current_user();
        $user_roles = $current_user->roles;

        // Check for role-specific settings first
        $hidden_items = [];
        $role_settings = isset($settings['role_menu_items']) && is_array($settings['role_menu_items'])
            ? $settings['role_menu_items']
            : [];

        // Find the first matching role with explicit settings
        $using_role_settings = false;
        foreach ($user_roles as $role) {
            if (isset($role_settings[$role]) && !empty($role_settings[$role])) {
                $hidden_items = explode(',', $role_settings[$role]);
                $using_role_settings = true;
                break;
            }
        }

        // Fall back to default (all users) settings if no role-specific settings
        if (!$using_role_settings) {
            $hidden_items = isset($settings['menu_items']) && is_string($settings['menu_items'])
                ? explode(',', $settings['menu_items'])
                : [];
        }

        $hidden_items = array_filter(array_map('trim', $hidden_items));

        global $menu;

        if (empty($hidden_items) || !is_array($menu)) {
            return;
        }

        // Always keep Switchboard accessible to prevent admin lockout
        $protected_slugs = ['admin.php?page=switchboard'];

        foreach ($menu as $key => $item) {
            if (isset($item[2]) && in_array($item[2], $hidden_items, true) && !in_array($item[2], $protected_slugs, true)) {
                remove_menu_page($item[2]);
            }
        }
    }
}

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