<?php

/**
 * Presets 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\PresetManager;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

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


/**
 * Presets controller class.
 */


class PresetsController extends BaseController {
    
    /**
     * Preset Manager instance
     *
     * @var PresetManager
     */
    private PresetManager $preset_manager;
    
    /**
     * Constructor
     *
     * @param PresetManager $preset_manager Preset manager instance
     */
    public function __construct(PresetManager $preset_manager) {
        $this->preset_manager = $preset_manager;
    }
    
    /**
     * Register routes.
     *
     * @return void
     */
    public function register_routes(): void {
        // Get all presets
        register_rest_route(
            $this->namespace,
            '/presets',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [$this, 'get_presets'],
                    'permission_callback' => [$this, 'check_permission'],
                ],
                'schema' => [$this, 'get_presets_schema'],
            ]
        );
        
        // Get specific preset
        register_rest_route(
            $this->namespace,
            '/presets/(?P<preset>[a-zA-Z0-9_-]+)',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [$this, 'get_preset'],
                    'permission_callback' => [$this, 'check_permission'],
                    'args'                => [
                        'preset' => [
                            'required'          => true,
                            'type'              => 'string',
                            'sanitize_callback' => 'sanitize_key',
                        ],
                    ],
                ],
            ]
        );
        
        // Apply preset
        register_rest_route(
            $this->namespace,
            '/presets/apply/(?P<preset>[a-zA-Z0-9_-]+)',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [$this, 'apply_preset'],
                    'permission_callback' => [$this, 'check_admin_permission'],
                    'args'                => [
                        'preset' => [
                            'required'          => true,
                            'type'              => 'string',
                            'sanitize_callback' => 'sanitize_key',
                        ],
                    ],
                ],
            ]
        );
    }
    
    /**
     * Get all available presets.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function get_presets(WP_REST_Request $request) {
        try {
            $presets = $this->preset_manager->get_presets();
            
            return $this->success_response([
                'presets' => $presets,
                'total' => count($presets),
            ]);
            
        } catch (\Exception $e) {
            return $this->error_response(
                __('Failed to fetch presets.', 'prorank-seo'),
                'fetch_failed',
                500
            );
        }
    }
    
    /**
     * Get specific preset details.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function get_preset(WP_REST_Request $request) {
        $preset_name = $request->get_param('preset');
        
        try {
            $preset = $this->preset_manager->get_preset($preset_name);
            
            if (!$preset) {
                return $this->error_response(
                    __('Preset not found.', 'prorank-seo'),
                    'not_found',
                    404
                );
            }
            
            return $this->success_response([
                'preset' => [
                    'id' => $preset_name,
                    'name' => $preset['name'],
                    'description' => $preset['description'],
                    'icon' => $preset['icon'] ?? 'admin-generic',
                    'settings' => $preset['settings'],
                ],
            ]);
            
        } catch (\Exception $e) {
            return $this->error_response(
                __('Failed to fetch preset details.', 'prorank-seo'),
                'fetch_failed',
                500
            );
        }
    }
    
    /**
     * Apply a preset.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error Response object or error.
     */
    public function apply_preset(WP_REST_Request $request) {
        $preset_name = $request->get_param('preset');
        
        // Additional capability check
        if (!current_user_can('manage_options')) {
            return $this->error_response(
                __('You do not have permission to apply presets.', 'prorank-seo'),
                'insufficient_permissions',
                403
            );
        }
        
        try {
            // Check if preset exists
            $preset = $this->preset_manager->get_preset($preset_name);
            
            if (!$preset) {
                return $this->error_response(
                    __('Preset not found.', 'prorank-seo'),
                    'not_found',
                    404
                );
            }
            
            // Apply the preset
            $success = $this->preset_manager->apply_preset($preset_name);
            
            if (!$success) {
                return $this->error_response(
                    __('Failed to apply preset. Please try again.', 'prorank-seo'),
                    'apply_failed',
                    500
                );
            }
            
            return $this->success_response([
                'message' => sprintf(
                    /* translators: %s: preset name */
                    __('Successfully applied "%1$s" preset.', 'prorank-seo'),
                    $preset['name']
                ),
                'preset' => $preset_name,
                'settings_applied' => count($preset['settings']),
            ]);
            
        } catch (\Exception $e) {
            return $this->error_response(
                __('An error occurred while applying the preset.', 'prorank-seo'),
                'apply_error',
                500
            );
        }
    }
    
    /**
     * Check admin permission.
     *
     * @return bool True if user has permission.
     */
    public function check_admin_permission(): bool {
        return current_user_can('manage_options');
    }
    
    /**
     * Get presets schema.
     *
     * @return array Schema definition.
     */
    public function get_presets_schema(): array {
        return [
            '$schema'    => 'http://json-schema.org/draft-04/schema#',
            'title'      => 'presets',
            'type'       => 'object',
            'properties' => [
                'presets' => [
                    'description' => __('List of available presets.', 'prorank-seo'),
                    'type'        => 'array',
                    'items'       => [
                        'type'       => 'object',
                        'properties' => [
                            'id' => [
                                'description' => __('Preset identifier.', 'prorank-seo'),
                                'type'        => 'string',
                            ],
                            'name' => [
                                'description' => __('Preset name.', 'prorank-seo'),
                                'type'        => 'string',
                            ],
                            'description' => [
                                'description' => __('Preset description.', 'prorank-seo'),
                                'type'        => 'string',
                            ],
                            'icon' => [
                                'description' => __('Preset icon.', 'prorank-seo'),
                                'type'        => 'string',
                            ],
                            'settings_count' => [
                                'description' => __('Number of settings in preset.', 'prorank-seo'),
                                'type'        => 'integer',
                            ],
                        ],
                    ],
                ],
                'total' => [
                    'description' => __('Total number of presets.', 'prorank-seo'),
                    'type'        => 'integer',
                ],
            ],
        ];
    }
}