<?php

/**
 * Readability Module
 *
 * @package ProRank\SEO\Modules\Content
 * @since   0.1.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Modules\Content;

use ProRank\SEO\Core\Content\AnalysisContentCollector;
use ProRank\SEO\Core\Content\InclusiveLanguageAnalyzer;
use ProRank\SEO\Core\Content\ProminentWordsAnalyzer;
use ProRank\SEO\Modules\BaseModule;
use WP_REST_Request;
use WP_REST_Response;

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


/**
 * Readability module class
 */


class ReadabilityModule extends BaseModule {
    
    /**
     * Module slug
     *
     * @var string
     */
    protected string $slug = 'readability-analysis';
    
    /**
     * Module name
     *
     * @var string
     */
    protected string $name = 'Readability';
    
    /**
     * Module description
     *
     * @var string
     */
    protected string $description = 'Analyze content readability and SEO optimization';
    
    /**
     * Required tier
     *
     * @var string
     */
    protected string $feature_tier = 'free';
    
    /**
     * Parent module
     *
     * @var string|null
     */
    protected ?string $parent_slug = 'on-page-seo';
    
    /**
     * Readability instance
     *
     * @var Readability|null
     */
    private ?Readability $readability = null;
    
    /**
     * Initialize module hooks
     *
     * @return void
     */
    public function init_hooks(): void {
        if (!$this->is_enabled()) {
            return;
        }
        
        // Initialize readability analysis
        $this->readability = new Readability();
        
        // Add hooks for readability analysis
        add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
        add_action('rest_api_init', [$this, 'register_rest_routes']);
    }
    
    /**
     * Enqueue module assets
     *
     * @param string $hook Current admin page hook
     * @return void
     */
    public function enqueue_assets(string $hook): void {
        if (!in_array($hook, ['post.php', 'post-new.php'], true)) {
            return;
        }
        
        // The readability functionality is included in the sidebar.js bundle
        // which is enqueued by the editor integration
    }
    
    /**
     * Register REST routes
     *
     * @return void
     */
    public function register_rest_routes(): void {
        // Register the ReadabilityController
        if (class_exists('\ProRank\SEO\Core\RestApi\ReadabilityController')) {
            $controller = new \ProRank\SEO\Core\RestApi\ReadabilityController();
            $controller->register_routes();
        }

        // Task 8 R1 — ProminentWordsController is registered from the
        // main REST bootstrap (Plugin::get_rest_controllers) so its routes
        // exist regardless of which module path booted on this request.
        // Registering here too would just produce duplicate-route notices.

        // Also register the old endpoint for backward compatibility
        register_rest_route(
            'prorank-seo/v1',
            '/readability/analyze',
            [
                'methods' => 'POST',
                'callback' => [$this, 'analyze_content'],
                'permission_callback' => function() {
                    return current_user_can('edit_posts');
                },
            ]
        );
    }

