<?php
if (!defined('ABSPATH')) {
    exit;
}

class VMO_Website_QA {
    private static $instance = null;
    private $wpdb;
    private $table_name;

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

        return self::$instance;
    }

    private function __construct() {
        global $wpdb;

        $this->wpdb = $wpdb;
        $this->table_name = $wpdb->prefix . 'vmo_website_qa_reports';

        add_action('init', array($this, 'ensure_schema'), 6);
    }

    public function ensure_schema() {
        if (!function_exists('dbDelta')) {
            require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        }

        $charset_collate = $this->wpdb->get_charset_collate();
        $sql = "CREATE TABLE IF NOT EXISTS {$this->table_name} (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
            user_id BIGINT UNSIGNED NOT NULL,
            session_id VARCHAR(255) NOT NULL,
            draft_key VARCHAR(191) DEFAULT NULL,
            related_post_id BIGINT UNSIGNED DEFAULT NULL,
            score TINYINT UNSIGNED DEFAULT 0,
            publish_ready TINYINT(1) DEFAULT 0,
            report_json LONGTEXT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY idx_user_id (user_id),
            KEY idx_session_id (session_id),
            KEY idx_draft_key (draft_key),
            KEY idx_related_post_id (related_post_id)
        ) {$charset_collate};";

        dbDelta($sql);
    }

    public function run_qa($user_id, $session_id, $website_payload, array $business_package = array(), array $context = array()) {
        $user_id = (int) $user_id;
        $session_id = (string) $session_id;
        $pages = $this->extract_pages($website_payload);
        $combined_content = strtolower($this->build_combined_content($pages));
        $brief_bundle = function_exists('vmo_get_master_business_brief_service')
            ? vmo_get_master_business_brief_service()->get_active_brief($session_id, $user_id)
            : array();
        $brief = isset($brief_bundle['brief']) && is_array($brief_bundle['brief']) ? $brief_bundle['brief'] : array();
        $business_name = strtolower(trim((string) ($brief['business_identity']['business_name'] ?? ($business_package['business_overview']['business_name'] ?? ''))));

        $critical = array();
        $warnings = array();
        $required_pages = array('home', 'about', 'services', 'contact');
        $required_legal_docs = $this->resolve_required_legal_docs($brief, $business_package);

        foreach ($required_pages as $required_page) {
            if (!array_key_exists($required_page, $pages)) {
                $warnings[] = ucfirst($required_page) . ' page is missing from the generated website output.';
            }
        }

        if (empty($brief)) {
            $critical[] = 'Business brief is not locked yet, so publish readiness cannot be verified against a canonical business profile.';
        }

        if ($business_name !== '' && strpos($combined_content, $business_name) === false) {
            $warnings[] = 'The generated website content does not clearly mention the business name.';
        }

        if (preg_match('/lorem ipsum|your business|my business|sample text|replace this/i', $combined_content)) {
            $critical[] = 'Generic placeholder copy is still present in the website content.';
        }

        if (preg_match('/\[(generated_image|generated_video):/i', $combined_content)) {
            $critical[] = 'Raw media placeholders are still present. Media generation or replacement has not completed.';
        }

        if (preg_match('/placeholder\.com|picsum\.photos|example\.com|via\.placeholder/i', $combined_content)) {
            $critical[] = 'Placeholder media URLs are still present in the website output.';
        }

        $media_complete = !$this->contains_incomplete_media($combined_content);
        if (!$media_complete) {
            $critical[] = 'Media completeness check failed because unresolved generated-media markers remain.';
        }

        $legal_pages_present = true;
        $missing_legal_pages = array();
        foreach ($required_legal_docs as $doc_slug) {
            if (!$this->has_legal_page($pages, $combined_content, $doc_slug)) {
                $legal_pages_present = false;
                $missing_legal_pages[] = $doc_slug;
            }
        }
        if (!$legal_pages_present) {
            $critical[] = 'Required legal pages or embedded legal content are missing: ' . implode(', ', $missing_legal_pages) . '.';
        }

        $score = max(0, 100 - (count($critical) * 20) - (count($warnings) * 5));
        $publish_ready = empty($critical);
        $checklist = array(
            'business_brief_locked' => !empty($brief),
            'website_qa_passed' => $publish_ready,
            'required_legal_pages_present' => $legal_pages_present,
            'media_complete' => $media_complete,
        );

        $report = array(
            'score' => $score,
            'publish_ready' => $publish_ready,
            'critical_findings' => $critical,
            'warnings' => $warnings,
            'checklist' => $checklist,
            'required_legal_docs' => $required_legal_docs,
            'page_count' => count($pages),
            'pages_detected' => array_keys($pages),
            'summary' => $publish_ready
                ? 'Website QA passed. The draft is ready for explicit publish approval.'
                : 'Website QA found blocking issues that must be resolved before publishing.',
        );

        $this->wpdb->insert(
            $this->table_name,
            array(
                'user_id' => $user_id,
                'session_id' => $session_id,
                'draft_key' => isset($context['draft_key']) ? (string) $context['draft_key'] : '',
                'related_post_id' => isset($context['related_post_id']) ? (int) $context['related_post_id'] : 0,
                'score' => $score,
                'publish_ready' => $publish_ready ? 1 : 0,
                'report_json' => wp_json_encode($report),
                'created_at' => current_time('mysql'),
            ),
            array('%d', '%s', '%s', '%d', '%d', '%d', '%s', '%s')
        );

        $report['report_id'] = (int) $this->wpdb->insert_id;

        return $report;
    }

    public function get_latest_report($session_id, $draft_key = '', $related_post_id = 0) {
        $session_id = (string) $session_id;
        if ($session_id === '') {
            return array();
        }

        $sql = "SELECT * FROM {$this->table_name} WHERE session_id = %s";
        $params = array($session_id);
        if ($draft_key !== '') {
            $sql .= ' AND draft_key = %s';
            $params[] = $draft_key;
        }
        if ((int) $related_post_id > 0) {
            $sql .= ' AND related_post_id = %d';
            $params[] = (int) $related_post_id;
        }
        $sql .= ' ORDER BY id DESC LIMIT 1';

        $row = $this->wpdb->get_row($this->wpdb->prepare($sql, $params), ARRAY_A);
        if (!$row) {
            return array();
        }

        $report = json_decode($row['report_json'], true);
        if (!is_array($report)) {
            $report = array();
        }
        $report['report_id'] = (int) $row['id'];

        return $report;
    }

    private function extract_pages($website_payload) {
        $pages = array();

        if (is_string($website_payload)) {
            return array('home' => $website_payload);
        }

        if (!is_array($website_payload)) {
            return $pages;
        }

        if (!empty($website_payload['website_code']) && is_string($website_payload['website_code'])) {
            $pages['home'] = $website_payload['website_code'];
        }

        $candidate_maps = array(
            $website_payload['pages_map'] ?? null,
            $website_payload['pages_generated'] ?? null,
            $website_payload['pages'] ?? null,
        );

        foreach ($candidate_maps as $candidate_map) {
            if (!is_array($candidate_map)) {
                continue;
            }
            foreach ($candidate_map as $key => $value) {
                $slug = is_string($key) ? sanitize_title($key) : sanitize_title((string) ($value['title'] ?? $value['name'] ?? $key));
                if ($slug === '') {
                    $slug = 'page-' . count($pages);
                }
                $pages[$slug] = $this->page_to_string($value);
            }
        }

        if (!empty($website_payload['pages_created']) && is_array($website_payload['pages_created'])) {
            foreach ($website_payload['pages_created'] as $page_value) {
                if (is_string($page_value)) {
                    $pages[sanitize_title($page_value)] = $page_value;
                } elseif (is_array($page_value)) {
                    $slug = sanitize_title((string) ($page_value['slug'] ?? $page_value['title'] ?? $page_value['name'] ?? 'page-' . count($pages)));
                    $pages[$slug] = $this->page_to_string($page_value);
                }
            }
        }

        if (empty($pages) && !empty($website_payload['content']) && is_string($website_payload['content'])) {
            $pages['home'] = $website_payload['content'];
        }

        return $pages;
    }

    private function resolve_required_legal_docs(array $brief, array $business_package) {
        $docs = array();

        if (!empty($business_package['document_recommendations']['website_embedded_docs']) && is_array($business_package['document_recommendations']['website_embedded_docs'])) {
            $docs = $business_package['document_recommendations']['website_embedded_docs'];
        } elseif (!empty($business_package['website_embedded_docs']) && is_array($business_package['website_embedded_docs'])) {
            $docs = $business_package['website_embedded_docs'];
        } elseif (!empty($brief['legal_policy_requirements']) && is_array($brief['legal_policy_requirements'])) {
            $docs = $brief['legal_policy_requirements'];
        }

        return array_values(array_unique(array_filter(array_map('sanitize_title', $docs))));
    }

    private function has_legal_page(array $pages, $combined_content, $doc_slug) {
        $doc_slug = sanitize_title((string) $doc_slug);
        if ($doc_slug === '') {
            return true;
        }

        foreach ($pages as $page_slug => $page_content) {
            if (strpos($page_slug, $doc_slug) !== false) {
                return true;
            }
            if (strpos(strtolower($page_content), str_replace('-', ' ', $doc_slug)) !== false) {
                return true;
            }
        }

        return strpos($combined_content, str_replace('-', ' ', $doc_slug)) !== false;
    }

    private function contains_incomplete_media($combined_content) {
        return (bool) preg_match('/data-vmo-generate=|data-vmo-sora=|\[(generated_image|generated_video):/i', $combined_content);
    }

    private function build_combined_content(array $pages) {
        $content = '';
        foreach ($pages as $page_slug => $page_content) {
            $content .= "\n<!-- {$page_slug} -->\n" . $page_content;
        }

        return $content;
    }

    private function page_to_string($value) {
        if (is_string($value)) {
            return $value;
        }
        if (is_array($value)) {
            if (!empty($value['html']) && is_string($value['html'])) {
                return $value['html'];
            }
            if (!empty($value['content']) && is_string($value['content'])) {
                return $value['content'];
            }
            return wp_json_encode($value);
        }

        return '';
    }
}

if (!function_exists('vmo_get_website_qa_service')) {
    function vmo_get_website_qa_service() {
        return VMO_Website_QA::get_instance();
    }
}
