<?php

namespace AIPT\Utils;

/**
 * Validates AI-generated responses against expected product context.
 * Detects cross-product contamination and content quality issues.
 * 
 * @since 2.4.0
 */
class AIResponseValidator {
    /**
     * @var array
     */
    private $product_context;

    /**
     * @var array
     */
    private $validation_issues = [];

    /**
     * @param array $product_context Product context from PromptBuilder
     */
    public function __construct(array $product_context) {
        $this->product_context = $product_context;
        $this->validation_issues = [];
    }

    /**
     * @param string $response      AI-generated response text
     * @param string $response_type Type of response ('short', 'full', 'tags')
     * @return ValidationResult
     */
    public function validate(string $response, string $response_type = 'full'): ValidationResult {
        $this->validation_issues = [];

        if (empty(trim($response))) {
            $this->validation_issues[] = 'Response is empty';
            return new ValidationResult($this->validation_issues, false);
        }

        $this->validateMinimumLength($response, $response_type);
        $this->validateNoPlaceholders($response);
        $this->validateNoMarkdownArtifacts($response, $response_type);

        $is_valid = empty($this->validation_issues);
        return new ValidationResult($this->validation_issues, $is_valid);
    }

    private function validateMinimumLength(string $response, string $type): void {
        $min_lengths = [
            'short' => 20,
            'full' => 50,
            'tags' => 3,
        ];

        $min_length = $min_lengths[$type] ?? 20;
        if (strlen(trim($response)) < $min_length) {
            $this->validation_issues[] = sprintf(
                'Response too short for %s description (min: %d chars)',
                $type,
                $min_length
            );
        }
    }

    private function validateNoPlaceholders(string $response): void {
        $placeholder_patterns = [
            '/\{[A-Z_]+\}/',
            '/\[INSERT .+?\]/i',
            '/\[YOUR .+?\]/i',
            '/\[PRODUCT .+?\]/i',
            '/Lorem ipsum/i',
        ];

        foreach ($placeholder_patterns as $pattern) {
            if (preg_match($pattern, $response)) {
                $this->validation_issues[] = 'Response contains placeholder text';
                break;
            }
        }
    }

    private function validateNoMarkdownArtifacts(string $response, string $type): void {
        if ($type === 'tags') {
            return;
        }

        $markdown_patterns = [
            '/^#{1,6}\s/',
            '/\*\*\*/',
            '/^```/',
            '/^- \[.\]/',
        ];

        foreach ($markdown_patterns as $pattern) {
            if (preg_match($pattern, $response, $matches)) {
                $this->validation_issues[] = 'Response contains markdown artifacts that should be HTML';
                break;
            }
        }
    }

    /**
     * @return array
     */
    public function getIssues(): array {
        return $this->validation_issues;
    }

    /**
     * @param string $response
     * @param array  $product_context
     * @param string $type
     * @return ValidationResult
     */
    public static function validateResponse(string $response, array $product_context, string $type = 'full'): ValidationResult {
        $validator = new self($product_context);
        return $validator->validate($response, $type);
    }
}

/**
 * @since 2.4.0
 */
class ValidationResult {
    /**
     * @var array
     */
    private $issues;

    /**
     * @var bool
     */
    private $is_valid;

    /**
     * @param array $issues   Validation issues found
     * @param bool  $is_valid Whether validation passed
     */
    public function __construct(array $issues, bool $is_valid) {
        $this->issues = $issues;
        $this->is_valid = $is_valid;
    }

    /**
     * @return bool
     */
    public function isValid(): bool {
        return $this->is_valid;
    }

    /**
     * @return array
     */
    public function getIssues(): array {
        return $this->issues;
    }

    /**
     * @return bool
     */
    public function hasIssues(): bool {
        return !empty($this->issues);
    }

    /**
     * @return string
     */
    public function getFirstIssue(): string {
        return $this->issues[0] ?? '';
    }

    /**
     * @return string
     */
    public function getIssuesAsString(): string {
        return implode('; ', $this->issues);
    }
}
