<?php

namespace FleekDash\Controllers;

use WP_REST_Request;
use WP_REST_Response;
use FleekDash\Services\ResponseService;

class LoginSettingsController extends BaseController
{
    const OPTION_PAGE_ID = 'fleekdash_login_page_id';
    const OPTION_TEMPLATE = 'fleekdash_login_template';
    const OPTION_SPLIT_POSITION = 'fleekdash_login_split_position';
    const OPTION_CUSTOM_ILLUSTRATION = 'fleekdash_login_custom_illustration';
    const OPTION_REMEMBER_ME_DEFAULT = 'fleekdash_login_remember_me_default';
    const OPTION_REMEMBER_ME_DURATION = 'fleekdash_login_remember_me_duration';
    const OPTION_DEMO_ENABLED = 'fleekdash_login_demo_enabled';
    const OPTION_DEMO_USER_ID = 'fleekdash_login_demo_user_id';
    const DEFAULT_REMEMBER_ME_DURATION = '2_weeks';

    /**
     * Get login settings
     *
     * @return WP_REST_Response
     */
    public function get_settings()
    {
        $page_id = \get_option(self::OPTION_PAGE_ID, 0);
        $template = \get_option(self::OPTION_TEMPLATE, 'split');
        $split_position = \get_option(self::OPTION_SPLIT_POSITION, 'right');
        $custom_illustration = \get_option(self::OPTION_CUSTOM_ILLUSTRATION, '');
        $remember_me_default = \get_option(self::OPTION_REMEMBER_ME_DEFAULT, false);
        $remember_me_duration = \get_option(self::OPTION_REMEMBER_ME_DURATION, self::DEFAULT_REMEMBER_ME_DURATION);
        $demo_enabled = \get_option(self::OPTION_DEMO_ENABLED, false);
        $demo_user_id = \get_option(self::OPTION_DEMO_USER_ID, 0);

        $page_data = null;
        if ($page_id) {
            $page = \get_post($page_id);
            if ($page) {
                $page_data = [
                    'id' => $page->ID,
                    'title' => $page->post_title,
                    'slug' => $page->post_name,
                    'permalink' => get_permalink($page->ID)
                ];
            }
        }

        $demo_user_data = null;
        if ($demo_user_id) {
            $user = \get_userdata($demo_user_id);
            if ($user) {
                $demo_user_data = [
                    'id' => $user->ID,
                    'display_name' => $user->display_name,
                    'user_email' => $user->user_email,
                    'user_login' => $user->user_login
                ];
            }
        }

        return ResponseService::success('Login settings retrieved', [
            'page_id' => (int)$page_id,
            'template' => $template,
            'split_position' => $split_position,
            'custom_illustration' => $custom_illustration,
            'remember_me_default' => (bool)$remember_me_default,
            'remember_me_duration' => $remember_me_duration,
            'demo_enabled' => (bool)$demo_enabled,
            'demo_user_id' => (int)$demo_user_id,
            'demo_user' => $demo_user_data,
            'page' => $page_data
        ]);
    }

    /**
     * Update login settings
     *
     * @param WP_REST_Request $request
     * @return WP_REST_Response
     */
    public function update_settings(WP_REST_Request $request)
    {
        $params = $request->get_json_params();

        $this->applyPageIdChange($params);
        $this->applySimpleOptions($params);
        $demo_error = $this->applyDemoUserOption($params);
        if ($demo_error !== null) {
            return $demo_error;
        }

        return ResponseService::success('Settings saved successfully');
    }

    /**
     * Handle page_id change: update option, clean old page, apply template to new page.
     *
     * @param array<string, mixed> $params
     */
    private function applyPageIdChange(array $params): void
    {
        if (!isset($params['page_id'])) {
            return;
        }
        $new_page_id = absint($params['page_id']);
        $old_page_id = \get_option(self::OPTION_PAGE_ID, 0);

        \update_option(self::OPTION_PAGE_ID, $new_page_id);

        if ($old_page_id && $old_page_id !== $new_page_id) {
            $old_template = \get_post_meta($old_page_id, '_wp_page_template', true);
            $is_login_template = $old_template === 'views/login-template.php' || $old_template === 'login-template.php';
            if ($is_login_template) {
                \delete_post_meta($old_page_id, '_wp_page_template');
            }
        }

        if ($new_page_id > 0) {
            $page = \get_post($new_page_id);
            if ($page && $page->post_type === 'page') {
                \update_post_meta($new_page_id, '_wp_page_template', 'login-template.php');
            }
        }
    }

