<?php
/**
 * GGM Commerce Custom Roles
 *
 * Defines custom user roles for shop management with restricted WordPress admin access.
 * These roles provide granular control over who can access what within the commerce system.
 *
 * @package GGM_Commerce
 * @since 1.0.0
 */

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter

class GGM_Commerce_Roles {

    /**
     * Singleton instance
     * @var GGM_Commerce_Roles
     */
    private static $instance = null;

    /**
     * Role definitions with their capabilities
     * @var array
     */
    private static $roles = [
        'ggmc_shop_manager' => [
            'display_name' => 'Shop Manager',
            'capabilities' => [
                // WordPress core capabilities
                'read' => true,
                'upload_files' => true,
                'edit_posts' => false,
                'delete_posts' => false,
                'publish_posts' => false,

                // GGM Commerce base access
                'ggmc_access_dashboard' => true,

                // GGM Commerce capabilities - Full access
                'ggmc_manage_products' => true,
                'ggmc_create_products' => true,
                'ggmc_edit_products' => true,
                'ggmc_delete_products' => true,
                'ggmc_manage_inventory' => true,
                'ggmc_manage_pricing' => true,
                'ggmc_manage_orders' => true,
                'ggmc_process_orders' => true,
                'ggmc_manage_refunds' => true,
                'ggmc_manage_shipments' => true,
                'ggmc_view_customers' => true,
                'ggmc_edit_customers' => true,
                'ggmc_manage_reviews' => true,
                'ggmc_view_reports' => true,
                'ggmc_manage_categories' => true,
                'ggmc_manage_attributes' => true,
                'ggmc_manage_variations' => true,

                // GGM Commerce settings access (limited)
                'ggmc_access_settings' => true,
                'ggmc_access_business_settings' => true,
                'ggmc_access_tax_settings' => true,
                'ggmc_access_shipping_settings' => true,
                'ggmc_access_currency_settings' => true,
                'ggmc_access_email_settings' => true,
                'ggmc_access_pages_settings' => false,
                'ggmc_access_widget_settings' => false,
                'ggmc_access_address_settings' => true,
                'ggmc_access_ai_settings' => false,
                'ggmc_access_payment_settings' => true,
                'ggmc_access_checkout_fields' => true,
                'ggmc_access_premium_settings' => false,
                'ggmc_access_google_merchant' => true,
            ],
        ],
        'ggmc_shop_staff' => [
            'display_name' => 'Shop Staff',
            'capabilities' => [
                // WordPress core capabilities
                'read' => true,
                'upload_files' => false,
                'edit_posts' => false,
                'delete_posts' => false,
                'publish_posts' => false,

                // GGM Commerce base access
                'ggmc_access_dashboard' => true,

                // GGM Commerce capabilities - Order processing focus
                'ggmc_manage_products' => false,
                'ggmc_create_products' => false,
                'ggmc_edit_products' => false,
                'ggmc_delete_products' => false,
                'ggmc_manage_inventory' => true,  // Can update stock levels
                'ggmc_manage_pricing' => false,
                'ggmc_manage_orders' => true,
                'ggmc_process_orders' => true,
                'ggmc_manage_refunds' => false,   // Cannot issue refunds
                'ggmc_manage_shipments' => true,
                'ggmc_view_customers' => true,
                'ggmc_edit_customers' => false,
                'ggmc_manage_reviews' => false,   // Can only flag reviews
                'ggmc_flag_reviews' => true,
                'ggmc_view_reports' => false,
                'ggmc_manage_categories' => false,
                'ggmc_manage_attributes' => false,
                'ggmc_manage_variations' => false,

                // No settings access
                'ggmc_access_settings' => false,
            ],
        ],
        'ggmc_inventory_manager' => [
            'display_name' => 'Inventory Manager',
            'capabilities' => [
                // WordPress core capabilities
                'read' => true,
                'upload_files' => true,
                'edit_posts' => false,
                'delete_posts' => false,
                'publish_posts' => false,

                // GGM Commerce base access
                'ggmc_access_dashboard' => true,

                // GGM Commerce capabilities - Inventory focus
                'ggmc_manage_products' => true,   // Can view products
                'ggmc_create_products' => false,
                'ggmc_edit_products' => true,     // Can edit product details
                'ggmc_delete_products' => false,
                'ggmc_manage_inventory' => true,
                'ggmc_manage_pricing' => false,   // Cannot change prices
                'ggmc_manage_orders' => false,    // View only for stock context
                'ggmc_view_orders' => true,
                'ggmc_process_orders' => false,
                'ggmc_manage_refunds' => false,
                'ggmc_manage_shipments' => false,
                'ggmc_view_customers' => false,
                'ggmc_edit_customers' => false,
                'ggmc_manage_reviews' => false,
                'ggmc_view_reports' => true,      // Inventory reports
                'ggmc_manage_categories' => true, // Can organize products
                'ggmc_manage_attributes' => true,
                'ggmc_manage_variations' => true,

                // No settings access
                'ggmc_access_settings' => false,
            ],
        ],
    ];

