<?php
declare(strict_types=1);

namespace ROITheme\Shared\Infrastructure\CLI;

use WP_CLI;

/**
 * Comando WP-CLI para limpiar contenido Thrive congelado de páginas
 *
 * LIMPIEZA QUIRÚRGICA CON VALIDACIONES DE SEGURIDAD:
 * - Elimina H2 con data-shortcode="tcb_post_title"
 * - Elimina paginación rota ([tcb_pagination_current_page], [tcb_pagination_total_pages])
 * - PRESERVA todo el demás contenido incluyendo shortcodes [roi_apu_search]
 * - Verifica que shortcodes importantes NO sean eliminados
 * - Aborta si se detecta pérdida excesiva de contenido (>50%)
 *
 * USO:
 *   wp roi-theme clean_thrive --dry-run    # Ver qué se limpiaría (OBLIGATORIO primero)
 *   wp roi-theme clean_thrive              # Ejecutar limpieza real
 *
 * SEGURIDAD:
 * - Verifica preservación de shortcodes [roi_apu_search]
 * - Máximo 50% de reducción de contenido permitida
 * - Valida cada preg_replace para evitar null returns
 */
final class CleanThriveContentCommand
{
    /**
     * IDs de páginas buscar-apus afectadas
     */
    private const AFFECTED_PAGE_IDS = [
        107264, 107312, 107340, 107345, 107351, 107357, 107362,
        107369, 107374, 107379, 107384, 107389, 107395, 107399,
        107403, 107407, 107411, 107416, 107421, 107425, 185752
    ];

    /**
     * Otras páginas con contenido Thrive (Blog, Curso)
     */
    private const OTHER_AFFECTED_IDS = [252030, 290709];

    /**
     * Shortcodes que DEBEN ser preservados
     */
    private const PROTECTED_SHORTCODES = [
        '[roi_apu_search',
        '[roi_',
    ];

    /**
     * Máximo porcentaje de contenido que puede eliminarse
     */
    private const MAX_CONTENT_LOSS_PERCENT = 50;