    /**
     * Apply template, split_position, custom_illustration, remember_me options.
     *
     * @param array<string, mixed> $params
     */
    private function applySimpleOptions(array $params): void
    {
        if (isset($params['template'])) {
            $template = in_array($params['template'], ['split', 'standard'], true) ? $params['template'] : 'split';
            \update_option(self::OPTION_TEMPLATE, $template);
        }
        if (isset($params['split_position'])) {
            $position = in_array($params['split_position'], ['left', 'right'], true) ? $params['split_position'] : 'right';
            \update_option(self::OPTION_SPLIT_POSITION, $position);
        }
        if (isset($params['custom_illustration'])) {
            \update_option(self::OPTION_CUSTOM_ILLUSTRATION, sanitize_url($params['custom_illustration']));
        }
        if (isset($params['remember_me_default'])) {
            \update_option(self::OPTION_REMEMBER_ME_DEFAULT, (bool) $params['remember_me_default']);
        }
        if (isset($params['remember_me_duration'])) {
            $allowed = ['1_day', '1_week', self::DEFAULT_REMEMBER_ME_DURATION, '1_month', '3_months', '6_months', '1_year'];
            $duration = in_array($params['remember_me_duration'], $allowed, true) ? $params['remember_me_duration'] : self::DEFAULT_REMEMBER_ME_DURATION;
            \update_option(self::OPTION_REMEMBER_ME_DURATION, $duration);
        }
        if (isset($params['demo_enabled'])) {
            \update_option(self::OPTION_DEMO_ENABLED, (bool) $params['demo_enabled']);
        }
    }

    /**
     * Validate and apply demo_user_id option. Returns error (WP_Error) or null on success.
     *
     * @param array<string, mixed> $params
     * @return \WP_Error|null
     */
    private function applyDemoUserOption(array $params): ?\WP_Error
    {
        if (!isset($params['demo_user_id'])) {
            return null;
        }
        $demo_user_id = absint($params['demo_user_id']);

        if ($demo_user_id > 0) {
            $user = \get_userdata($demo_user_id);
            if (!$user || !user_can($user, 'manage_options')) {
                return ResponseService::error('Selected user does not have permission to access FleekDash', null, 400);
            }
        }

        \update_option(self::OPTION_DEMO_USER_ID, $demo_user_id);

        $demo_token = \get_option('fleekdash_login_demo_token');
        if (!$demo_token) {
            $demo_token = \bin2hex(\random_bytes(16));
            \update_option('fleekdash_login_demo_token', $demo_token);
        }

        return null;
    }

    /**
     * Search users for demo
     *
     * @param WP_REST_Request $request
     * @return WP_REST_Response
     */
    public function search_users(WP_REST_Request $request)
    {
        $search = $request->get_param('search');

        // Get roles that can access FleekDash
        // By default, we use 'manage_options' as the requirement for admin access
        $args = [
            'search' => '*' . $search . '*',
            'search_columns' => ['user_login', 'user_email', 'display_name'],
            'number' => 50, // Increase limit to filter more effectively
            'fields' => 'all',
            'capability' => 'read', // Base requirement
        ];

        $user_query = new \WP_User_Query($args);
        $users = [];

        foreach ($user_query->get_results() as $user) {
            // CRITICAL: Only include users who can actually access FleekDash
            // We check for 'manage_options' as a proxy for admin access,
            // or we could check for specific FleekDash capabilities if they exist.
            if (!user_can($user, 'manage_options')) {
                continue;
            }

            $avatar_url = get_avatar_url($user->ID, ['size' => 96]);
            $roles = $user->roles ?? [];
            $primary_role = !empty($roles) ? $roles[0] : 'subscriber';

            $users[] = [
                'id' => $user->ID,
                'display_name' => $user->display_name,
                'user_email' => $user->user_email,
                'user_login' => $user->user_login,
                'avatar_url' => $avatar_url,
                'roles' => $roles,
                'role' => $primary_role,
            ];

            // Limit to 20 results after filtering
            if (count($users) >= 20) {
                break;
            }
        }

        return ResponseService::success('Users retrieved', $users);
    }

