<?php
/**
 * Name: Redirect After Login
 * Description: Set custom redirect URL after user login to send users to specific pages like dashboard, profile, or custom welcome page based on role
 * Category: User Management
 * Icon: -
  * UseCases: [
 *   {
 *     "title": "Customized User Journey",
 *     "description": "Send users to specific pages after login based on their role - send customers to their account, admins to the dashboard."
 *   },
 *   {
 *     "title": "Better Onboarding",
 *     "description": "Guide new users to helpful pages or tutorials right after they log in for the first time."
 *   }
 * ]
 * Added: 2025-06-26
 * Tags: login, redirect, url, authentication, ux
 * WhereToFind: {
 *   "location": "Configure in module settings",
 *   "url": "",
 *   "instructions": "Set redirect URL - applied after successful login",
 *   "newTab": false
 * }
 */

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

class SwitchboardRedirectAfterLogin {

    public function __construct() {
        add_filter('login_redirect', [$this, 'custom_login_redirect'], 10, 3);
        
        // 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_redirect-after-login_settings'
            ],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
            'term_meta' => [],
            'transients' => []
        ];
    }

    /**
     * Render settings panel for Redirect After Login
     * 
     * Displays comprehensive login redirect configuration with:
     * - Mode selector dropdown (single URL vs role-based)
     * - Single URL mode: one redirect URL for all users
     * - Role-based mode: dynamic URL input for each WordPress role
     * - Example URLs section with common redirect destinations
     * - Security notice about internal URLs only
     * - jQuery for dynamic show/hide of mode sections
     * 
     * This module uses the WordPress login_redirect filter to customize where users
     * go after successful login. It supports two modes:
     * 
     * 1. Single URL: All users redirect to same URL (stored in 'redirect_url' setting)
     * 2. Role-Based: Each role gets own URL (stored as 'redirect_{role_slug}' settings)
     * 
     * Security features:
     * - Only internal URLs allowed (prevents open redirect vulnerabilities)
     * - Validates URLs start with '/' (relative) or home_url() (absolute internal)
     * - External URLs are rejected and WordPress default is used instead
     * 
     * The UI dynamically generates input fields for all registered WordPress roles
     * using wp_roles()->get_names(). jQuery handles mode switching to show/hide
     * the appropriate input sections.
     * 
     * @param array $settings Current module settings with 'mode', 'redirect_url', and 'redirect_{role}' keys
     * @return void Outputs HTML directly with inline CSS and jQuery
     */
    public function render_settings($settings = []) {
        $mode = isset($settings['mode']) ? $settings['mode'] : 'single';
        $redirect_url = isset($settings['redirect_url']) ? $settings['redirect_url'] : '';
        $allow_external = isset($settings['allow_external']) ? $settings['allow_external'] : '0';

        $all_roles = wp_roles()->get_names();
        ?>
        <input type="hidden" name="module" value="redirect-after-login">

        <div class="sb-sp-group" style="margin-bottom: 24px;">
            <h3 class="sb-sp-heading"><?php esc_html_e('Login Redirect Settings', 'wpswitchboard'); ?></h3>
            <p class="sb-sp-description"><?php esc_html_e('Control where users go after logging in via', 'wpswitchboard'); ?> <code>/wp-admin</code> <?php esc_html_e('or', 'wpswitchboard'); ?> <code>/wp-login.php</code></p>
        </div>

        <div class="sb-sp-group sb-sp-field-horizontal" style="margin-bottom: 24px;">
            <div class="sb-sp-field-horizontal-left">
                <label for="redirect_mode" class="sb-sp-label"><?php esc_html_e('Redirect Mode', 'wpswitchboard'); ?></label>
                <p class="sb-sp-description"><?php esc_html_e('Choose how to redirect users after login', 'wpswitchboard'); ?></p>
            </div>
            <select name="setting_mode" id="redirect_mode" class="sb-sp-select">
                <option value="single" <?php selected($mode, 'single'); ?>><?php esc_html_e('Single URL (all users)', 'wpswitchboard'); ?></option>
                <option value="role_based" <?php selected($mode, 'role_based'); ?>><?php esc_html_e('Role-Based (different URL per role)', 'wpswitchboard'); ?></option>
            </select>
        </div>

        <!-- Single URL Mode -->
        <div id="single_mode_settings" class="sb-sp-group sb-sp-field-horizontal" style="margin-bottom: 24px; <?php echo ($mode === 'single' ? '' : 'display: none;'); ?>">
            <div class="sb-sp-field-horizontal-left">
                <label for="setting_redirect_url" class="sb-sp-label"><?php esc_html_e('Redirect URL', 'wpswitchboard'); ?></label>
                <p class="sb-sp-description"><?php esc_html_e('All users will be redirected to this URL', 'wpswitchboard'); ?></p>
            </div>
            <input type="url" name="setting_redirect_url" id="setting_redirect_url" value="<?php echo esc_attr($redirect_url); ?>" class="sb-sp-input" placeholder="<?php echo esc_attr(home_url('/welcome')); ?>">
        </div>

        <!-- Role-Based Mode -->
        <div id="role_based_settings" class="sb-sp-group" style="margin-bottom: 24px; <?php echo ($mode === 'role_based' ? '' : 'display: none;'); ?>">
            <p class="sb-sp-description" style="margin-bottom: 16px;"><?php esc_html_e('Set a redirect URL for each role:', 'wpswitchboard'); ?></p>
            <div class="sb-sp-card sb-sp-p-4" style="display: flex; flex-direction: column; gap: 16px;">
                <?php foreach ($all_roles as $role_slug => $role_name):
                    $role_url = isset($settings['redirect_' . $role_slug]) ? $settings['redirect_' . $role_slug] : '';
                ?>
                    <div class="sb-sp-field-horizontal">
                        <div class="sb-sp-field-horizontal-left">
                            <label for="setting_redirect_<?php echo esc_attr($role_slug); ?>" class="sb-sp-label"><?php echo esc_html($role_name); ?></label>
                            <p class="sb-sp-description"><?php esc_html_e('Redirect URL for this role after login', 'wpswitchboard'); ?></p>
                        </div>
                        <input type="url" name="setting_redirect_<?php echo esc_attr($role_slug); ?>" id="setting_redirect_<?php echo esc_attr($role_slug); ?>" value="<?php echo esc_attr($role_url); ?>" placeholder="<?php echo esc_attr(home_url()); ?>" class="sb-sp-input">
                    </div>
                <?php endforeach; ?>
            </div>
            <p class="sb-sp-description" style="margin-top: 12px;"><?php esc_html_e('Leave empty to use WordPress default', 'wpswitchboard'); ?></p>
        </div>

        <div class="sb-sp-info-box sb-sp-info-box-tip" style="margin-bottom: 24px;">
            <h4 class="sb-sp-heading-sm"><?php esc_html_e('Example URLs', 'wpswitchboard'); ?></h4>
            <ul class="sb-sp-list">
                <li class="sb-sp-list-item"><code>/</code> - <?php esc_html_e('Homepage', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><code>/welcome</code> - <?php esc_html_e('Welcome page', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><code>/my-account</code> - <?php esc_html_e('User account page', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><code><?php echo esc_url(admin_url()); ?></code> - <?php esc_html_e('Admin dashboard', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><code><?php echo esc_url(admin_url('edit.php')); ?></code> - <?php esc_html_e('Posts list', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><code><?php echo esc_url(admin_url('profile.php')); ?></code> - <?php esc_html_e('User profile', 'wpswitchboard'); ?></li>
            </ul>
        </div>

        <div class="sb-sp-info-box sb-sp-info-box-info">
            <h4 class="sb-sp-heading-sm"><?php esc_html_e('Security', 'wpswitchboard'); ?></h4>
            <p class="sb-sp-description" style="margin: 0;"><?php esc_html_e('Only internal URLs (same site) are allowed. External URLs are not supported to prevent open redirect vulnerabilities.', 'wpswitchboard'); ?></p>
        </div>

        <script>
        jQuery(document).ready(function($) {
            $("#redirect_mode").on("change", function() {
                const mode = $(this).val();
                if (mode === "single") {
                    $("#single_mode_settings").show();
                    $("#role_based_settings").hide();
                } else {
                    $("#single_mode_settings").hide();
                    $("#role_based_settings").show();
                }
            });
        });
        </script>
        <?php
    }

    public function custom_login_redirect($redirect_to, $request, $user) {
        // Check if user object is valid
        if (is_wp_error($user) || !isset($user->roles)) {
            return $redirect_to;
        }

        $settings = get_option('switchboard_redirect-after-login_settings', []);
        $mode = isset($settings['mode']) ? $settings['mode'] : 'single';

        // Determine redirect URL based on mode
        $custom_url = '';

        if ($mode === 'role_based' && isset($user->roles[0])) {
            // Role-based redirect
            $user_role = $user->roles[0];
            $custom_url = isset($settings['redirect_' . $user_role]) ? $settings['redirect_' . $user_role] : '';
        } else {
            // Single URL for all users
            $custom_url = isset($settings['redirect_url']) ? $settings['redirect_url'] : '';
        }

        // If no custom URL set, use default
        if (empty($custom_url)) {
            return $redirect_to;
        }

        $custom_url = trim($custom_url);

        // SECURITY: Only allow internal URLs to prevent open redirect
        // Check if it's a relative path or starts with home URL
        if (strpos($custom_url, '/') === 0) {
            // Relative path - make it absolute
            return home_url($custom_url);
        } elseif (strpos($custom_url, home_url()) === 0) {
            // Already an absolute internal URL
            return esc_url_raw($custom_url);
        }

        // URL doesn't match criteria (external URL), use default
        return $redirect_to;
    }
}

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