<?php

/**
 * HTML Sitemap 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\Config\Settings;
use ProRank\SEO\Modules\TechnicalSEO\HtmlSitemapModule;
use ProRank\SEO\Plugin;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

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


/**
 * Class HtmlSitemapController
 */


class HtmlSitemapController extends BaseController {
    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Settings endpoints
        register_rest_route($this->namespace, '/settings/html-sitemap', [
            [
                'methods'             => 'GET',
                'callback'            => [$this, 'get_settings'],
                'permission_callback' => [$this, 'check_permission'],
            ],
            [
                'methods'             => 'POST',
                'callback'            => [$this, 'update_settings'],
                'permission_callback' => [$this, 'check_permission'],
                'args'                => [
                    'settings' => [
                        'required' => true,
                        'type'     => 'object',
                    ],
                ],
            ],
        ]);

        // Preview endpoint
        register_rest_route($this->namespace, '/html-sitemap/preview', [
            'methods'             => 'POST',
            'callback'            => [$this, 'get_preview'],
            'permission_callback' => [$this, 'check_permission'],
            'args'                => [
                'settings' => [
                    'required' => true,
                    'type'     => 'object',
                ],
            ],
        ]);
    }

    /**
     * Get HTML sitemap settings
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_settings(WP_REST_Request $request) {
        $defaults = [
            'enable_html_sitemap' => true,
            'sitemap_page_id' => '',
            'auto_insert_shortcode' => false,
            'include_sections' => ['pages', 'posts', 'categories', 'tags'],
            'exclude_empty' => true,
            'show_post_count' => true,
            'show_date' => false,
            'show_excerpt' => false,
            'columns' => 1,
            'style' => 'list',
            'heading_tag' => 'h3',
            'sort_order' => 'title',
            'exclude_ids' => '',
            'custom_css' => '',
            'widget_enabled' => true,
            'widget_title' => __('Sitemap', 'prorank-seo'),
            'widget_sections' => ['pages', 'posts'],
        ];

        $settings = [];
        foreach ($defaults as $key => $default) {
            $settings[$key] = Settings::get('modules.html_sitemap.' . $key, $default);
        }

        return new WP_REST_Response([
            'settings' => $settings,
        ]);
    }

    /**
     * Update HTML sitemap settings
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function update_settings(WP_REST_Request $request) {
        $settings = $request->get_param('settings');

        if (!is_array($settings)) {
            return new WP_Error(
                'invalid_settings',
                __('Invalid settings format', 'prorank-seo'),
                ['status' => 400]
            );
        }

        $sanitized = [
            'enable_html_sitemap' => !empty($settings['enable_html_sitemap']),
            'sitemap_page_id' => isset($settings['sitemap_page_id']) ? (string) absint($settings['sitemap_page_id']) : '',
            'auto_insert_shortcode' => !empty($settings['auto_insert_shortcode']),
            'include_sections' => isset($settings['include_sections']) && is_array($settings['include_sections'])
                ? array_values(array_filter(array_map('sanitize_key', $settings['include_sections'])))
                : ['pages', 'posts', 'categories', 'tags'],
            'exclude_empty' => !empty($settings['exclude_empty']),
            'show_post_count' => !empty($settings['show_post_count']),
            'show_date' => !empty($settings['show_date']),
            'show_excerpt' => !empty($settings['show_excerpt']),
            'columns' => max(1, min(4, (int) ($settings['columns'] ?? 1))),
            'style' => in_array(($settings['style'] ?? 'list'), ['list', 'grid', 'compact'], true) ? $settings['style'] : 'list',
            'heading_tag' => in_array(($settings['heading_tag'] ?? 'h3'), ['h2', 'h3', 'h4', 'h5', 'h6'], true) ? $settings['heading_tag'] : 'h3',
            'sort_order' => in_array(($settings['sort_order'] ?? 'title'), ['title', 'date', 'modified', 'menu_order'], true) ? $settings['sort_order'] : 'title',
            'exclude_ids' => isset($settings['exclude_ids']) ? sanitize_text_field((string) $settings['exclude_ids']) : '',
            'custom_css' => isset($settings['custom_css']) ? sanitize_textarea_field((string) $settings['custom_css']) : '',
            'widget_enabled' => !empty($settings['widget_enabled']),
            'widget_title' => isset($settings['widget_title']) ? sanitize_text_field((string) $settings['widget_title']) : __('Sitemap', 'prorank-seo'),
            'widget_sections' => isset($settings['widget_sections']) && is_array($settings['widget_sections'])
                ? array_values(array_filter(array_map('sanitize_key', $settings['widget_sections'])))
                : ['pages', 'posts'],
        ];

        foreach ($sanitized as $key => $value) {
            Settings::set('modules.html_sitemap.' . $key, $value);
        }

        // Auto-insert shortcode if enabled
        if (!empty($sanitized['sitemap_page_id']) && $sanitized['auto_insert_shortcode']) {
            $this->auto_insert_shortcode((int) $sanitized['sitemap_page_id']);
        }

        // Clear any HTML sitemap caches
        wp_cache_delete('prorank_html_sitemap', 'prorank_seo');

        return new WP_REST_Response([
            'success' => true,
            'message' => __('Settings saved successfully', 'prorank-seo'),
        ]);
    }

    /**
     * Get HTML sitemap preview
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_preview(WP_REST_Request $request) {
        $settings = $request->get_param('settings');

        if (!is_array($settings)) {
            return new WP_Error(
                'invalid_settings',
                __('Invalid settings format', 'prorank-seo'),
                ['status' => 400]
            );
        }

        // Generate preview HTML using the shortcode with provided settings
        $atts = [
            'include' => implode(',', $settings['include_sections'] ?? []),
            'columns' => $settings['columns'] ?? 1,
            'style' => $settings['style'] ?? 'list',
            'exclude_empty' => !empty($settings['exclude_empty']) ? 'true' : 'false',
            'show_post_count' => !empty($settings['show_post_count']) ? 'true' : 'false',
            'show_date' => $settings['show_date'] ? 'true' : 'false',
            'show_excerpt' => $settings['show_excerpt'] ? 'true' : 'false',
            'heading_tag' => $settings['heading_tag'] ?? 'h3',
            'sort_order' => $settings['sort_order'] ?? 'title',
            'exclude_ids' => $settings['exclude_ids'] ?? '',
        ];

        // Resolve the HTML sitemap module directly from the plugin runtime.
        $module = $this->get_html_sitemap_module();
        
        if (!$module) {
            return new WP_Error(
                'module_not_found',
                __('HTML Sitemap module not found', 'prorank-seo'),
                ['status' => 404]
            );
        }

        // Generate preview
        $preview_html = $module->render_sitemap_shortcode($atts);

        return new WP_REST_Response([
            'preview' => $preview_html,
        ]);
    }

    /**
     * Resolve the HTML sitemap module instance for preview generation.
     *
     * @return HtmlSitemapModule|null
     */
    private function get_html_sitemap_module(): ?HtmlSitemapModule {
        try {
            $plugin = Plugin::get_instance();
            $module_manager = method_exists($plugin, 'modules') ? $plugin->modules() : null;

            if ($module_manager && method_exists($module_manager, 'get_active_modules')) {
                foreach ($module_manager->get_active_modules() as $module) {
                    if ($module instanceof HtmlSitemapModule) {
                        return $module;
                    }
                }
            }
        } catch (\Throwable $e) {
            // Fall back to direct instantiation below.
        }

        return class_exists(HtmlSitemapModule::class) ? new HtmlSitemapModule() : null;
    }

    /**
     * Auto-insert shortcode into page
     *
     * @param int $page_id Page ID
     * @return void
     */
    private function auto_insert_shortcode(int $page_id): void {
        $page = get_post($page_id);
        
        if (!$page || $page->post_type !== 'page') {
            return;
        }

        // Check if shortcode already exists
        if (has_shortcode($page->post_content, 'prorank_sitemap') || 
            has_shortcode($page->post_content, 'prorank_html_sitemap')) {
            return;
        }

        // Add shortcode to the end of content
        $updated_content = $page->post_content;
        if (!empty($updated_content)) {
            $updated_content .= "\n\n";
        }
        $updated_content .= '[prorank_sitemap]';

        // Update the page
        wp_update_post([
            'ID' => $page_id,
            'post_content' => $updated_content,
        ]);
    }
}
