<?php

declare(strict_types=1);

namespace WPUltimateSecurity\UltimateSecurity\Presentation\API\Controllers;

use WP_REST_Request;
use WP_REST_Response;
use WPUltimateSecurity\UltimateSecurity\Modules\Setup\SecurityWizard;
use WPUltimateSecurity\UltimateSecurity\Modules\Setup\SecurityProfiles;
use WPUltimateSecurity\UltimateSecurity\Infrastructure\Settings\SettingsRepository;

/**
 * Wizard REST API Controller
 *
 * Handles all wizard-related API endpoints:
 * - GET /wizard/scan - Run security scan
 * - GET /wizard/profiles - Get available profiles
 * - GET /wizard/status - Get wizard completion status
 * - POST /wizard/apply - Apply selected profile
 * - POST /wizard/undo - Undo wizard changes
 * - POST /wizard/skip - Skip the wizard
 */
class WizardController
{
    /**
     * Get wizard status
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function getStatus(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $status = SecurityWizard::getWizardStatus();
        $profileMeta = SecurityProfiles::getProfileMeta();

        // If a profile was applied, include its metadata
        if ($status['profile'] && isset($profileMeta[$status['profile']])) {
            $status['profile_info'] = $profileMeta[$status['profile']];
        }

        return new WP_REST_Response([
            'success' => true,
            'data' => $status,
        ], 200);
    }

    /**
     * Run security scan
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function runScan(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $results = SecurityWizard::runSecurityScan();

        return new WP_REST_Response([
            'success' => true,
            'data' => $results,
        ], 200);
    }

    /**
     * Get available security profiles
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function getProfiles(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $profileMeta = SecurityProfiles::getProfileMeta();
        $profiles = [];

        foreach ($profileMeta as $level => $meta) {
            $profiles[$level] = array_merge($meta, [
                'level' => $level,
                'settings_preview' => self::getSettingsPreview($level),
            ]);
        }

        return new WP_REST_Response([
            'success' => true,
            'data' => [
                'profiles' => $profiles,
                'recommended' => self::getRecommendedProfile(),
            ],
        ], 200);
    }

    /**
     * Get profile comparison with current settings
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function getProfileComparison(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $level = sanitize_text_field($request->get_param('level') ?? 'moderate');
        $comparison = SecurityWizard::getProfileComparison($level);
        $profileMeta = SecurityProfiles::getProfileMeta();

        if (!isset($profileMeta[$level])) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Invalid profile level.', 'ultimate-security'),
            ], 400);
        }

        // Count changes
        $willChange = array_filter($comparison, fn($item) => $item['will_change']);

        return new WP_REST_Response([
            'success' => true,
            'data' => [
                'profile' => $profileMeta[$level],
                'comparison' => $comparison,
                'changes_count' => count($willChange),
                'total_settings' => count($comparison),
            ],
        ], 200);
    }

    /**
     * Apply a security profile
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function applyProfile(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $level = sanitize_text_field($request->get_param('level') ?? '');

        if (empty($level)) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Profile level is required.', 'ultimate-security'),
            ], 400);
        }

        $validLevels = [
            SecurityProfiles::LEVEL_BASIC,
            SecurityProfiles::LEVEL_MODERATE,
            SecurityProfiles::LEVEL_STRICT,
        ];

        if (!in_array($level, $validLevels, true)) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Invalid profile level.', 'ultimate-security'),
            ], 400);
        }

        $result = SecurityWizard::applyProfile($level);

        return new WP_REST_Response($result, $result['success'] ? 200 : 500);
    }

    /**
     * Undo wizard changes
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function undoChanges(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $result = SecurityWizard::undoChanges();

        return new WP_REST_Response($result, $result['success'] ? 200 : 400);
    }

    /**
     * Skip the wizard
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function skipWizard(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        SecurityWizard::skipWizard();

        return new WP_REST_Response([
            'success' => true,
            'message' => __('Wizard has been skipped.', 'ultimate-security'),
        ], 200);
    }

    /**
     * Get recommended profile based on current site analysis
     *
     * @return string
     */
    private static function getRecommendedProfile(): string
    {
        // Basic heuristics for recommendation
        $isEcommerce = class_exists('WooCommerce');
        $isMembership = class_exists('MemberPress') || class_exists('Paid_Memberships_Pro');
        $isMultisite = is_multisite();
        $userCount = count_users()['total_users'] ?? 1;

        // Strict for e-commerce, membership sites, multisite, or many users
        if ($isEcommerce || $isMembership || $isMultisite || $userCount > 50) {
            return SecurityProfiles::LEVEL_STRICT;
        }

        // Moderate for sites with multiple users
        if ($userCount > 5) {
            return SecurityProfiles::LEVEL_MODERATE;
        }

        // Basic for small personal sites
        return SecurityProfiles::LEVEL_BASIC;
    }

