<?php

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use ProRank\SEO\Core\Content\AiAttributeStripper;
use ProRank\SEO\Core\Content\AiContentLeakAuditor;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

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

/**
 * REST endpoints for AI content leak detection and cleanup.
 *
 * Routes:
 *   GET   /prorank-seo/v1/ai-leaks/post/{id}    — per-post leak count (used by editor sidebar)
 *   GET   /prorank-seo/v1/ai-leaks/scan         — site-wide scan
 *   POST  /prorank-seo/v1/ai-leaks/strip/{id}   — strip a single post (dry_run param)
 *   POST  /prorank-seo/v1/ai-leaks/strip-all    — bulk strip (dry_run param)
 */
class AiLeaksController extends BaseController {

    protected $rest_base = 'ai-leaks';

    public function register_routes(): void {
        register_rest_route($this->namespace, '/' . $this->rest_base . '/post/(?P<id>\d+)', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'check_post'],
                'permission_callback' => [$this, 'check_editor_permission'],
                'args' => [
                    'id' => [
                        'validate_callback' => static fn($v) => is_numeric($v) && (int) $v > 0,
                    ],
                ],
            ],
        ]);

        register_rest_route($this->namespace, '/' . $this->rest_base . '/scan', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'scan'],
                'permission_callback' => [$this, 'check_permission'],
            ],
        ]);

        register_rest_route($this->namespace, '/' . $this->rest_base . '/strip/(?P<id>\d+)', [
            [
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => [$this, 'strip_post'],
                'permission_callback' => [$this, 'check_permission'],
                'args' => [
                    'id' => [
                        'validate_callback' => static fn($v) => is_numeric($v) && (int) $v > 0,
                    ],
                    'dry_run' => [
                        'default' => true,
                        'sanitize_callback' => 'rest_sanitize_boolean',
                    ],
                ],
            ],
        ]);

        register_rest_route($this->namespace, '/' . $this->rest_base . '/strip-all', [
            [
                'methods' => WP_REST_Server::CREATABLE,
                'callback' => [$this, 'strip_all'],
                'permission_callback' => [$this, 'check_permission'],
                'args' => [
                    'dry_run' => [
                        'default' => true,
                        'sanitize_callback' => 'rest_sanitize_boolean',
                    ],
                ],
            ],
        ]);
    }

    /**
     * Editors and above can read per-post leak status (so the sidebar shows for them).
     */
    public function check_editor_permission() {
        return current_user_can('edit_posts');
    }

    public function check_post(WP_REST_Request $request) {
        $post_id = (int) $request->get_param('id');
        $post = get_post($post_id);
        if (!$post) {
            return $this->error(__('Post not found', 'prorank-seo'), 'post_not_found', 404);
        }
        if (!current_user_can('edit_post', $post_id)) {
            return $this->error(__('Insufficient permissions', 'prorank-seo'), 'forbidden', 403);
        }

        $auditor = new AiContentLeakAuditor();
        $content = $auditor->breakdown((string) $post->post_content);
        $excerpt = $auditor->breakdown((string) $post->post_excerpt);

        $elementor_high = 0;
        $elementor_data = get_post_meta($post_id, '_elementor_data', true);
        if (is_string($elementor_data) && $elementor_data !== '') {
            $elementor_high = $auditor->breakdown_json($elementor_data)['high_confidence'];
        }

        return $this->success([
            'post_id' => $post_id,
            'high_confidence' => $content['high_confidence'] + $excerpt['high_confidence'],
            'ambiguous' => $content['ambiguous'] + $excerpt['ambiguous'],
            'elementor_high_confidence' => $elementor_high,
            'by_vendor' => $this->merge_vendors($content['by_vendor'], $excerpt['by_vendor']),
            'by_attribute' => $this->merge_vendors($content['by_attribute'], $excerpt['by_attribute']),
        ]);
    }

    public function scan() {
        $auditor = new AiContentLeakAuditor();
        return $this->success($auditor->scan());
    }

    public function strip_post(WP_REST_Request $request) {
        $post_id = (int) $request->get_param('id');
        if (!current_user_can('edit_post', $post_id)) {
            return $this->error(__('Insufficient permissions', 'prorank-seo'), 'forbidden', 403);
        }
        $dry_run = (bool) $request->get_param('dry_run');

        $stripper = new AiAttributeStripper();
        $content = $stripper->strip_post($post_id, $dry_run);
        $elementor = $stripper->strip_elementor($post_id, $dry_run);

        if (!$dry_run && (!empty($content['mutated']) || !empty($elementor['mutated']))) {
            $stripper->refresh_runtime_caches([$post_id]);
        }

        return $this->success([
            'post_id' => $post_id,
            'dry_run' => $dry_run,
            'content' => $content,
            'elementor' => $elementor,
        ]);
    }

    public function strip_all(WP_REST_Request $request) {
        $dry_run = (bool) $request->get_param('dry_run');
        $stripper = new AiAttributeStripper();
        $totals = $stripper->strip_all($dry_run);
        return $this->success([
            'dry_run' => $dry_run,
            'totals' => $totals,
        ]);
    }

    private function merge_vendors(array $a, array $b): array {
        foreach ($b as $k => $v) {
            $a[$k] = ($a[$k] ?? 0) + $v;
        }
        return $a;
    }
}
