<?php
/**
 * LuxStrat Content Validator
 *
 * Validates AI-generated Luxembourg structuring content before publication.
 * Ensures word count, structure, legal precision, and SEO compliance.
 *
 * @package DamalionBlogAI
 * @subpackage LuxStrat
 */

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

class DBA_LuxStrat_Validator {

    private static $instance = null;

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Validate generated content against quality criteria.
     *
     * @param  array $data {
     *     @type string $title     Post title.
     *     @type string $content   HTML content.
     *     @type string $excerpt   Post excerpt.
     *     @type string $theme     Theme slug.
     * }
     * @return array { 'valid' => bool, 'errors' => string[], 'warnings' => string[] }
     */
    public function validate( $data ) {
        $errors   = array();
        $warnings = array();

        $title   = isset( $data['title'] )   ? trim( $data['title'] )   : '';
        $content = isset( $data['content'] ) ? trim( $data['content'] ) : '';
        $excerpt = isset( $data['excerpt'] ) ? trim( $data['excerpt'] ) : '';
        $theme   = isset( $data['theme'] )   ? trim( $data['theme'] )   : '';

        // ── Title checks ──
        if ( empty( $title ) ) {
            $errors[] = 'Title is empty.';
        } elseif ( mb_strlen( $title ) < 30 ) {
            $errors[] = 'Title too short (min 30 chars). Got: ' . mb_strlen( $title );
        } elseif ( mb_strlen( $title ) > 160 ) {
            $warnings[] = 'Title is very long (' . mb_strlen( $title ) . ' chars). Consider shortening for SEO.';
        }

        // ── Content checks ──
        if ( empty( $content ) ) {
            $errors[] = 'Content is empty.';
        } else {
            $word_count = str_word_count( strip_tags( $content ) );
            $settings   = get_option( 'dba_luxstrat_settings', array() );
            $min_words  = ! empty( $settings['word_count_min'] ) ? (int) $settings['word_count_min'] : 1000;
            $max_words  = ! empty( $settings['word_count_max'] ) ? (int) $settings['word_count_max'] : 1800;

            // Allow 8% tolerance on minimum (AI word count vs PHP word count can differ)
            $soft_min = (int) round( $min_words * 0.92 );
            if ( $word_count < $soft_min ) {
                $errors[] = "Word count too low: {$word_count} (minimum: {$min_words}, hard floor: {$soft_min}).";
            } elseif ( $word_count < $min_words ) {
                $warnings[] = "Word count slightly below target: {$word_count} (target: {$min_words}). Accepted within tolerance.";
            }
            if ( $word_count > $max_words + 300 ) {
                $warnings[] = "Word count high: {$word_count} (target max: {$max_words}).";
            }

            // Must have H2 headings for structure
            if ( substr_count( $content, '<h2' ) < 2 ) {
                $errors[] = 'Content must have at least 2 H2 headings for proper structure.';
            }

            // Must have paragraphs
            if ( substr_count( $content, '<p' ) < 3 ) {
                $errors[] = 'Content must have at least 3 paragraphs.';
            }

            // Check for AI slop phrases
            $slop_phrases = array(
                'in conclusion',
                'it is important to note',
                'it should be noted that',
                'as we have seen',
                'in this article we',
                'let\'s dive in',
                'without further ado',
                'in today\'s ever-changing',
                'navigating the complex',
                'in the ever-evolving',
            );
            $content_lower = mb_strtolower( $content );
            foreach ( $slop_phrases as $phrase ) {
                if ( strpos( $content_lower, $phrase ) !== false ) {
                    $warnings[] = 'AI slop phrase detected: "' . $phrase . '". Consider revision.';
                }
            }

            // Must not contain placeholder text
            $placeholders = array( '[INSERT', '[TODO', '[PLACEHOLDER', '{{', '}}', 'Lorem ipsum' );
            foreach ( $placeholders as $ph ) {
                if ( stripos( $content, $ph ) !== false ) {
                    $errors[] = 'Placeholder text found: "' . $ph . '"';
                }
            }
        }

        // ── Excerpt check ──
        if ( empty( $excerpt ) ) {
            $warnings[] = 'Excerpt is empty. Will auto-generate from content.';
        } elseif ( mb_strlen( $excerpt ) > 300 ) {
            $warnings[] = 'Excerpt is long (' . mb_strlen( $excerpt ) . ' chars). Keep under 160 for SEO.';
        }

        // ── Theme check ──
        if ( empty( $theme ) ) {
            $errors[] = 'Theme slug is missing.';
        } elseif ( ! DBA_LuxStrat_Registry::get_theme( $theme ) ) {
            $errors[] = 'Unknown theme slug: "' . $theme . '"';
        }

        // ── Duplicate title check ──
        if ( ! empty( $title ) && DBA_LuxStrat_Dedupe::title_is_duplicate( $title ) ) {
            $errors[] = 'Title too similar to a recent LuxStrat post (last 90 days).';
        }

        return array(
            'valid'    => empty( $errors ),
            'errors'   => $errors,
            'warnings' => $warnings,
        );
    }
}