    /**
     * Get preview of key settings for a profile
     *
     * @param string $level Profile level
     * @return array
     */
    private static function getSettingsPreview(string $level): array
    {
        $profile = SecurityProfiles::getProfile($level);
        if (!$profile) {
            return [];
        }

        $preview = [];

        // Extract key settings for preview
        $keySettings = [
            'password_length' => $profile['security']['password_policies']['min_length'] ?? null,
            'login_attempts' => $profile['security']['login_limit']['login_attempts'] ?? null,
            'lockout_duration' => $profile['security']['login_limit']['lockout_duration'] ?? null,
            '2fa_enabled' => isset($profile['security']['2fa_authentication']),
            'security_headers' => isset($profile['security_headers']['enable']) && $profile['security_headers']['enable'] === '1',
            'rate_limiting' => isset($profile['rate_limiter']['rate_limiting_enabled']) && $profile['rate_limiter']['rate_limiting_enabled'] === '1',
        ];

        foreach ($keySettings as $key => $value) {
            if ($value !== null) {
                $preview[$key] = $value;
            }
        }

        return $preview;
    }

    /**
     * Get 2FA wizard data
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function get2FAWizardData(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $settings = SettingsRepository::getInstance();
        $wizardData = $settings->get('ultimate_security_2fa_wizard', self::getDefault2FAWizardData());

        return new WP_REST_Response([
            'success' => true,
            'data' => $wizardData,
        ], 200);
    }

    /**
     * Update 2FA wizard data
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function update2FAWizardData(WP_REST_Request $request): WP_REST_Response
    {
        if (!current_user_can('manage_options')) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You do not have permission to access this resource.', 'ultimate-security'),
            ], 403);
        }

        $wizardData = $request->get_param('wizard_data');
        if (empty($wizardData) || !is_array($wizardData)) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Invalid wizard data.', 'ultimate-security'),
            ], 400);
        }

        // Sanitize and validate wizard data
        $sanitizedData = self::sanitize2FAWizardData($wizardData);

        // Save to database
        $settings = SettingsRepository::getInstance();
        $updated = $settings->set('ultimate_security_2fa_wizard', $sanitizedData);

        if ($updated) {
            return new WP_REST_Response([
                'success' => true,
                'message' => __('Wizard data saved successfully.', 'ultimate-security'),
                'data' => $sanitizedData,
            ], 200);
        } else {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Failed to save wizard data.', 'ultimate-security'),
            ], 500);
        }
    }

    /**
     * Get default 2FA wizard data
     *
     * @return array
     */
    private static function getDefault2FAWizardData(): array
    {
        return [
            'security_level' => 'recommended',
            'primary_method' => 'app',
            'selected_roles' => ['administrator'],
            'backup_codes_enabled' => true,
            'completed' => false,
            'created_at' => current_time('mysql'),
        ];
    }

    /**
     * Sanitize 2FA wizard data
     *
     * @param array $data Raw wizard data
     * @return array Sanitized wizard data
     */
    private static function sanitize2FAWizardData(array $data): array
    {
        $defaults = self::getDefault2FAWizardData();
        
        return [
            'security_level' => in_array($data['security_level'] ?? '', ['basic', 'recommended']) 
                ? sanitize_text_field($data['security_level']) 
                : $defaults['security_level'],
            'primary_method' => in_array($data['primary_method'] ?? '', ['app', 'email']) 
                ? sanitize_text_field($data['primary_method']) 
                : $defaults['primary_method'],
            'selected_roles' => isset($data['selected_roles']) && is_array($data['selected_roles'])
                ? array_map('sanitize_text_field', $data['selected_roles'])
                : $defaults['selected_roles'],
            'backup_codes_enabled' => isset($data['backup_codes_enabled']) 
                ? (bool) $data['backup_codes_enabled'] 
                : $defaults['backup_codes_enabled'],
            'completed' => isset($data['completed']) 
                ? (bool) $data['completed'] 
                : $defaults['completed'],
            'updated_at' => current_time('mysql'),
            'created_at' => $data['created_at'] ?? $defaults['created_at'],
        ];
    }
}