    /**
     * GGM Commerce settings tabs and required capabilities
     * @var array
     */
    private static $settings_tabs = [
        'business' => 'ggmc_access_business_settings',
        'tax' => 'ggmc_access_tax_settings',
        'shipping' => 'ggmc_access_shipping_settings',
        'currency' => 'ggmc_access_currency_settings',
        'email' => 'ggmc_access_email_settings',
        'pages' => 'ggmc_access_pages_settings',
        'widget-controls' => 'ggmc_access_widget_settings',
        'address-settings' => 'ggmc_access_address_settings',
        'ai-integration' => 'ggmc_access_ai_settings',
        'checkout-fields' => 'ggmc_access_checkout_fields',
        'payment' => 'ggmc_access_payment_settings',
        'subscriptions' => 'ggmc_access_payment_settings',
        'premium-components' => 'ggmc_access_premium_settings',
        'google-merchant' => 'ggmc_access_google_merchant',
        'legal' => 'manage_options',  // Admin only
        'transaction-export' => 'manage_options',  // Admin only
        'test-data' => 'manage_options',  // Admin only
        'user-roles' => 'manage_options', // Admin only
    ];

    /**
     * Get singleton instance
     */
    public static function instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor
     */
    private function __construct() {
        // Only run on admin
        if (!is_admin()) {
            return;
        }

        // Filter admin menu for custom roles
        add_action('admin_menu', [$this, 'filter_admin_menu'], 999);

        // Filter admin bar for custom roles
        add_action('admin_bar_menu', [$this, 'filter_admin_bar'], 999);

        // Redirect unauthorized access
        add_action('admin_init', [$this, 'redirect_unauthorized_access']);

        // Add custom dashboard for shop roles
        add_action('wp_dashboard_setup', [$this, 'setup_shop_dashboard'], 999);

        // Filter settings tabs based on capabilities
        add_filter('ggmc_settings_allowed_tabs', [$this, 'filter_settings_tabs']);

        // Add custom body class for styling
        add_filter('admin_body_class', [$this, 'add_admin_body_class']);
    }

    /**
     * Roles version - increment when capabilities change
     */
    private static $roles_version = '1.1';

    /**
     * Register custom roles on plugin activation
     */
    public static function register_roles() {
        foreach (self::$roles as $role_slug => $role_data) {
            // Remove existing role first (to update capabilities)
            remove_role($role_slug);

            // Add the role with capabilities
            add_role(
                $role_slug,
                $role_data['display_name'],
                $role_data['capabilities']
            );
        }

        // Also add our custom capabilities to administrator
        $admin_role = get_role('administrator');
        if ($admin_role) {
            foreach (self::get_all_capabilities() as $cap) {
                $admin_role->add_cap($cap);
            }
        }
    }

    /**
     * Remove custom roles on plugin deactivation (optional)
     */
    public static function remove_roles() {
        foreach (array_keys(self::$roles) as $role_slug) {
            remove_role($role_slug);
        }
    }

    /**
     * Get all GGM Commerce capabilities
     */
    public static function get_all_capabilities() {
        $caps = [];
        foreach (self::$roles as $role_data) {
            foreach (array_keys($role_data['capabilities']) as $cap) {
                if (strpos($cap, 'ggmc_') === 0) {
                    $caps[] = $cap;
                }
            }
        }
        return array_unique($caps);
    }