    public function __invoke(array $args, array $assoc_args): void
    {
        $dryRun = isset($assoc_args['dry-run']);
        $includeOthers = isset($assoc_args['include-others']);
        $force = isset($assoc_args['force']);

        $pageIds = self::AFFECTED_PAGE_IDS;
        if ($includeOthers) {
            $pageIds = array_merge($pageIds, self::OTHER_AFFECTED_IDS);
        }

        WP_CLI::log('');
        WP_CLI::log('╔══════════════════════════════════════════════════════════════════╗');
        WP_CLI::log('║   LIMPIEZA QUIRÚRGICA DE CONTENIDO THRIVE CONGELADO (v2.0)       ║');
        WP_CLI::log('║   Con validaciones de seguridad para proteger shortcodes         ║');
        WP_CLI::log('╚══════════════════════════════════════════════════════════════════╝');
        WP_CLI::log('');

        if ($dryRun) {
            WP_CLI::warning('MODO DRY-RUN: No se modificará ningún contenido');
        } else {
            WP_CLI::error('MODO REAL DESHABILITADO: Ejecuta primero con --dry-run', false);
            WP_CLI::log('');
            WP_CLI::log('Para ejecutar la limpieza real, primero revisa el dry-run:');
            WP_CLI::log('  wp roi-theme clean_thrive --dry-run');
            WP_CLI::log('');
            WP_CLI::log('Si el dry-run es correcto y deseas ejecutar:');
            WP_CLI::log('  wp roi-theme clean_thrive --force');

            if (!$force) {
                return;
            }
            WP_CLI::warning('MODO REAL CON --force: Se modificará el contenido');
        }

        WP_CLI::log('');
        WP_CLI::log('Páginas a procesar: ' . count($pageIds));
        WP_CLI::log('Shortcodes protegidos: ' . implode(', ', self::PROTECTED_SHORTCODES));
        WP_CLI::log('Máxima pérdida permitida: ' . self::MAX_CONTENT_LOSS_PERCENT . '%');
        WP_CLI::log('');

        $totalH2Removed = 0;
        $totalPaginationRemoved = 0;
        $totalBytesFreed = 0;
        $pagesModified = 0;
        $pagesSkipped = 0;
        $errors = [];

        foreach ($pageIds as $id) {
            $page = get_post($id);
            if (!$page) {
                WP_CLI::warning("Página {$id} no encontrada, saltando...");
                continue;
            }

            $originalContent = $page->post_content;
            $originalSize = strlen($originalContent);

            // Verificar si tiene contenido Thrive que limpiar
            $hasThrive = strpos($originalContent, 'tcb_post_title') !== false ||
                         strpos($originalContent, 'tcb_pagination') !== false;

            if (!$hasThrive) {
                WP_CLI::log(sprintf(
                    "[SIN THRIVE] ID %d: %s",
                    $id,
                    mb_substr($page->post_title, 0, 50)
                ));
                continue;
            }

            // Contar elementos antes de limpiar
            $h2Count = preg_match_all('/<h2[^>]*>.*?data-shortcode="tcb_post_title".*?<\/h2>/s', $originalContent);

            // Contar shortcodes protegidos antes
            $protectedBefore = $this->countProtectedShortcodes($originalContent);

            // Limpiar contenido con validación
            $cleanResult = $this->cleanContentSafely($originalContent);

            if ($cleanResult['error']) {
                $errors[] = "ID {$id}: {$cleanResult['error']}";
                WP_CLI::error(sprintf(
                    "[ERROR] ID %d: %s - %s",
                    $id,
                    mb_substr($page->post_title, 0, 40),
                    $cleanResult['error']
                ), false);
                $pagesSkipped++;
                continue;
            }

            $cleanedContent = $cleanResult['content'];
            $newSize = strlen($cleanedContent);

            // Contar shortcodes protegidos después
            $protectedAfter = $this->countProtectedShortcodes($cleanedContent);

            // VALIDACIÓN CRÍTICA: Verificar shortcodes protegidos
            if ($protectedAfter < $protectedBefore) {
                $errors[] = "ID {$id}: Se perderían shortcodes protegidos ({$protectedBefore} → {$protectedAfter})";
                WP_CLI::error(sprintf(
                    "[ABORTADO] ID %d: Se perderían shortcodes protegidos (%d → %d)",
                    $id,
                    $protectedBefore,
                    $protectedAfter
                ), false);
                $pagesSkipped++;
                continue;
            }

            // Verificar pérdida excesiva de contenido
            $lossPercent = $originalSize > 0 ? (($originalSize - $newSize) / $originalSize) * 100 : 0;
            if ($lossPercent > self::MAX_CONTENT_LOSS_PERCENT) {
                $errors[] = "ID {$id}: Pérdida excesiva de contenido ({$lossPercent}%)";
                WP_CLI::error(sprintf(
                    "[ABORTADO] ID %d: Pérdida excesiva %.1f%% (máx %d%%)",
                    $id,
                    $lossPercent,
                    self::MAX_CONTENT_LOSS_PERCENT
                ), false);
                $pagesSkipped++;
                continue;
            }

            // Verificar si hubo cambios
            $hasChanges = $originalContent !== $cleanedContent;
            $bytesSaved = $originalSize - $newSize;

            // Contar paginación removida
            $paginationRemoved = (
                strpos($originalContent, 'tcb_pagination_current_page') !== false &&
                strpos($cleanedContent, 'tcb_pagination_current_page') === false
            ) ? 1 : 0;

            if ($hasChanges) {
                $pagesModified++;
                $totalH2Removed += $h2Count;
                $totalPaginationRemoved += $paginationRemoved;
                $totalBytesFreed += $bytesSaved;

                $status = $dryRun ? '[DRY-RUN]' : '[LIMPIADO]';
                WP_CLI::log(sprintf(
                    "%s ID %d: %s",
                    $status,
                    $id,
                    mb_substr($page->post_title, 0, 50) . (mb_strlen($page->post_title) > 50 ? '...' : '')
                ));
                WP_CLI::log(sprintf(
                    "         → H2 eliminados: %d | Paginación: %s | Pérdida: %.1f%%",
                    $h2Count,
                    $paginationRemoved ? 'Sí' : 'No',
                    $lossPercent
                ));
                WP_CLI::log(sprintf(
                    "         → Shortcodes [roi_*] preservados: %d | Bytes liberados: %s",
                    $protectedAfter,
                    $this->formatBytes($bytesSaved)
                ));

                if (!$dryRun && $force) {
                    wp_update_post([
                        'ID' => $id,
                        'post_content' => $cleanedContent
                    ]);
                }
            } else {
                WP_CLI::log(sprintf(
                    "[SIN CAMBIOS] ID %d: %s",
                    $id,
                    mb_substr($page->post_title, 0, 50)
                ));
            }
        }

        WP_CLI::log('');
        WP_CLI::log('════════════════════════════════════════════════════════════════════');
        WP_CLI::log('RESUMEN:');
        WP_CLI::log(sprintf('  Páginas modificadas:    %d', $pagesModified));
        WP_CLI::log(sprintf('  Páginas omitidas:       %d', $pagesSkipped));
        WP_CLI::log(sprintf('  Total H2 eliminados:    %d', $totalH2Removed));
        WP_CLI::log(sprintf('  Paginaciones removidas: %d', $totalPaginationRemoved));
        WP_CLI::log(sprintf('  Espacio liberado:       %s', $this->formatBytes($totalBytesFreed)));
        WP_CLI::log('════════════════════════════════════════════════════════════════════');

        if (count($errors) > 0) {
            WP_CLI::log('');
            WP_CLI::warning('ERRORES ENCONTRADOS:');
            foreach ($errors as $error) {
                WP_CLI::log("  - {$error}");
            }
        }

        if ($dryRun && $pagesModified > 0 && count($errors) === 0) {
            WP_CLI::log('');
            WP_CLI::success('Dry-run completado SIN errores.');
            WP_CLI::log('');
            WP_CLI::warning('Para ejecutar la limpieza real:');
            WP_CLI::log('  wp roi-theme clean_thrive --force');
        } elseif (!$dryRun && $force && $pagesModified > 0) {
            WP_CLI::log('');
            WP_CLI::success('Limpieza completada exitosamente.');
            WP_CLI::log('');
            WP_CLI::warning('IMPORTANTE: Purga el caché del sitio para ver los cambios.');
        }
    }

