<?php

/**
 * Wizard State REST API Controller
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   1.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use WP_REST_Request;
use WP_REST_Response;
use ProRank\SEO\Core\Config\Settings;

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


/**
 * Class WizardStateController
 *
 * Handles REST API endpoints for wizard state persistence
 */


class WizardStateController extends BaseController {
    /**
     * Option key for storing wizard state
     *
     * @var string
     */
    protected string $option_key = 'prorank_wizard_state_server';

    /**
     * Register REST API routes
     *
     * @return void
     */
    public function register_routes(): void {
        register_rest_route($this->namespace, '/wizard/state', [
            [
                'methods'             => \WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_state'],
                'permission_callback' => [$this, 'check_admin_permission'],
            ],
            [
                'methods'             => \WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'save_state'],
                'permission_callback' => [$this, 'check_admin_permission'],
            ],
        ]);

        register_rest_route($this->namespace, '/wizard/apply-optimizations', [
            'methods'             => \WP_REST_Server::CREATABLE,
            'callback'            => [$this, 'apply_optimizations'],
            'permission_callback' => [$this, 'check_admin_permission'],
        ]);
    }

    /**
     * Get the current wizard state
     *
     * @param WP_REST_Request $request REST request object.
     * @return WP_REST_Response
     */
    public function get_state(WP_REST_Request $request): WP_REST_Response {
        $stored = get_option($this->option_key, []);
        return new WP_REST_Response([
            'success' => true,
            'data'    => $stored,
        ], 200);
    }

    /**
     * Save the wizard state
     *
     * @param WP_REST_Request $request REST request object.
     * @return WP_REST_Response
     */
    public function save_state(WP_REST_Request $request): WP_REST_Response {
        $body = $request->get_json_params();
        if (!is_array($body) || $body === []) {
            $body = $request->get_body_params();
        }

        if (!is_array($body)) {
            return new WP_REST_Response([
                'success' => false,
                'code'    => 'invalid_payload',
                'message' => __('Invalid payload', 'prorank-seo'),
            ], 400);
        }

        $state = [
            'currentStep'    => max(0, absint($body['currentStep'] ?? 0)),
            'completedSteps' => is_array($body['completedSteps'] ?? null) ? array_values($body['completedSteps']) : [],
            'wizardData'     => is_array($body['wizardData'] ?? null) ? $body['wizardData'] : [],
            'updated_at'     => current_time('mysql'),
            'updated_by'     => get_current_user_id(),
        ];

        update_option($this->option_key, $state, false);

        $wizard_completed = !empty($state['wizardData']['wizardCompleted']);
        Settings::update('onboarding_completed', $wizard_completed);
        update_option('prorank_onboarding_completed', $wizard_completed, false);

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

    /**
     * Apply wizard optimizations — writes real settings to the database.
     *
     * @param WP_REST_Request $request REST request object.
     * @return WP_REST_Response
     */
    public function apply_optimizations(WP_REST_Request $request): WP_REST_Response {
        $body = $request->get_json_params();
        if (!is_array($body) || $body === []) {
            $body = $request->get_body_params();
        }

        $keys    = is_array($body['optimizations'] ?? null) ? $body['optimizations'] : [];
        $results = [];

        foreach ($keys as $key) {
            try {
                switch ($key) {
                    case 'robots_txt':
                        // Enable the robots.txt editor with sensible defaults
                        $robots = Settings::get('robots_indexing', []);
                        $robots['enable_robots_editor'] = true;
                        if (empty($robots['robots_txt_rules'])) {
                            $robots['robots_txt_rules'] = "User-agent: *\nAllow: /\n\nSitemap: " . trailingslashit(home_url()) . "sitemap_index.xml";
                        }
                        Settings::update('robots_indexing', $robots);
                        $results[$key] = ['success' => true, 'message' => 'Robots.txt editor enabled'];
                        break;

                    case 'xml_sitemap':
                        // Enable XML sitemaps via the sitemaps settings group
                        $sitemap = Settings::get('sitemaps', []);
                        $sitemap['enable_xml_sitemap'] = true;
                        Settings::update('sitemaps', $sitemap);
                        $results[$key] = ['success' => true, 'message' => 'XML sitemap enabled'];
                        break;

                    case 'breadcrumbs':
                        $bc = get_option('prorank_seo_breadcrumbs_settings', []);
                        if (!is_array($bc)) {
                            $bc = [];
                        }
                        $bc['enabled']       = true;
                        $bc['enable_schema'] = true;
                        update_option('prorank_seo_breadcrumbs_settings', $bc);
                        update_option('prorank_seo_breadcrumbs', $bc);
                        $results[$key] = ['success' => true, 'message' => 'Breadcrumbs enabled'];
                        break;

                    case 'permalinks':
                        global $wp_rewrite;
                        if ($wp_rewrite && get_option('permalink_structure') !== '/%postname%/') {
                            $wp_rewrite->set_permalink_structure('/%postname%/');
                            $wp_rewrite->flush_rules(false);
                        }
                        $results[$key] = ['success' => true, 'message' => 'Permalinks set to postname'];
                        break;

                    case 'schema_markup':
                        $schema = get_option('prorank_basic_schema_settings', []);
                        $schema['enabled'] = true;
                        update_option('prorank_basic_schema_settings', $schema);
                        $results[$key] = ['success' => true, 'message' => 'Basic schema markup enabled'];
                        break;

                    case 'redirect_attachments':
                        $hc = get_option('prorank_seo_head_cleanup', []);
                        $hc['redirect_attachments'] = true;
                        update_option('prorank_seo_head_cleanup', $hc);
                        $results[$key] = ['success' => true, 'message' => 'Attachment redirects enabled'];
                        break;

                    case 'noindex_archives':
                        $tm = get_option('prorank_titles_meta_settings', []);
                        $tm['noindex_date_archives']   = true;
                        $tm['noindex_author_archives'] = true;
                        update_option('prorank_titles_meta_settings', $tm, false);
                        $results[$key] = ['success' => true, 'message' => 'Archive pages noindexed'];
                        break;

                    case 'image_alt_text':
                        // Kept for backward compatibility with older wizard builds.
                        $results[$key] = [
                            'success' => false,
                            'error'   => __('Auto image alt-text generation is not available in this edition.', 'prorank-seo'),
                        ];
                        break;

                    default:
                        $results[$key] = ['success' => false, 'error' => 'Unknown optimization'];
                }
            } catch (\Throwable $e) {
                $results[$key] = ['success' => false, 'error' => $e->getMessage()];
            }
        }

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