<?php

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

final class AISBW_Quality_Checker
{
    private AISBW_Topic_Repository $topics;
    private AISBW_AI_Client $client;
    private AISBW_Logger $logger;

    public function __construct(
        ?AISBW_Topic_Repository $topics = null,
        ?AISBW_AI_Client $client = null,
        ?AISBW_Logger $logger = null
    ) {
        $this->topics = $topics ?: new AISBW_Topic_Repository();
        $this->client = $client ?: new AISBW_AI_Client();
        $this->logger = $logger ?: new AISBW_Logger();
    }

    public function check(int $topic_id): array
    {
        $topic = $this->topics->get($topic_id);

        if (!$topic) {
            throw new RuntimeException(__('Topic not found.', 'guco-ai-blog-writer'));
        }

        $article = json_decode((string) ($topic['generated_content'] ?? ''), true);
        $brief = json_decode((string) ($topic['brief'] ?? ''), true);

        if (!is_array($article) || empty($article['content_html'])) {
            throw new RuntimeException(__('Brak wygenerowanego artykułu do oceny.', 'guco-ai-blog-writer'));
        }

        $this->logger->info('quality_check_started', 'Rozpoczęto quality check.', [], $topic_id);

        try {
            $result = $this->client->request_json(
                [
                    [
                        'role' => 'system',
                        'content' => self::prompt(),
                    ],
                    [
                        'role' => 'user',
                        'content' => wp_json_encode([
                            'topic' => $topic,
                            'brief' => is_array($brief) ? $brief : null,
                            'article' => $article,
                            'guardrails' => [
                                'quality_score_below_70' => 'failed albo review_required',
                                'quality_score_70_84' => 'review_required',
                                'quality_score_85_plus' => 'można stworzyć szkic WP',
                                'high_risk_topics' => 'zawsze requires_human_review',
                            ],
                        ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
                    ],
                ],
                self::schema(),
                'aisbw_quality_check',
                null,
                $topic_id,
                'quality_check'
            );

            $result = $this->apply_hard_rules($topic, $article, $result);
            $status = $this->status_from_quality_result($result);
            $this->topics->save_quality_result($topic_id, $result, $status);
            $this->logger->info('quality_check_finished', 'Quality check zakończony.', ['status' => $status], $topic_id);

            return $result;
        } catch (Throwable $e) {
            $this->topics->update_status($topic_id, 'failed', $e->getMessage());
            $this->logger->error('quality_check_failed', $e->getMessage(), [], $topic_id);
            throw $e;
        }
    }

    public function status_from_quality_result(array $result): string
    {
        $score = isset($result['quality_score']) ? absint($result['quality_score']) : 0;

        if (!$result['passed'] || $score < 70) {
            return 'failed';
        }

        if ($score < 85 || !empty($result['requires_human_review'])) {
            return 'review_required';
        }

        return 'draft_ready';
    }

    private function apply_hard_rules(array $topic, array $article, array $result): array
    {
        $issues = isset($result['issues']) && is_array($result['issues']) ? $result['issues'] : [];
        $content = (string) ($article['content_html'] ?? '');

        if ('' === trim($content)) {
            $result['passed'] = false;
            $result['requires_human_review'] = true;
            $result['recommended_action'] = 'reject';
            $issues[] = [
                'type' => 'content',
                'severity' => 'critical',
                'message' => __('content_html is empty.', 'guco-ai-blog-writer'),
            ];
        }

        if ($this->contains_placeholder($content)) {
            $result['passed'] = false;
            $result['requires_human_review'] = true;
            $result['recommended_action'] = 'human_review';
            $issues[] = [
                'type' => 'content',
                'severity' => 'critical',
                'message' => __('Text contains placeholders.', 'guco-ai-blog-writer'),
            ];
        }

        if ($this->is_high_risk_topic($topic)) {
            $result['risk_level'] = 'high';
            $result['requires_human_review'] = true;
            $result['recommended_action'] = 'human_review';
            $issues[] = [
                'type' => 'risk',
                'severity' => 'major',
                'message' => __('High-risk topic requires manual review.', 'guco-ai-blog-writer'),
            ];
        }

        $result['issues'] = $issues;
        $result['quality_score'] = max(0, min(100, absint($result['quality_score'] ?? 0)));
        $result['passed'] = !empty($result['passed']);
        $result['requires_human_review'] = !empty($result['requires_human_review']);

        if (empty($result['risk_level']) || !in_array($result['risk_level'], ['low', 'normal', 'high'], true)) {
            $result['risk_level'] = 'normal';
        }

        if (empty($result['recommended_action']) || !in_array($result['recommended_action'], ['create_wp_draft', 'revise', 'reject', 'human_review', 'publish'], true)) {
            $result['recommended_action'] = $result['requires_human_review'] ? 'human_review' : 'create_wp_draft';
        }

        return $result;
    }

    private function contains_placeholder(string $content): bool
    {
        return (bool) preg_match('/\[(?:TU|WSTAW|PLACEHOLDER|TODO)[^\]]*\]/iu', $content);
    }

    private function is_high_risk_topic(array $topic): bool
    {
        if ('high' === ($topic['risk_level'] ?? '')) {
            return true;
        }

        $haystack = implode(' ', [
            $topic['topic'] ?? '',
            $topic['primary_keyword'] ?? '',
            $topic['secondary_keywords'] ?? '',
        ]);
        $haystack = function_exists('mb_strtolower') ? mb_strtolower($haystack, 'UTF-8') : strtolower($haystack);

        foreach (['zdrowie', 'finanse', 'prawo', 'polityka', 'religia', 'oskarżenia', 'ceny produktów', 'ranking produktów'] as $keyword) {
            if (str_contains($haystack, $keyword)) {
                return true;
            }
        }

        return false;
    }

    private static function prompt(): string
    {
        return 'Jesteś redaktorem prowadzącym, fact-checkerem i specjalistą SEO. Oceń wygenerowany artykuł pod kątem zgodności z briefem, jakości językowej, naturalności, halucynacji, ryzyk prawnych, twierdzeń wymagających źródeł, SEO title, meta description, slug, struktury nagłówków i potrzeby ręcznej recenzji. Zwróć wyłącznie JSON zgodny ze schematem.';
    }

    public static function schema(): array
    {
        return [
            'type' => 'object',
            'additionalProperties' => false,
            'required' => ['passed', 'quality_score', 'risk_level', 'issues', 'requires_human_review', 'recommended_action'],
            'properties' => [
                'passed' => ['type' => 'boolean'],
                'quality_score' => ['type' => 'integer', 'minimum' => 0, 'maximum' => 100],
                'risk_level' => ['type' => 'string', 'enum' => ['low', 'normal', 'high']],
                'issues' => [
                    'type' => 'array',
                    'items' => [
                        'type' => 'object',
                        'additionalProperties' => false,
                        'required' => ['type', 'severity', 'message'],
                        'properties' => [
                            'type' => ['type' => 'string'],
                            'severity' => ['type' => 'string', 'enum' => ['minor', 'major', 'critical']],
                            'message' => ['type' => 'string'],
                        ],
                    ],
                ],
                'requires_human_review' => ['type' => 'boolean'],
                'recommended_action' => ['type' => 'string', 'enum' => ['create_wp_draft', 'revise', 'reject', 'human_review', 'publish']],
            ],
        ];
    }
}
