<?php
/**
 * Name: Login ID Type Restriction
 * Description: Restrict login authentication to username only or email only to improve security and prevent users from logging in with alternative credentials they might forget
 * Category: Security
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "Simplify Login Process",
 *     "description": "Let users choose whether to log in with username, email, or both based on what works best for your site."
 *   },
 *   {
 *     "title": "Improve Security",
 *     "description": "Restrict login to username-only to prevent email enumeration attacks and make brute force attempts harder."
 *   }
 * ]
 * Added: 2025-06-25
 * Tags: login, username, email, security, authentication
 * WhereToFind: {
 *   "location": "Configure in module settings",
 *   "url": "",
 *   "instructions": "Choose username-only, email-only, or both - enforced at login",
 *   "newTab": false
 * }
 */

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

class SwitchboardLoginIdType {

    public function __construct() {
        add_filter('authenticate', [$this, 'restrict_login_type'], 30, 3);
    }
    
    public function restrict_login_type($user, $username, $password) {
        if (empty($username)) {
            return $user;
        }
        
        $settings = get_option('switchboard_login-id-type_settings', []);
        $type = isset($settings['type']) ? $settings['type'] : 'both';
        
        if ($type === 'username_only' && is_email($username)) {
            return new WP_Error('invalid_login', esc_html__('Please login with your username, not email.', 'wpswitchboard'));
        }

        if ($type === 'email_only' && !is_email($username)) {
            return new WP_Error('invalid_login', esc_html__('Please login with your email address, not username.', 'wpswitchboard'));
        }
        
        return $user;
    }