    /**
     * Check if current user has a GGM Commerce role
     */
    public static function is_ggmc_user() {
        $user = wp_get_current_user();
        $ggmc_roles = array_keys(self::$roles);
        return !empty(array_intersect($ggmc_roles, $user->roles));
    }

    /**
     * Get current user's GGM Commerce role
     */
    public static function get_user_ggmc_role() {
        $user = wp_get_current_user();
        $ggmc_roles = array_keys(self::$roles);
        $intersection = array_intersect($ggmc_roles, $user->roles);
        return !empty($intersection) ? reset($intersection) : null;
    }

    /**
     * Filter admin menu for custom roles
     */
    public function filter_admin_menu() {
        if (!self::is_ggmc_user()) {
            return;
        }

        global $menu, $submenu;

        // Menu items to keep for shop roles
        $allowed_menus = [
            'index.php',                    // Dashboard
            'upload.php',                   // Media (if they can upload)
            'admin.php?page=ggmc-plugin',   // GGM Commerce main
            'ggmc-plugin',                  // GGM Commerce
            'profile.php',                  // Profile
        ];

        // Remove all menus except allowed ones
        if (!empty($menu)) {
            foreach ($menu as $key => $item) {
                $menu_slug = $item[2] ?? '';

                // Check if this menu should be visible
                $keep = false;
                foreach ($allowed_menus as $allowed) {
                    if ($menu_slug === $allowed || strpos($menu_slug, 'ggmc') !== false) {
                        $keep = true;
                        break;
                    }
                }

                // Check upload capability
                if ($menu_slug === 'upload.php' && !current_user_can('upload_files')) {
                    $keep = false;
                }

                if (!$keep) {
                    remove_menu_page($menu_slug);
                }
            }
        }

        // Filter GGM Commerce submenus based on capabilities
        $this->filter_ggmc_submenus();
    }

    /**
     * Filter GGM Commerce submenus based on user capabilities
     */
    private function filter_ggmc_submenus() {
        global $submenu;

        if (!isset($submenu['ggmc-plugin'])) {
            return;
        }

        $user_role = self::get_user_ggmc_role();
        if (!$user_role || !isset(self::$roles[$user_role])) {
            return;
        }

        $caps = self::$roles[$user_role]['capabilities'];

        // Define which submenus require which capabilities
        $submenu_caps = [
            'ggmc-products' => 'ggmc_manage_products',
            'ggmc-orders' => 'ggmc_manage_orders',
            'ggmc-customers' => 'ggmc_view_customers',
            'ggmc-inventory' => 'ggmc_manage_inventory',
            'ggmc-reports' => 'ggmc_view_reports',
            'ggmc-settings' => 'ggmc_access_settings',
        ];

        foreach ($submenu['ggmc-plugin'] as $key => $item) {
            $page_slug = $item[2] ?? '';

            // Check if this submenu requires a capability
            foreach ($submenu_caps as $slug => $required_cap) {
                if (strpos($page_slug, $slug) !== false) {
                    if (empty($caps[$required_cap])) {
                        unset($submenu['ggmc-plugin'][$key]);
                    }
                    break;
                }
            }
        }
    }

    /**
     * Filter admin bar for custom roles
     */
    public function filter_admin_bar($wp_admin_bar) {
        if (!self::is_ggmc_user()) {
            return;
        }

        // Remove nodes that aren't relevant for shop roles
        $nodes_to_remove = [
            'comments',
            'new-content',
            'wp-logo',
            'updates',
            'customize',
            'themes',
            'widgets',
            'menus',
        ];

        foreach ($nodes_to_remove as $node) {
            $wp_admin_bar->remove_node($node);
        }

        // Keep only relevant items under 'new'
        $wp_admin_bar->remove_node('new-post');
        $wp_admin_bar->remove_node('new-page');
        $wp_admin_bar->remove_node('new-user');
    }

