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

class AIFLT_AI_Report_Log {
    public static function table_name(): string {
        global $wpdb;
        return $wpdb->prefix . 'aiflt_ai_report_log';
    }

    public static function maybe_create_table(): void {
        global $wpdb;
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        $table = esc_sql(self::table_name());
        $charset_collate = $wpdb->get_charset_collate();
        $sql = "CREATE TABLE {$table} (
            id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            action_key VARCHAR(120) NOT NULL,
            provider VARCHAR(30) NOT NULL DEFAULT 'local',
            status VARCHAR(30) NOT NULL DEFAULT 'unknown',
            title VARCHAR(255) DEFAULT NULL,
            context_key VARCHAR(190) DEFAULT NULL,
            content LONGTEXT NULL,
            message TEXT NULL,
            payload_hash CHAR(64) DEFAULT NULL,
            created_by BIGINT(20) UNSIGNED DEFAULT NULL,
            created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY action_key (action_key),
            KEY provider (provider),
            KEY status (status),
            KEY context_key (context_key),
            KEY created_at (created_at)
        ) {$charset_collate};";
        dbDelta($sql);
    }

    public static function save(array $entry): void {
        global $wpdb;
        self::maybe_create_table();
        $content = isset($entry['content']) ? trim((string) $entry['content']) : '';
        $message = isset($entry['message']) ? trim((string) $entry['message']) : '';
        if ($content === '' && $message === '') {
            return;
        }
        $wpdb->insert(esc_sql(self::table_name()), [
            'action_key'   => sanitize_key($entry['action_key'] ?? 'general'),
            'provider'     => sanitize_key($entry['provider'] ?? 'local'),
            'status'       => sanitize_key($entry['status'] ?? 'unknown'),
            'title'        => isset($entry['title']) ? sanitize_text_field((string) $entry['title']) : null,
            'context_key'  => isset($entry['context_key']) ? sanitize_text_field((string) $entry['context_key']) : null,
            'content'      => wp_kses_post($content),
            'message'      => sanitize_textarea_field($message),
            'payload_hash' => isset($entry['payload_hash']) ? sanitize_text_field((string) $entry['payload_hash']) : null,
            'created_by'   => get_current_user_id() ?: null,
            'created_at'   => current_time('mysql'),
        ], ['%s','%s','%s','%s','%s','%s','%s','%s','%d','%s']);
    }

    public static function latest(string $action_key = '', string $context_key = ''): ?array {
        global $wpdb;
        self::maybe_create_table();
        $table = esc_sql(self::table_name());
        if ($action_key !== '' && $context_key !== '') {
            $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE action_key = %s AND context_key = %s ORDER BY created_at DESC, id DESC LIMIT 1", sanitize_key($action_key), sanitize_text_field($context_key)), ARRAY_A);
        } elseif ($action_key !== '') {
            $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$table} WHERE action_key = %s ORDER BY created_at DESC, id DESC LIMIT 1", sanitize_key($action_key)), ARRAY_A);
        } else {
            $row = $wpdb->get_row("SELECT * FROM {$table} ORDER BY created_at DESC, id DESC LIMIT 1", ARRAY_A);
        }
        return is_array($row) ? $row : null;
    }

    public static function recent(int $limit = 20, string $action_key = ''): array {
        global $wpdb;
        self::maybe_create_table();
        $limit = min(max(1, absint($limit)), 100);
        $table = esc_sql(self::table_name());
        if ($action_key !== '') {
            return $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE action_key = %s ORDER BY created_at DESC, id DESC LIMIT %d", sanitize_key($action_key), $limit), ARRAY_A) ?: [];
        }
        return $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} ORDER BY created_at DESC, id DESC LIMIT %d", $limit), ARRAY_A) ?: [];
    }

    public static function render_content($content): string {
        $content = self::normalize_content_string(is_string($content) ? $content : '');
        if ($content === '') {
            return '';
        }

        $decoded = self::decode_structured_content($content);
        if (is_array($decoded)) {
            return self::render_structured_content($decoded);
        }

        return self::render_markdown_content($content);
    }

    public static function normalize_content_string(string $content): string {
        $content = trim($content);
        if ($content === '') {
            return '';
        }
        $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        $content = str_replace(["\\r\\n", "\\n", "\\r", "\\t"], ["\n", "\n", "\n", "\t"], $content);
        $content = trim($content);

        if (preg_match('/^```(?:json|javascript|js)?\s*(.*?)\s*```$/is', $content, $m)) {
            $content = trim($m[1]);
        }

        if (stripos($content, 'data:') === 0) {
            $lines = preg_split('/\r\n|\r|\n/', $content);
            $payloads = [];
            foreach ($lines as $line) {
                $line = trim((string) $line);
                if (stripos($line, 'data:') === 0) {
                    $payload = trim(substr($line, 5));
                    if ($payload !== '' && $payload !== '[DONE]') {
                        $payloads[] = $payload;
                    }
                }
            }
            if (!empty($payloads)) {
                $content = trim((string) end($payloads));
            }
        }

        return trim($content);
    }

    public static function decode_structured_content(string $content) {
        $content = self::normalize_content_string($content);
        if ($content === '') {
            return null;
        }

        $decoded = json_decode($content, true);
        if (json_last_error() !== JSON_ERROR_NONE || !is_array($decoded)) {
            return null;
        }

        foreach (['output', 'content', 'message', 'result', 'response', 'report'] as $key) {
            if (!array_key_exists($key, $decoded)) {
                continue;
            }
            if (is_array($decoded[$key])) {
                return $decoded[$key];
            }
            if (is_string($decoded[$key])) {
                $inner = self::decode_structured_content($decoded[$key]);
                return is_array($inner) ? $inner : null;
            }
        }

        foreach ([['data', 'output'], ['data', 'content'], ['data', 'message'], ['data', 'result'], ['data', 'response']] as $path) {
            $value = $decoded;
            foreach ($path as $key) {
                if (is_array($value) && array_key_exists($key, $value)) {
                    $value = $value[$key];
                } else {
                    $value = null;
                    break;
                }
            }
            if (is_array($value)) {
                return $value;
            }
            if (is_string($value)) {
                $inner = self::decode_structured_content($value);
                if (is_array($inner)) {
                    return $inner;
                }
            }
        }

        return $decoded;
    }

    private static function render_markdown_content(string $content): string {
        $content = self::normalize_content_string($content);
        $lines = preg_split('/\r\n|\r|\n/', $content);
        $html = '';
        $in_list = false;

        $close_list = function () use (&$html, &$in_list) {
            if ($in_list) {
                $html .= '</ul>';
                $in_list = false;
            }
        };

        foreach ($lines as $raw_line) {
            $line = trim((string) $raw_line);
            if ($line === '') {
                $close_list();
                continue;
            }

            if (preg_match('/^#{1,6}\s+(.+)$/', $line, $m)) {
                $close_list();
                $html .= '<h4>' . self::format_inline($m[1]) . '</h4>';
                continue;
            }

            if (preg_match('/^[-*]\s+(.+)$/', $line, $m)) {
                if (!$in_list) {
                    $html .= '<ul class="aift-clean-list">';
                    $in_list = true;
                }
                $html .= '<li>' . self::format_inline($m[1]) . '</li>';
                continue;
            }

            $close_list();
            $html .= '<p>' . self::format_inline(preg_replace('/^#+\s*/', '', $line)) . '</p>';
        }

        $close_list();
        return wp_kses_post($html);
    }


    private static function is_empty_structured_value($value): bool {
        if ($value === null || $value === '') {
            return true;
        }
        if (is_array($value)) {
            foreach ($value as $item) {
                if (!self::is_empty_structured_value($item)) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    private static function render_structured_content(array $data): string {
        $data = self::unwrap_structured_data($data);
        if (empty($data)) {
            return '';
        }

        $html = '<div class="aift-structured-ai-report">';
        $summary_keys = ['executiveSummary', 'executive_summary', 'summary', 'pattern_summary', 'diagnosis', 'plainLanguageSummary', 'plain_language_summary', 'clientSummary', 'client_summary', 'reportTitle', 'title'];
        foreach ($summary_keys as $key) {
            if (!empty($data[$key]) && is_scalar($data[$key])) {
                $html .= '<section class="aift-structured-section aift-structured-summary"><h4>' . esc_html(self::human_label($key)) . '</h4><p>' . self::format_inline((string) $data[$key]) . '</p></section>';
                unset($data[$key]);
                break;
            }
        }

        foreach ($data as $key => $value) {
            if (self::is_empty_structured_value($value) || $key === '_raw') {
                continue;
            }
            $html .= '<section class="aift-structured-section"><h4>' . esc_html(self::human_label((string) $key)) . '</h4>' . self::render_structured_value($value) . '</section>';
        }

        $html .= '</div>';
        return wp_kses_post($html);
    }

    private static function unwrap_structured_data(array $data): array {
        foreach (['output', 'content', 'message', 'result', 'response', 'report'] as $key) {
            if (isset($data[$key]) && is_array($data[$key])) {
                return self::unwrap_structured_data($data[$key]);
            }
        }
        return $data;
    }

    private static function render_structured_value($value): string {
        if (is_scalar($value)) {
            return '<p>' . self::format_inline((string) $value) . '</p>';
        }
        if (!is_array($value)) {
            return '';
        }
        if (self::is_list_array($value)) {
            $html = '<div class="aift-structured-grid">';
            foreach ($value as $index => $item) {
                $html .= '<div class="aift-structured-card">' . self::render_card_content($item, $index) . '</div>';
            }
            $html .= '</div>';
            return $html;
        }

        $html = '<div class="aift-structured-grid">';
        foreach ($value as $key => $item) {
            if (self::is_empty_structured_value($item)) {
                continue;
            }
            $html .= '<div class="aift-structured-card"><span class="aift-structured-kicker">' . esc_html(self::human_label((string) $key)) . '</span>' . self::render_card_content($item, 0) . '</div>';
        }
        $html .= '</div>';
        return $html;
    }

    private static function render_card_content($item, int $index): string {
        if (is_scalar($item)) {
            return '<p>' . self::format_inline((string) $item) . '</p>';
        }
        if (!is_array($item)) {
            return '';
        }

        $title = '';
        foreach (['title', 'heading', 'recommendation', 'action', 'name', 'label', 'subject', 'step'] as $title_key) {
            if (!empty($item[$title_key]) && is_scalar($item[$title_key])) {
                $title = (string) $item[$title_key];
                unset($item[$title_key]);
                break;
            }
        }
        $html = $title !== '' ? '<strong class="aift-structured-card-title">' . self::format_inline($title) . '</strong>' : '';

        if (self::is_list_array($item)) {
            $html .= '<ul class="aift-clean-list">';
            foreach ($item as $row) {
                $html .= '<li>' . (is_scalar($row) ? self::format_inline((string) $row) : self::render_card_content($row, 0)) . '</li>';
            }
            $html .= '</ul>';
            return $html;
        }

        foreach ($item as $key => $value) {
            if (self::is_empty_structured_value($value)) {
                continue;
            }
            if (is_scalar($value)) {
                $html .= '<p><strong>' . esc_html(self::human_label((string) $key)) . ':</strong> ' . self::format_inline((string) $value) . '</p>';
            } else {
                $html .= '<div class="aift-structured-nested"><strong>' . esc_html(self::human_label((string) $key)) . '</strong>' . self::render_structured_value($value) . '</div>';
            }
        }
        return $html;
    }

    private static function is_list_array(array $value): bool {
        if ($value === []) {
            return true;
        }
        return array_keys($value) === range(0, count($value) - 1);
    }

    private static function human_label(string $key): string {
        $key = preg_replace('/([a-z])([A-Z])/', '$1 $2', $key);
        $key = str_replace(['_', '-'], ' ', $key);
        return ucwords(trim((string) $key));
    }

    private static function format_inline(string $text): string {
        $text = esc_html($text);
        $text = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $text);
        $text = preg_replace('/_(.*?)_/', '<em>$1</em>', $text);
        return $text;
    }

}
