<?php

declare(strict_types=1);

namespace ProRank\SEO\CLI;

use ProRank\SEO\Core\Content\AiAttributeStripper;
use ProRank\SEO\Core\Content\AiContentLeakAuditor;
use ProRank\SEO\Core\Content\AiContentLeakSignatures;
use WP_CLI;

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

/**
 * Detect and remove AI chat surface metadata leaks in content.
 *
 * ## EXAMPLES
 *
 *     # Scan the site for AI paste artifacts
 *     wp prorank ai-leaks scan
 *
 *     # Strip leaks (dry-run, default)
 *     wp prorank ai-leaks strip
 *
 *     # Commit changes
 *     wp prorank ai-leaks strip --commit
 *
 *     # Show what's detected
 *     wp prorank ai-leaks signatures
 */
class AiLeaksCommand {

    /**
     * Scan all posts/pages/CPTs and Elementor data for AI metadata leaks.
     *
     * ## OPTIONS
     *
     * [--format=<format>]
     * : Output format. Accepts: table, json, csv, yaml, count. Default: table.
     *
     * [--limit=<n>]
     * : Show top N offenders in the table output. Default 25.
     *
     * @when after_wp_load
     */
    public function scan($args, $assoc_args): void {
        $format = $assoc_args['format'] ?? 'table';
        $limit = isset($assoc_args['limit']) ? max(1, (int) $assoc_args['limit']) : 25;

        $auditor = new AiContentLeakAuditor();
        $result = $auditor->scan();

        WP_CLI::log(sprintf(
            'Scanned: %d offending content items, %d high-confidence leaks, %d ambiguous markers.',
            $result['offender_count'],
            $result['totals']['high_confidence'],
            $result['totals']['ambiguous']
        ));
        WP_CLI::log(sprintf(
            'Elementor data: %d items with %d high-confidence leaks, %d ambiguous.',
            $result['elementor']['item_count'],
            $result['elementor']['totals']['high_confidence'],
            $result['elementor']['totals']['ambiguous']
        ));
        if (!empty($result['terms']['item_count'])) {
            WP_CLI::log(sprintf(
                'Term descriptions: %d items with %d high-confidence leaks, %d ambiguous.',
                $result['terms']['item_count'],
                $result['terms']['totals']['high_confidence'],
                $result['terms']['totals']['ambiguous']
            ));
        }

        if (!empty($result['by_post_type'])) {
            WP_CLI::log('');
            WP_CLI::log('By post type:');
            foreach ($result['by_post_type'] as $type => $count) {
                WP_CLI::log(sprintf('  %s: %d', $type, $count));
            }
        }
        if (!empty($result['by_vendor'])) {
            WP_CLI::log('');
            WP_CLI::log('By vendor:');
            foreach ($result['by_vendor'] as $vendor => $count) {
                WP_CLI::log(sprintf('  %s: %d', $vendor, $count));
            }
        }

        if ($format === 'count') {
            return;
        }

        $rows = array_slice($result['offenders'], 0, $limit);
        $display = array_map(static function ($o) {
            return [
                'id' => $o['id'],
                'type' => $o['type'],
                'high' => $o['high_confidence'],
                'ambig' => $o['ambiguous'],
                'date' => substr((string) $o['date'], 0, 10),
                'title' => mb_substr((string) $o['title'], 0, 60),
            ];
        }, $rows);

        WP_CLI\Utils\format_items($format, $display, ['id', 'type', 'high', 'ambig', 'date', 'title']);
    }

    /**
     * Strip AI metadata attributes from post content and Elementor data.
     *
     * ## OPTIONS
     *
     * [--commit]
     * : Actually write changes. Without this flag, runs in dry-run mode.
     *
     * @when after_wp_load
     */
    public function strip($args, $assoc_args): void {
        $commit = isset($assoc_args['commit']);
        $dry_run = !$commit;

        if ($dry_run) {
            WP_CLI::log('DRY RUN — no changes will be written. Re-run with --commit to apply.');
        } else {
            WP_CLI::warning('COMMIT mode — content will be modified. Make sure you have a backup.');
        }

        $stripper = new AiAttributeStripper();
        $totals = $stripper->strip_all($dry_run, function ($kind, $item, $result) {
            if (!$result['mutated']) {
                return;
            }
            $item_id = (int) ($item['id'] ?? $item['term_id'] ?? 0);
            $label = (string) ($item['title'] ?? $item['name'] ?? '');
            WP_CLI::log(sprintf(
                '  %-9s id=%d removed=%d (%s)',
                $kind,
                $item_id,
                (int) $result['removed'],
                mb_substr($label, 0, 50)
            ));
        });

        WP_CLI::success(sprintf(
            'Posts examined %d, mutated %d, content leaks removed %d. Elementor items examined %d, mutated %d, leaks removed %d. Terms examined %d, mutated %d, leaks removed %d.',
            $totals['posts_examined'],
            $totals['posts_mutated'],
            $totals['content_leaks_removed'],
            $totals['elementor_items_examined'],
            $totals['elementor_items_mutated'],
            $totals['elementor_leaks_removed'],
            $totals['terms_examined'] ?? 0,
            $totals['terms_mutated'] ?? 0,
            $totals['term_leaks_removed'] ?? 0
        ));
    }

    /**
     * Print the catalogue of attributes detected.
     *
     * @when after_wp_load
     */
    public function signatures(): void {
        WP_CLI::log('High-confidence (auto-strippable):');
        foreach (AiContentLeakSignatures::HIGH_CONFIDENCE as $attr => $vendor) {
            WP_CLI::log(sprintf('  %-30s %s', $attr, $vendor));
        }
        WP_CLI::log('');
        WP_CLI::log('Ambiguous (detect-only):');
        foreach (AiContentLeakSignatures::AMBIGUOUS as $attr => $vendor) {
            WP_CLI::log(sprintf('  %-30s %s', $attr, $vendor));
        }
    }
}

if (defined('WP_CLI') && WP_CLI) {
    WP_CLI::add_command('prorank ai-leaks', 'ProRank\\SEO\\CLI\\AiLeaksCommand');
}