    /**
     * Redirect unauthorized admin page access
     */
    public function redirect_unauthorized_access() {
        if (!self::is_ggmc_user()) {
            return;
        }

        global $pagenow;

        // Pages that are always allowed
        $allowed_pages = [
            'index.php',
            'admin.php',
            'profile.php',
            'admin-ajax.php',
            'upload.php',
            'media-new.php',
            'async-upload.php',
        ];

        // Check if current page is allowed
        if (!in_array($pagenow, $allowed_pages, true)) {
            wp_safe_redirect(admin_url('admin.php?page=ggmc-plugin'));
            exit;
        }

        // For admin.php, check the page parameter
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a URL parameter check, not form processing
        if ($pagenow === 'admin.php' && isset($_GET['page'])) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $page = sanitize_text_field(wp_unslash($_GET['page']));

            // Allow all GGM Commerce pages
            if (strpos($page, 'ggmc') !== 0) {
                wp_safe_redirect(admin_url('admin.php?page=ggmc-plugin'));
                exit;
            }
        }
    }

    /**
     * Setup custom dashboard for shop roles
     */
    public function setup_shop_dashboard() {
        if (!self::is_ggmc_user()) {
            return;
        }

        // Remove default dashboard widgets
        $widgets_to_remove = [
            'dashboard_quick_press',
            'dashboard_primary',
            'dashboard_site_health',
            'dashboard_right_now',
            'dashboard_activity',
            'dashboard_incoming_links',
            'dashboard_plugins',
            'dashboard_recent_drafts',
            'dashboard_recent_comments',
            'dashboard_browser_nag',
        ];

        foreach ($widgets_to_remove as $widget) {
            remove_meta_box($widget, 'dashboard', 'normal');
            remove_meta_box($widget, 'dashboard', 'side');
        }

        // Add GGM Commerce dashboard widget
        wp_add_dashboard_widget(
            'ggmc_shop_dashboard',
            'Goose Commerce Overview',
            [$this, 'render_shop_dashboard_widget']
        );
    }

    /**
     * Render the shop dashboard widget
     */
    public function render_shop_dashboard_widget() {
        $user_role = self::get_user_ggmc_role();
        $caps = self::$roles[$user_role]['capabilities'] ?? [];

        echo '<div class="ggmc-dashboard-widget">';

        // Quick stats
        if (!empty($caps['ggmc_manage_orders'])) {
            $pending_orders = $this->get_pending_orders_count();
            echo '<div class="ggmc-stat">';
            echo '<span class="dashicons dashicons-cart"></span> ';
            echo '<strong>' . esc_html($pending_orders) . '</strong> pending orders';
            echo '</div>';
        }

        if (!empty($caps['ggmc_manage_inventory'])) {
            $low_stock = $this->get_low_stock_count();
            echo '<div class="ggmc-stat">';
            echo '<span class="dashicons dashicons-warning"></span> ';
            echo '<strong>' . esc_html($low_stock) . '</strong> low stock items';
            echo '</div>';
        }

        if (!empty($caps['ggmc_manage_reviews'])) {
            $pending_reviews = $this->get_pending_reviews_count();
            echo '<div class="ggmc-stat">';
            echo '<span class="dashicons dashicons-star-half"></span> ';
            echo '<strong>' . esc_html($pending_reviews) . '</strong> pending reviews';
            echo '</div>';
        }

        // Quick links
        echo '<div class="ggmc-quick-links" style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #ddd;">';
        echo '<strong>Quick Links:</strong><br>';

        if (!empty($caps['ggmc_manage_orders'])) {
            echo '<a href="' . esc_url(admin_url('admin.php?page=ggmc-orders')) . '">View Orders</a> | ';
        }
        if (!empty($caps['ggmc_manage_products'])) {
            echo '<a href="' . esc_url(admin_url('admin.php?page=ggmc-products')) . '">Manage Products</a> | ';
        }
        if (!empty($caps['ggmc_manage_inventory'])) {
            echo '<a href="' . esc_url(admin_url('admin.php?page=ggmc-inventory')) . '">Inventory</a>';
        }

        echo '</div>';
        echo '</div>';

        // Styles are in assets/css/admin.css
    }

    /**
     * Get count of pending orders
     */
    private function get_pending_orders_count() {
        global $wpdb;
        $table = $wpdb->prefix . 'ggmc_orders';

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM {$table} WHERE status IN (%s, %s)",
                'pending',
                'processing'
            )
        );
    }

    /**
     * Get count of low stock products
     */
    private function get_low_stock_count() {
        global $wpdb;
        $table = $wpdb->prefix . 'ggmc_products';
        $default_threshold = get_option('ggm_commerce_low_stock_threshold', 5);

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM {$table}
                WHERE track_stock = 1
                AND stock_quantity <= COALESCE(low_stock_threshold, %d)
                AND stock_quantity > 0",
                $default_threshold
            )
        );
    }

    /**
     * Get count of pending reviews
     */
    private function get_pending_reviews_count() {
        global $wpdb;
        $table = $wpdb->prefix . 'ggmc_reviews';

        // Check if table exists
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $table_exists = $wpdb->get_var(
            $wpdb->prepare(
                "SHOW TABLES LIKE %s",
                $table
            )
        );

        if (!$table_exists) {
            return 0;
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return (int) $wpdb->get_var(
            "SELECT COUNT(*) FROM {$table} WHERE status = 'pending'"
        );
    }

    /**
     * Filter settings tabs based on user capabilities
     */
    public function filter_settings_tabs($tabs) {
        if (current_user_can('manage_options')) {
            return $tabs; // Admin sees all
        }

        $filtered_tabs = [];
        foreach ($tabs as $tab) {
            $required_cap = self::$settings_tabs[$tab] ?? 'manage_options';
            if (current_user_can($required_cap)) {
                $filtered_tabs[] = $tab;
            }
        }

        return $filtered_tabs;
    }

    /**
     * Get allowed settings tabs for current user
     */
    public static function get_allowed_settings_tabs() {
        if (current_user_can('manage_options')) {
            return array_keys(self::$settings_tabs);
        }

        $allowed = [];
        foreach (self::$settings_tabs as $tab => $cap) {
            if (current_user_can($cap)) {
                $allowed[] = $tab;
            }
        }
        return $allowed;
    }

    /**
     * Check if user can access a specific settings tab
     */
    public static function can_access_tab($tab) {
        if (current_user_can('manage_options')) {
            return true;
        }

        $required_cap = self::$settings_tabs[$tab] ?? 'manage_options';
        return current_user_can($required_cap);
    }

    /**
     * Add admin body class for custom roles
     */
    public function add_admin_body_class($classes) {
        if (self::is_ggmc_user()) {
            $classes .= ' ggmc-shop-user';
            $role = self::get_user_ggmc_role();
            if ($role) {
                $classes .= ' ' . $role;
            }
        }
        return $classes;
    }

    /**
     * Get role definitions (for admin UI)
     */
    public static function get_roles() {
        return self::$roles;
    }

    /**
     * Get settings tab capabilities map
     */
    public static function get_settings_tabs_map() {
        return self::$settings_tabs;
    }

    /**
     * Check if custom roles feature is enabled
     */
    public static function is_enabled() {
        return get_option('ggmc_custom_roles_enabled', false);
    }

    /**
     * Enable custom roles
     */
    public static function enable() {
        update_option('ggmc_custom_roles_enabled', true);
        self::register_roles();
    }

    /**
     * Disable custom roles
     */
    public static function disable() {
        update_option('ggmc_custom_roles_enabled', false);
        // Note: We don't remove roles on disable, only on uninstall
        // This preserves user assignments
    }

    /**
     * Check if roles need updating and re-register if version changed
     */
    public static function maybe_update_roles() {
        $stored_version = get_option('ggmc_roles_version', '1.0');

        if (version_compare($stored_version, self::$roles_version, '<')) {
            self::register_roles();
            update_option('ggmc_roles_version', self::$roles_version);
        }
    }
}

// Initialize roles on admin
add_action('admin_init', function() {
    if (GGM_Commerce_Roles::is_enabled()) {
        // Check if roles need updating (version changed)
        GGM_Commerce_Roles::maybe_update_roles();
        GGM_Commerce_Roles::instance();
    }
});
