<?php

/**
 * User Preferences REST API Controller.
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   0.1.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use ProRank\SEO\Core\UserPreferences;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use WP_REST_Server;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}


/**
 * User Preferences controller class.
 */


class UserPreferencesController extends BaseController {
    
    /**
     * Register routes.
     *
     * @return void
     */
    public function register_routes(): void {
        // Get all preferences
        register_rest_route(
            $this->namespace,
            '/user/preferences',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [$this, 'get_preferences'],
                    'permission_callback' => [$this, 'check_permission'],
                ],
                'schema' => [$this, 'get_preferences_schema'],
            ]
        );
        
        // Update preferences
        register_rest_route(
            $this->namespace,
            '/user/preferences',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [$this, 'update_preferences'],
                    'permission_callback' => [$this, 'check_permission'],
                    'args'                => $this->get_update_args(),
                ],
            ]
        );
        
        // Expert mode endpoint
        register_rest_route(
            $this->namespace,
            '/user/expert-mode',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [$this, 'get_expert_mode'],
                    'permission_callback' => [$this, 'check_permission'],
                ],
                [
                    'methods'             => 'POST',
                    'callback'            => [$this, 'set_expert_mode'],
                    'permission_callback' => [$this, 'check_permission'],
                    'args'                => [
                        'enabled' => [
                            'required'          => true,
                            'type'              => 'boolean',
                            'sanitize_callback' => 'rest_sanitize_boolean',
                        ],
                    ],
                ],
            ]
        );
        
        // Pinned modules endpoints
        register_rest_route(
            $this->namespace,
            '/user/pinned-modules',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [$this, 'get_pinned_modules'],
                    'permission_callback' => [$this, 'check_permission'],
                ],
                [
                    'methods'             => 'POST',
                    'callback'            => [$this, 'set_pinned_modules'],
                    'permission_callback' => [$this, 'check_permission'],
                    'args'                => [
                        'modules' => [
                            'required'          => true,
                            'type'              => 'array',
                            'items'             => [
                                'type' => 'string',
                            ],
                            'sanitize_callback' => function($modules) {
                                return array_map('sanitize_key', $modules);
                            },
                        ],
                    ],
                ],
            ]
        );
        
        // Toggle pinned module
        register_rest_route(
            $this->namespace,
            '/user/pinned-modules/toggle',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [$this, 'toggle_pinned_module'],
                    'permission_callback' => [$this, 'check_permission'],
                    'args'                => [
                        'module' => [
                            'required'          => true,
                            'type'              => 'string',
                            'sanitize_callback' => 'sanitize_key',
                        ],
                    ],
                ],
            ]
        );
    }
    
    /**
     * Get all user preferences.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function get_preferences(WP_REST_Request $request) {
        try {
            $preferences = UserPreferences::get_all();

            if (!is_array($preferences)) {
                $preferences = [];
            }
            
            // Add specific preferences if not set
            if (!isset($preferences['expert_mode'])) {
                $preferences['expert_mode'] = UserPreferences::is_expert_mode();
            }
            
            if (!isset($preferences['pinned_modules'])) {
                $preferences['pinned_modules'] = UserPreferences::get_pinned_modules();
            }
            
            return $this->success_response($preferences);
            
        } catch (\Exception $e) {
            return $this->success_response([
                'expert_mode' => false,
                'pinned_modules' => [],
            ]);
        }
    }
    
    /**
     * Update user preferences.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function update_preferences(WP_REST_Request $request) {
        try {
            $preferences = $request->get_param('preferences');
            $updated = [];

            if (!is_array($preferences)) {
                return $this->error_response(
                    __('Invalid preferences payload.', 'prorank-seo'),
                    'invalid_preferences',
                    400
                );
            }
            
            foreach ($preferences as $key => $value) {
                $full_key = '_prorank_' . sanitize_key($key);
                
                if (UserPreferences::set($full_key, $value)) {
                    $updated[$key] = $value;
                }
            }
            
            return $this->success_response([
                'updated' => $updated,
                'message' => __('Preferences updated successfully.', 'prorank-seo'),
            ]);
            
        } catch (\Exception $e) {
            return $this->error_response(
                __('Failed to update preferences.', 'prorank-seo'),
                'update_failed',
                500
            );
        }
    }
    
    /**
     * Get expert mode status.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function get_expert_mode(WP_REST_Request $request) {
        return $this->success_response([
            'enabled' => UserPreferences::is_expert_mode(),
        ]);
    }
    
    /**
     * Set expert mode status.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function set_expert_mode(WP_REST_Request $request) {
        $enabled = $request->get_param('enabled');
        
        if (UserPreferences::set_expert_mode($enabled)) {
            return $this->success_response([
                'enabled' => $enabled,
                'message' => $enabled 
                    ? __('Expert mode enabled.', 'prorank-seo')
                    : __('Expert mode disabled.', 'prorank-seo'),
            ]);
        }
        
        return $this->error_response(
            __('Failed to update expert mode.', 'prorank-seo'),
            'update_failed',
            500
        );
    }
    
    /**
     * Get pinned modules.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function get_pinned_modules(WP_REST_Request $request) {
        return $this->success_response([
            'modules' => UserPreferences::get_pinned_modules(),
        ]);
    }
    
    /**
     * Set pinned modules.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function set_pinned_modules(WP_REST_Request $request) {
        $modules = $request->get_param('modules');
        
        if (UserPreferences::set_pinned_modules($modules)) {
            return $this->success_response([
                'modules' => $modules,
                'message' => __('Pinned modules updated.', 'prorank-seo'),
            ]);
        }
        
        return $this->error_response(
            __('Failed to update pinned modules.', 'prorank-seo'),
            'update_failed',
            500
        );
    }
    
    /**
     * Toggle pinned module.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function toggle_pinned_module(WP_REST_Request $request) {
        $module = $request->get_param('module');
        $is_pinned = UserPreferences::toggle_pinned_module($module);
        
        return $this->success_response([
            'module'    => $module,
            'is_pinned' => $is_pinned,
            'modules'   => UserPreferences::get_pinned_modules(),
            'message'   => $is_pinned 
                ? __('Module pinned.', 'prorank-seo')
                : __('Module unpinned.', 'prorank-seo'),
        ]);
    }
    
    /**
     * Get update arguments.
     *
     * @return array Arguments definition.
     */
    private function get_update_args(): array {
        return [
            'preferences' => [
                'required'    => true,
                'type'        => 'object',
                'description' => __('Preferences to update.', 'prorank-seo'),
            ],
        ];
    }
    
    /**
     * Get preferences schema.
     *
     * @return array Schema definition.
     */
    public function get_preferences_schema(): array {
        return [
            '$schema'    => 'http://json-schema.org/draft-04/schema#',
            'title'      => 'user-preferences',
            'type'       => 'object',
            'properties' => [
                'expert_mode' => [
                    'description' => __('Whether expert mode is enabled.', 'prorank-seo'),
                    'type'        => 'boolean',
                ],
                'pinned_modules' => [
                    'description' => __('List of pinned module slugs.', 'prorank-seo'),
                    'type'        => 'array',
                    'items'       => [
                        'type' => 'string',
                    ],
                ],
            ],
        ];
    }
}