    /**
     * Backward-compatible readability analyzer.
     *
     * Supports legacy POST /readability/analyze payloads.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response
     */
    public function analyze_content(WP_REST_Request $request): WP_REST_Response {
        $content = (string) $request->get_param('content');
        $post_id = absint((string) $request->get_param('post_id'));

        // Task 5 — when only a post_id is supplied, use the central collector
        // so the analyzer respects the custom-field / ACF inclusion settings.
        $collected = ['custom_fields_included' => false, 'custom_field_count' => 0, 'custom_field_chars' => 0];
        if ('' === trim($content) && $post_id > 0) {
            if (class_exists(AnalysisContentCollector::class)) {
                $info = AnalysisContentCollector::collect($post_id);
                $content = (string) $info['text'];
                $collected = [
                    'custom_fields_included' => (bool) $info['custom_fields_included'],
                    'custom_field_count'     => (int) $info['custom_field_count'],
                    'custom_field_chars'     => (int) $info['custom_field_chars'],
                ];
            } else {
                $post_content = get_post_field('post_content', $post_id, 'raw');
                if (is_string($post_content)) {
                    $content = $post_content;
                }
            }
        }

        if ('' === trim($content)) {
            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'score' => null,
                    'level' => null,
                    'grade' => null,
                    'stats' => [
                        'word_count' => 0,
                        'sentence_count' => 0,
                        'paragraph_count' => 0,
                        'estimated_reading_time' => 0,
                    ],
                    'message' => __('No content to analyze.', 'prorank-seo'),
                    'inclusive_language' => $this->build_inclusive_language_payload(''),
                    'prominent_words' => $this->build_prominent_words_payload(0),
                ],
            ], 200);
        }

        $cleaned_content = strip_shortcodes($content);
        $cleaned_content = wp_strip_all_tags($cleaned_content);
        $cleaned_content = html_entity_decode($cleaned_content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        $cleaned_content = preg_replace('/\s+/', ' ', $cleaned_content);
        $cleaned_content = trim((string) $cleaned_content);

        if ('' === $cleaned_content) {
            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'score' => null,
                    'level' => null,
                    'grade' => null,
                    'stats' => [
                        'word_count' => 0,
                        'sentence_count' => 0,
                        'paragraph_count' => 0,
                        'estimated_reading_time' => 0,
                    ],
                    'message' => __('No content to analyze.', 'prorank-seo'),
                    'inclusive_language' => $this->build_inclusive_language_payload(''),
                    'prominent_words' => $this->build_prominent_words_payload(0),
                ],
            ], 200);
        }

        $score = Readability::calculate_flesch_kincaid($cleaned_content);
        $word_count = str_word_count($cleaned_content);
        $sentence_count = preg_match_all('/[.!?]+/', $cleaned_content, $matches);
        $paragraph_count = max(1, count(preg_split('/\n\s*\n/', $content)));
        $estimated_reading_time = max(1, (int) ceil($word_count / 225));

        return new WP_REST_Response([
            'success' => true,
            'data' => [
                'score' => $score,
                'level' => null !== $score ? Readability::get_readability_level($score) : null,
                'grade' => null !== $score ? Readability::get_grade_level($score) : null,
                'stats' => [
                    'word_count' => $word_count,
                    'sentence_count' => max(1, (int) $sentence_count),
                    'paragraph_count' => $paragraph_count,
                    'estimated_reading_time' => $estimated_reading_time,
                ],
                'custom_fields_included' => $collected['custom_fields_included'],
                'custom_field_count'     => $collected['custom_field_count'],
                'custom_field_chars'     => $collected['custom_field_chars'],
                'inclusive_language'     => $this->build_inclusive_language_payload($content),
                'prominent_words'        => $this->build_prominent_words_payload($post_id),
            ],
        ], 200);
    }

    /**
     * Task 7 — additive inclusive-language summary for the legacy
     * /readability/analyze endpoint. Mirrors the controller helper so the
     * editor sees a stable shape regardless of which endpoint it hits.
     */
    private function build_inclusive_language_payload(string $content): array {
        if (!class_exists(InclusiveLanguageAnalyzer::class)) {
            return [
                'enabled'         => false,
                'total_issues'    => 0,
                'severity_counts' => ['high' => 0, 'medium' => 0, 'low' => 0],
                'issues'          => [],
                'truncated'       => false,
            ];
        }
        $settings = InclusiveLanguageAnalyzer::get_settings();
        $payload = [
            'enabled'         => (bool) $settings['enabled'],
            'total_issues'    => 0,
            'severity_counts' => ['high' => 0, 'medium' => 0, 'low' => 0],
            'issues'          => [],
            'truncated'       => false,
        ];
        if (!$settings['enabled'] || $content === '') {
            return $payload;
        }
        $result = InclusiveLanguageAnalyzer::analyze($content, [
            'ignored_terms' => $settings['ignored_terms'],
        ]);
        $payload['total_issues']    = (int) $result['total_issues'];
        $payload['severity_counts'] = $result['severity_counts'];
        $payload['issues']          = $result['issues'];
        $payload['truncated']       = (bool) $result['truncated'];
        return $payload;
    }

    /**
     * Task 8 — additive prominent-words payload for the legacy
     * `/readability/analyze` endpoint. Mirrors the controller helper so
     * the editor sees a stable shape from either endpoint.
     */
    private function build_prominent_words_payload(int $post_id): array {
        $stub = [
            'enabled' => false,
            'indexed' => false,
            'stale'   => false,
            'version' => class_exists(ProminentWordsAnalyzer::class)
                ? ProminentWordsAnalyzer::ANALYZER_VERSION
                : 0,
            'terms'   => [],
        ];
        if (!class_exists(ProminentWordsAnalyzer::class)) {
            return $stub;
        }
        if ($post_id <= 0) {
            $stub['enabled'] = (bool) ProminentWordsAnalyzer::get_settings()['enabled'];
            return $stub;
        }
        return ProminentWordsAnalyzer::get_post_index($post_id);
    }
}