    /**
     * Render settings panel for Login ID Type Restriction
     * 
     * Displays settings interface for controlling login authentication method with:
     * - Three styled radio button options (both, username only, email only)
     * - Visual header with icon and description
     * - Inline CSS for hover effects and active state styling
     * - Custom border colors based on selected option
     * 
     * This module restricts how users can authenticate to WordPress by enforcing
     * login restrictions at the authentication level. It uses the WordPress 'authenticate'
     * filter to intercept login attempts and reject them if they don't match the
     * configured ID type. The interface provides three options: allow both username
     * and email (default WordPress behavior), restrict to username only (blocks email
     * login and prevents email enumeration), or restrict to email only (useful for
     * email-centric workflows).
     * 
     * The UI uses modern card-style radio buttons with blue accent colors, dynamic
     * border highlighting, and hover effects implemented via inline CSS. The checked()
     * WordPress function is used to determine the active radio button based on the
     * stored 'type' setting value.
     * 
     * @param array $settings Current module settings with 'type' key (both/username_only/email_only)
     * @return void Outputs HTML directly
     */
    public function render_settings($settings = []) {
        $type = isset($settings['type']) ? $settings['type'] : 'both';
        ?>
        <input type="hidden" name="module" value="login-id-type">

        <div class="sb-sp-group" style="margin-bottom: 24px;">
            <h3 class="sb-sp-heading"><?php esc_html_e('Login ID Type', 'wpswitchboard'); ?></h3>
            <p class="sb-sp-description"><?php esc_html_e('Control how users authenticate to your WordPress site', 'wpswitchboard'); ?></p>
        </div>

        <div style="display: flex; flex-direction: column; gap: 12px; margin-bottom: 24px;">
            <label class="sb-sp-card" style="cursor: pointer; padding: 16px; border: 2px solid <?php echo $type === 'both' ? 'var(--primary-500)' : '#e5e7eb'; ?>; transition: all 0.2s ease; <?php echo $type === 'both' ? 'background: var(--primary-50);' : ''; ?>; margin: 0;" onmouseover="if(this.querySelector('input[type=radio]').checked === false) { this.style.borderColor='var(--primary-500)'; this.style.backgroundColor='var(--primary-50)'; }" onmouseout="if(this.querySelector('input[type=radio]').checked === false) { this.style.borderColor='#e5e7eb'; this.style.backgroundColor=''; }">
                <div style="display: flex; align-items: flex-start; gap: 12px;">
                    <input type="radio" name="setting_type" value="both" <?php checked($type, 'both'); ?> style="margin-top: 2px; cursor: pointer;" onchange="document.querySelectorAll('.sb-sp-card').forEach(c => { c.style.borderColor='#e5e7eb'; c.style.backgroundColor=''; }); this.closest('.sb-sp-card').style.borderColor='var(--primary-500)'; this.closest('.sb-sp-card').style.backgroundColor='var(--primary-50)';">
                    <div style="flex: 1;">
                        <strong class="sb-sp-text-semibold" style="display: block; margin-bottom: 4px; color: #111827;"><?php esc_html_e('Username or Email (Default)', 'wpswitchboard'); ?></strong>
                        <p class="sb-sp-description" style="margin: 0; font-size: 13px;"><?php esc_html_e('Users can log in using either their username or email address. Most flexible option.', 'wpswitchboard'); ?></p>
                    </div>
                </div>
            </label>

            <label class="sb-sp-card" style="cursor: pointer; padding: 16px; border: 2px solid <?php echo $type === 'username_only' ? 'var(--primary-500)' : '#e5e7eb'; ?>; transition: all 0.2s ease; <?php echo $type === 'username_only' ? 'background: var(--primary-50);' : ''; ?>; margin: 0;" onmouseover="if(this.querySelector('input[type=radio]').checked === false) { this.style.borderColor='var(--primary-500)'; this.style.backgroundColor='var(--primary-50)'; }" onmouseout="if(this.querySelector('input[type=radio]').checked === false) { this.style.borderColor='#e5e7eb'; this.style.backgroundColor=''; }">
                <div style="display: flex; align-items: flex-start; gap: 12px;">
                    <input type="radio" name="setting_type" value="username_only" <?php checked($type, 'username_only'); ?> style="margin-top: 2px; cursor: pointer;" onchange="document.querySelectorAll('.sb-sp-card').forEach(c => { c.style.borderColor='#e5e7eb'; c.style.backgroundColor=''; }); this.closest('.sb-sp-card').style.borderColor='var(--primary-500)'; this.closest('.sb-sp-card').style.backgroundColor='var(--primary-50)';">
                    <div style="flex: 1;">
                        <strong class="sb-sp-text-semibold" style="display: block; margin-bottom: 4px; color: #111827;"><?php esc_html_e('Username Only', 'wpswitchboard'); ?></strong>
                        <p class="sb-sp-description" style="margin: 0; font-size: 13px;"><?php esc_html_e('Users must log in with their username. Email addresses will not work for login.', 'wpswitchboard'); ?></p>
                    </div>
                </div>
            </label>

            <label class="sb-sp-card" style="cursor: pointer; padding: 16px; border: 2px solid <?php echo $type === 'email_only' ? 'var(--primary-500)' : '#e5e7eb'; ?>; transition: all 0.2s ease; <?php echo $type === 'email_only' ? 'background: var(--primary-50);' : ''; ?>; margin: 0;" onmouseover="if(this.querySelector('input[type=radio]').checked === false) { this.style.borderColor='var(--primary-500)'; this.style.backgroundColor='var(--primary-50)'; }" onmouseout="if(this.querySelector('input[type=radio]').checked === false) { this.style.borderColor='#e5e7eb'; this.style.backgroundColor=''; }">
                <div style="display: flex; align-items: flex-start; gap: 12px;">
                    <input type="radio" name="setting_type" value="email_only" <?php checked($type, 'email_only'); ?> style="margin-top: 2px; cursor: pointer;" onchange="document.querySelectorAll('.sb-sp-card').forEach(c => { c.style.borderColor='#e5e7eb'; c.style.backgroundColor=''; }); this.closest('.sb-sp-card').style.borderColor='var(--primary-500)'; this.closest('.sb-sp-card').style.backgroundColor='var(--primary-50)';">
                    <div style="flex: 1;">
                        <strong class="sb-sp-text-semibold" style="display: block; margin-bottom: 4px; color: #111827;"><?php esc_html_e('Email Only', 'wpswitchboard'); ?></strong>
                        <p class="sb-sp-description" style="margin: 0; font-size: 13px;"><?php esc_html_e('Users must log in with their email address. Usernames will not work for login. Better for email-based workflows.', 'wpswitchboard'); ?></p>
                    </div>
                </div>
            </label>
        </div>

        <div class="sb-sp-info-box sb-sp-info-box-info">
            <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('This module restricts how users can authenticate to WordPress by enforcing login restrictions at the authentication level. It intercepts login attempts and rejects them if they don\'t match the configured ID type.', 'wpswitchboard'); ?>
            </p>
        </div>
        <?php
    }

    /**
     * Register data locations for cleanup system
     *
     * @return array Data storage locations
     */
    public function register_data_locations() {
        return [
            'options' => [
                'switchboard_login-id-type_settings',
            ],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
        ];
    }
}

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