    /**
     * Limpia el contenido con validaciones de seguridad
     *
     * @return array{content: string, error: string|null}
     */
    private function cleanContentSafely(string $content): array
    {
        $originalContent = $content;

        // 1. Eliminar H2 con data-shortcode="tcb_post_title"
        $result = preg_replace(
            '/<h2[^>]*>.*?data-shortcode="tcb_post_title".*?<\/h2>/s',
            '',
            $content
        );
        if ($result === null) {
            return ['content' => $originalContent, 'error' => 'preg_replace falló en patrón H2'];
        }
        $content = $result;

        // 2. Eliminar paginación Thrive rota
        $result = preg_replace(
            '/<p[^>]*>.*?\[tcb_pagination_current_page\].*?\[tcb_pagination_total_pages\].*?<\/p>/s',
            '',
            $content
        );
        if ($result === null) {
            return ['content' => $originalContent, 'error' => 'preg_replace falló en patrón paginación'];
        }
        $content = $result;

        // 3. Eliminar botones de paginación Thrive
        $result = preg_replace(
            '/<p[^>]*data-button_layout="[^"]*"[^>]*data-page="[^"]*"[^>]*>.*?<\/p>/s',
            '',
            $content
        );
        if ($result === null) {
            return ['content' => $originalContent, 'error' => 'preg_replace falló en patrón botones'];
        }
        $content = $result;

        // 4. Eliminar shortcodes Thrive huérfanos
        $content = str_replace('[tcb_pagination_current_page]', '', $content);
        $content = str_replace('[tcb_pagination_total_pages]', '', $content);

        // 5. Limpiar múltiples líneas vacías (con validación)
        $result = preg_replace('/(\r?\n){3,}/', "\n\n", $content);
        if ($result === null) {
            return ['content' => $originalContent, 'error' => 'preg_replace falló en limpieza líneas'];
        }
        $content = $result;

        // 6. Trim
        $content = trim($content);

        // Validación final: no retornar vacío si original tenía contenido
        if (empty($content) && !empty($originalContent)) {
            return ['content' => $originalContent, 'error' => 'El contenido quedó vacío'];
        }

        return ['content' => $content, 'error' => null];
    }

    /**
     * Cuenta shortcodes protegidos en el contenido
     */
    private function countProtectedShortcodes(string $content): int
    {
        $count = 0;
        foreach (self::PROTECTED_SHORTCODES as $shortcode) {
            $count += substr_count($content, $shortcode);
        }
        return $count;
    }

    /**
     * Formatea bytes a formato legible
     */
    private function formatBytes(int $bytes): string
    {
        if ($bytes < 1024) {
            return $bytes . ' B';
        } elseif ($bytes < 1048576) {
            return round($bytes / 1024, 1) . ' KB';
        } else {
            return round($bytes / 1048576, 2) . ' MB';
        }
    }
}