    /**
     * Upload illustration
     *
     * @param WP_REST_Request $request
     * @return WP_REST_Response
     */
    public function upload_illustration(WP_REST_Request $request)
    {
        $error_response = null;
        if (!isset($_FILES['illustration'])) {
            $error_response = ResponseService::error('No file uploaded', null, 400);
        }
        if ($error_response === null) {
            $file = $_FILES['illustration'];
            $allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg+xml', 'image/webp'];
            $max_size = 5 * 1024 * 1024; // 5MB
            if (!in_array($file['type'], $allowed_types)) {
                $error_response = ResponseService::error('Invalid file type. Allowed: JPEG, PNG, SVG, WebP', null, 400);
            } elseif ($file['size'] > $max_size) {
                $error_response = ResponseService::error('File too large. Maximum size: 5MB', null, 400);
            }
        }
        if ($error_response !== null) {
            return $error_response;
        }

        $file = $_FILES['illustration'];
        if (!function_exists('wp_handle_upload')) {
            require_once ABSPATH . 'wp-admin/includes/image.php';
            require_once ABSPATH . 'wp-admin/includes/file.php';
            require_once ABSPATH . 'wp-admin/includes/media.php';
        }
        $upload_overrides = [
            'test_form' => false,
            'mimes' => [
                'jpg|jpeg' => 'image/jpeg',
                'png' => 'image/png',
                'svg' => 'image/svg+xml',
                'webp' => 'image/webp'
            ]
        ];
        $uploaded_file = wp_handle_upload($file, $upload_overrides);
        if (isset($uploaded_file['error']) || !isset($uploaded_file['url'])) {
            $msg = $uploaded_file['error'] ?? 'Failed to upload illustration';
            return ResponseService::error($msg, null, 500);
        }

        $attachment = [
            'guid' => $uploaded_file['url'],
            'post_mime_type' => $uploaded_file['type'],
            'post_title' => 'FleekDash Login Illustration',
            'post_content' => '',
            'post_status' => 'inherit'
        ];
        $attachment_id = \wp_insert_attachment($attachment, $uploaded_file['file']);
        if (!is_wp_error($attachment_id)) {
            $attachment_data = \wp_generate_attachment_metadata($attachment_id, $uploaded_file['file']);
            \wp_update_attachment_metadata($attachment_id, $attachment_data);
        }
        return ResponseService::success('Illustration uploaded successfully', ['url' => $uploaded_file['url']]);
    }

    /**
     * Search pages
     *
     * @param WP_REST_Request $request
     * @return WP_REST_Response
     */
    public function search_pages(WP_REST_Request $request)
    {
        $search = $request->get_param('search');

        $args = [
            'post_type' => 'page',
            'post_status' => 'publish',
            'posts_per_page' => 20,
            's' => $search
        ];

        $query = new \WP_Query($args);
        $pages = [];

        foreach ($query->posts as $post) {
            $pages[] = [
                'id' => $post->ID,
                'title' => $post->post_title,
                'slug' => $post->post_name,
                'permalink' => get_permalink($post->ID)
            ];
        }

        return ResponseService::success('Pages retrieved', $pages);
    }

    /**
     * Create a new login page
     *
     * @param WP_REST_Request $request
     * @return WP_REST_Response
     */
    public function create_page(WP_REST_Request $request)
    {
        $params = $request->get_json_params();
        $slug = sanitize_title($params['slug'] ?? 'login');
        $title = \sanitize_text_field($params['title'] ?? 'Login');

        $error = null;
        if (empty($slug)) {
            $error = ResponseService::error('Slug is required', null, 400);
        } elseif (get_page_by_path($slug)) {
            $error = ResponseService::error('Page with this slug already exists', null, 400);
        }
        if ($error !== null) {
            return $error;
        }

        $page_id = \wp_insert_post([
            'post_title' => $title,
            'post_name' => $slug,
            'post_type' => 'page',
            'post_status' => 'publish',
            'post_content' => '<!-- FleekDash Login Page -->'
        ]);
        $error = is_wp_error($page_id) ? ResponseService::error($page_id->get_error_message(), null, 500) : null;
        if ($error !== null) {
            return $error;
        }

        \update_post_meta($page_id, '_wp_page_template', 'login-template.php');
        \update_option(self::OPTION_PAGE_ID, $page_id);

        return ResponseService::success('Page created and selected successfully', [
            'id' => $page_id,
            'title' => $title,
            'slug' => $slug,
            'permalink' => get_permalink($page_id),
            'message' => 'Page created and selected successfully'
        ]);
    }
}
