<?php

namespace HaoZiTeam\AIPost\Service\Settings\Traits;

defined('ABSPATH') || exit;

trait TraitDebugLog
{
    // 渲染：调试日志操作面板（预览/下载）
    public function render_debug_log_panel(): void
    {
        // 标记：告知 Setting 已渲染，避免页脚兜底再次输出
        if (property_exists($this, 'debug_panel_rendered')) {
            $this->debug_panel_rendered = true;
        }
        $path = $this->resolve_debug_log_path();
        $exists = $path && @file_exists($path);
        $size = $exists ? @filesize($path) : 0;
        $nonce = \wp_create_nonce('ai_post_debug_log');
        $connNonce = \wp_create_nonce('ai_post_connectivity_check');
        // 额外：文生图自检/连通性 Nonce
        $volcLocalNonce  = \wp_create_nonce('ai_post_volc_imagegen_check');
        $volcOnlineNonce = \wp_create_nonce('ai_post_volc_imagegen_connectivity');
        $aliyunLocalNonce  = \wp_create_nonce('ai_post_aliyun_imagegen_check');
        $aliyunOnlineNonce = \wp_create_nonce('ai_post_aliyun_imagegen_connectivity');
        $adminAjax = \admin_url('admin-ajax.php');
        $prettySize = $size >= 1048576 ? round($size/1048576, 2) . ' MB' : ($size >= 1024 ? round($size/1024, 2) . ' KB' : $size . ' B');
        ?>
        <div class="ai-post-debug-panel" style="background:#f8f9fa;border:1px solid #e5e7eb;border-radius:6px;padding:12px;">
            <div style="margin-bottom:8px;">
                <strong>日志路径：</strong>
                <code><?php echo esc_html($path ?: '未知'); ?></code>
                <?php if ($exists): ?>
                    <span style="margin-left:8px;color:#666;">大小：<?php echo esc_html($prettySize); ?></span>
                <?php else: ?>
                    <span style="margin-left:8px;color:#d63638;">文件不存在（开启开关并触发一次请求后再试）</span>
                <?php endif; ?>
            </div>
            <style>
                .aipost-sys-grid { display:grid; grid-template-columns:1fr; gap:12px; margin-top:6px; }
                @media (min-width: 980px){ .aipost-sys-grid { grid-template-columns: 1fr 1fr; } }
                .aipost-card { background:#fff; border:1px solid #e5e7eb; border-radius:8px; padding:12px; }
                .aipost-card h3 { margin:0 0 8px; font-size:15px; }
                .aipost-desc { color:#6b7280; font-size:12px; margin:2px 0 10px; }
                .aipost-actions { display:grid; grid-template-columns:1fr; gap:8px; }
                @media (min-width: 480px){ .aipost-actions { grid-template-columns:1fr 1fr; } }
                .aipost-btn { display:flex; align-items:center; gap:8px; padding:10px 12px; border:1px solid #e5e7eb; border-radius:6px; background:#fff; color:#111; text-decoration:none; transition:.15s ease; }
                .aipost-btn:hover { background:#f6f7f7; border-color:#d1d5db; }
                .aipost-btn strong { display:block; font-size:13px; }
                .aipost-btn span { display:block; font-size:12px; color:#6b7280; }
                .aipost-btn.primary { background:#fff; border-color:#e5e7eb; color:#0e7490; }
                .aipost-btn.primary:hover { background:#f6f7f7; border-color:#d1d5db; }
                .aipost-btn.warn { background:#fff; border-color:#e5e7eb; color:#92400e; }
                .aipost-btn.warn:hover { background:#f6f7f7; border-color:#d1d5db; }
                .aipost-btn.danger { background:#fff; border-color:#e5e7eb; color:#991b1b; }
                .aipost-btn.danger:hover { background:#f6f7f7; border-color:#d1d5db; }
            </style>
            <div class="aipost-sys-grid">
                <div class="aipost-card">
                    <h3>日志操作</h3>
                    <div class="aipost-desc">预览、下载或清理调试日志；用于快速排查问题。</div>
                    <div class="aipost-actions">
                        <a href="javascript:;" class="aipost-btn primary" id="ai-post-preview-debug-log"><div>
                            <strong>预览最近200行</strong>
                            <span>快速浏览最新错误与提示</span>
                        </div></a>
                        <a class="aipost-btn" id="ai-post-download-debug-log" href="<?php echo $exists ? esc_url(add_query_arg(['action' => 'ai_post_download_debug_log', '_wpnonce' => $nonce], $adminAjax)) : '#'; ?>" <?php echo $exists ? '' : 'disabled'; ?>><div>
                            <strong>下载完整日志</strong>
                            <span>用于提交给开发者分析</span>
                        </div></a>
                        <a href="javascript:;" class="aipost-btn danger" id="ai-post-delete-debug-log" <?php echo $exists ? '' : 'disabled'; ?>><div>
                            <strong>删除日志</strong>
                            <span>如不再需要调试日志，可删除，同时关闭日志开关</span>
                        </div></a>
                    </div>
                </div>
                <div class="aipost-card">
                    <h3>连通性与模型自测</h3>
                    <div class="aipost-desc">本地自检不发起外网请求；外网连通性会执行最小实际调用。</div>
                    <div class="aipost-actions">
                        <a href="javascript:;" class="aipost-btn warn" id="ai-post-connectivity-check"><div>
                            <strong>一键自检（/v1/models）</strong>
                            <span>WP‑Cron / Loopback / 证书 / 权限</span>
                        </div></a>
                        <a href="javascript:;" class="aipost-btn" id="ai-post-volc-imagegen-check"><div>
                            <strong>豆包文生图（本地）</strong>
                            <span>配置结构与权限快速自检</span>
                        </div></a>
                        <a href="javascript:;" class="aipost-btn warn" id="ai-post-volc-imagegen-online"><div>
                            <strong>豆包文生图（外网）</strong>
                            <span>真实最小调用，验证出口连通</span>
                        </div></a>
                        <a href="javascript:;" class="aipost-btn" id="ai-post-aliyun-imagegen-check"><div>
                            <strong>阿里云文生图（本地）</strong>
                            <span>不出网，仅校验参数合法性</span>
                        </div></a>
                        <a href="javascript:;" class="aipost-btn warn" id="ai-post-aliyun-imagegen-online"><div>
                            <strong>阿里云文生图（外网）</strong>
                            <span>真实最小调用，验证出口连通</span>
                        </div></a>
                    </div>
                </div>
            </div>
            <pre id="ai-post-debug-log-output" style="margin-top:10px;display:none;max-height:300px;overflow:auto;background:#111;color:#e6edf3;padding:10px;border-radius:6px;"></pre>
            <div id="ai-post-connectivity-output" style="margin-top:10px;display:none;padding:10px;border-radius:6px;background:#fff;border:1px solid #e5e7eb;color:#111;"></div>
            <div id="ai-post-volc-imagegen-output" style="margin-top:10px;display:none;padding:10px;border-radius:6px;background:#fff;border:1px solid #e5e7eb;color:#111;"></div>
            <div id="ai-post-volc-imagegen-online-output" style="margin-top:10px;display:none;padding:10px;border-radius:6px;background:#fff;border:1px solid #e5e7eb;color:#111;"></div>
            <div id="ai-post-aliyun-imagegen-output" style="margin-top:10px;display:none;padding:10px;border-radius:6px;background:#fff;border:1px solid #e5e7eb;color:#111;"></div>
            <div id="ai-post-aliyun-imagegen-online-output" style="margin-top:10px;display:none;padding:10px;border-radius:6px;background:#fff;border:1px solid #e5e7eb;color:#111;"></div>
        </div>
        <script>
        (function($){
            var adminAjax = <?php echo json_encode($adminAjax); ?>;
            $('#ai-post-preview-debug-log').on('click', function(){
                var $btn = $(this), $out = $('#ai-post-debug-log-output');
                $btn.prop('disabled', true).text('加载中...');
                $.post(adminAjax, {
                    action: 'ai_post_preview_debug_log',
                    _ajax_nonce: '<?php echo esc_js($nonce); ?>',
                    lines: 200
                }).done(function(res){
                    if(res && res.success){
                        $out.text(res.data.content || '');
                        $out.show();
                    } else {
                        $out.text((res && res.data && res.data.message) ? res.data.message : '加载失败');
                        $out.show();
                    }
                }).fail(function(){
                    $out.text('请求失败').show();
                }).always(function(){
                    $btn.prop('disabled', false).text('预览最近200行');
                });
            });
            $('#ai-post-delete-debug-log').on('click', function(){
                if(!confirm('确认删除调试日志文件？该操作不可恢复！')) return;
                var $btn = $(this), $out = $('#ai-post-debug-log-output');
                $btn.prop('disabled', true).text('删除中...');
                $.post(adminAjax, {action: 'ai_post_delete_debug_log', _ajax_nonce: '<?php echo esc_js($nonce); ?>'}, function(res){
                    if(res && res.success){
                        $out.text('日志已删除。');
                        $out.show();
                        $('#ai-post-download-debug-log').prop('href', '#');
                        $('#ai-post-delete-debug-log').prop('disabled', true);
                    } else {
                        alert((res && res.data && res.data.message) ? res.data.message : '删除失败');
                    }
                }).fail(function(){
                    alert('请求失败');
                }).always(function(){
                    $btn.prop('disabled', true).text('删除日志');
                });
            });
            $('#ai-post-connectivity-check').on('click', function(){
                var $btn = $(this), $out = $('#ai-post-connectivity-output');
                $btn.prop('disabled', true).text('自检中...');
                $out.hide();
                $.post(adminAjax, {action: 'ai_post_connectivity_check', _ajax_nonce: '<?php echo esc_js($connNonce); ?>'}, function(res){
                    if(res && res.success){
                        var data = res.data || {};
                        var html = '';
                        html += '<div><strong>状态码：</strong>' + (data.status || '-') + '</div>';
                        html += '<div><strong>请求URL：</strong>' + (data.url || '-') + '</div>';
                        html += '<div><strong>耗时(ms)：</strong>' + (data.duration_ms || '-') + '</div>';
                        html += '<div style="margin-top:8px;"><strong>响应片段：</strong><pre style="white-space:pre-wrap;word-break:break-word;">' + (data.snippet || '') + '</pre></div>';
                        $out.html(html).show();
                    } else {
                        var msg = (res && res.data && res.data.message) ? res.data.message : '自检失败';
                        $out.text(msg).show();
                    }
                }).fail(function(){
                    $out.text('请求失败').show();
                }).always(function(){
                    $btn.prop('disabled', false).text('一键自检（/v1/models）');
                });
            });

            // 文生图参数自检（豆包，本地，不出网）
            $('#ai-post-volc-imagegen-check').on('click', function(){
                var $btn = $(this), $out = $('#ai-post-volc-imagegen-output');
                $btn.prop('disabled', true).text('校验中...');
                $out.hide();
                $.post(adminAjax, {action: 'ai_post_volc_imagegen_check', _wpnonce: '<?php echo esc_js($volcLocalNonce); ?>'}, function(res){
                    if(res && res.success){
                        var d = res.data || {};
                        var html = '';
                        html += '<div><strong>Endpoint：</strong>' + (d.endpoint || '-') + '</div>';
                        html += '<div><strong>模型：</strong>' + (d.model || '-') + '</div>';
                        html += '<div><strong>尺寸：</strong>' + (d.size || '-') + '</div>';
                        html += '<div><strong>水印：</strong>' + (d.watermark ? '开启' : '关闭') + '</div>';
                        html += '<div><strong>令牌存在：</strong>' + (d.has_key ? '是' : '否') + '</div>';
                        html += '<div style="margin-top:8px;"><strong>示例负载：</strong><pre style="white-space:pre-wrap;word-break:break-word;">' + (d.payload_pretty || '-') + '</pre></div>';
                        $out.html(html).show();
                    } else {
                        var msg = (res && res.data && res.data.message) ? res.data.message : '校验失败';
                        $out.text(msg).show();
                    }
                }).fail(function(){
                    $out.text('请求失败').show();
                }).always(function(){
                    $btn.prop('disabled', false).text('豆包文生图（本地）');
                });
            });

            // 文生图外网连通性（豆包，最小真实调用）
            $('#ai-post-volc-imagegen-online').on('click', function(){
                if(!confirm('该操作将发起一次真实的文生图最小尺寸调用，可能产生少量费用。是否继续？')){ return; }
                var $btn = $(this), $out = $('#ai-post-volc-imagegen-online-output');
                $btn.prop('disabled', true).text('外网连通性自检中...');
                $out.hide();
                $.post(adminAjax, {action: 'ai_post_volc_imagegen_connectivity', _wpnonce: '<?php echo esc_js($volcOnlineNonce); ?>'}, function(res){
                    if(res && res.success){
                        var d = res.data || {};
                        var html = '';
                        html += '<div><strong>HTTP状态：</strong>' + (d.status || '-') + '</div>';
                        html += '<div><strong>耗时：</strong>' + (d.duration_ms || '-') + ' ms</div>';
                        html += '<div><strong>返回URL：</strong>' + (d.url ? ('<a href="'+ d.url +'" target="_blank">' + d.url + '</a>') : '-') + '</div>';
                        html += '<div style="margin-top:8px;"><strong>响应片段：</strong><pre style="white-space:pre-wrap;word-break:break-word;">' + (d.snippet || '-') + '</pre></div>';
                        $out.html(html).show();
                    } else {
                        var msg = (res && res.data && res.data.message) ? res.data.message : '连通性自检失败';
                        $out.text(msg).show();
                    }
                }).fail(function(){
                    $out.text('请求失败').show();
                }).always(function(){
                    $btn.prop('disabled', false).text('豆包文生图（外网）');
                });
            });

            // 阿里云参数自检（本地，不出网）
            $('#ai-post-aliyun-imagegen-check').on('click', function(){
                var $btn = $(this), $out = $('#ai-post-aliyun-imagegen-output');
                $btn.prop('disabled', true).text('校验中...');
                $out.hide();
                $.post(adminAjax, {action: 'ai_post_aliyun_imagegen_check', _wpnonce: '<?php echo esc_js($aliyunLocalNonce); ?>'}, function(res){
                    if(res && res.success){
                        var d = res.data || {};
                        var html = '';
                        html += '<div><strong>Endpoint：</strong>' + (d.endpoint || '-') + '</div>';
                        html += '<div><strong>模型：</strong>' + (d.model || '-') + '</div>';
                        html += '<div><strong>尺寸：</strong>' + (d.size || '-') + '</div>';
                        html += '<div><strong>数量 n：</strong>' + (d.n || '-') + '</div>';
                        html += '<div><strong>令牌存在：</strong>' + (d.has_key ? '是' : '否') + '</div>';
                        if(d.model === 'qwen-image'){
                            html += '<div><strong>prompt_extend：</strong>' + (d.prompt_extend ? 'true' : 'false') + '</div>';
                            html += '<div><strong>watermark：</strong>' + (d.watermark ? 'true' : 'false') + '</div>';
                        }
                        if(d.model === 'wanx-v1'){
                            html += '<div><strong>style：</strong>' + (d.style || '<auto>') + '</div>';
                        }
                        html += '<div style="margin-top:8px;"><strong>示例负载：</strong><pre style="white-space:pre-wrap;word-break:break-word;">' + (d.payload_pretty || '-') + '</pre></div>';
                        $out.html(html).show();
                    } else {
                        var msg = (res && res.data && res.data.message) ? res.data.message : '校验失败';
                        $out.text(msg).show();
                    }
                }).fail(function(){
                    $out.text('请求失败').show();
                }).always(function(){
                    $btn.prop('disabled', false).text('阿里云文生图（本地）');
                });
            });

            // 阿里云外网连通性（最小真实调用）
            $('#ai-post-aliyun-imagegen-online').on('click', function(){
                if(!confirm('该操作将发起一次真实的阿里云文生图最小尺寸调用，可能产生少量费用。是否继续？')){ return; }
                var $btn = $(this), $out = $('#ai-post-aliyun-imagegen-online-output');
                $btn.prop('disabled', true).text('外网连通性自检中...');
                $out.hide();
                $.post(adminAjax, {action: 'ai_post_aliyun_imagegen_connectivity', _wpnonce: '<?php echo esc_js($aliyunOnlineNonce); ?>'}, function(res){
                    if(res && res.success){
                        var d = res.data || {};
                        var html = '';
                        html += '<div><strong>HTTP状态：</strong>' + (d.status || '-') + '</div>';
                        html += '<div><strong>耗时：</strong>' + (d.duration_ms || '-') + ' ms</div>';
                        html += '<div><strong>响应片段：</strong><pre style="white-space:pre-wrap;word-break:break-word;">' + (d.snippet || '-') + '</pre></div>';
                        $out.html(html).show();
                    } else {
                        var msg = (res && res.data && res.data.message) ? res.data.message : '连通性自检失败';
                        $out.text(msg).show();
                    }
                }).fail(function(){
                    $out.text('请求失败').show();
                }).always(function(){
                    $btn.prop('disabled', false).text('阿里云文生图（外网）');
                });
            });
        })(jQuery);
        </script>
        <?php
    }

    // 获取调试日志路径（与 Plugin.php 策略一致）
    private function resolve_debug_log_path(): ?string
    {
        foreach ($this->get_debug_log_candidates() as $p) {
            $dir = dirname($p);
            if (!@file_exists($dir)) {
                @wp_mkdir_p($dir);
            }
            // 若文件已存在或目录可写，返回该路径
            if ((@file_exists($p) && @is_writable($p)) || (@is_dir($dir) && @is_writable($dir))) {
                return $p;
            }
        }
        return null;
    }

    // 计算调试日志路径候选
    private function get_debug_log_candidates(): array
    {
        $root = rtrim(defined('ABSPATH') ? ABSPATH : dirname(__FILE__, 5), "/\\");
        $target = $root . DIRECTORY_SEPARATOR . 'debug.log';
        $candidates = [$target];
        if (defined('WP_CONTENT_DIR')) {
            $uploadsDir = rtrim(WP_CONTENT_DIR, '/\\') . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'ai-post' . DIRECTORY_SEPARATOR . 'logs';
            $candidates[] = $uploadsDir . DIRECTORY_SEPARATOR . 'debug.log';
        }
        return $candidates;
    }

    // AJAX：预览日志（返回最近N行）
    public function ajax_preview_debug_log(): void
    {
        \check_ajax_referer('ai_post_debug_log');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $path = $this->resolve_debug_log_path();
        if (!$path || !@file_exists($path)) {
            \wp_send_json_error(['message' => '调试日志文件不存在']);
        }

        $lines = isset($_POST['lines']) ? (int) $_POST['lines'] : 200;
        $lines = max(1, min(2000, $lines));

        $content = '';
        $all = @file($path, FILE_IGNORE_NEW_LINES);
        if ($all === false) {
            \wp_send_json_error(['message' => '读取日志失败']);
        }
        $total = count($all);
        if ($total > $lines) {
            $slice = array_slice($all, $total - $lines, $lines);
        } else {
            $slice = $all;
        }
        $content = implode("\n", $slice);

        // 中文编码尽量转为 UTF-8
        try {
            $enc = null;
            if (function_exists('mb_detect_encoding')) {
                $enc = @mb_detect_encoding($content, ['UTF-8', 'GB18030', 'GBK', 'GB2312', 'BIG5', 'ISO-8859-1'], true);
            }
            $is_utf8 = ($enc === 'UTF-8') || (function_exists('seems_utf8') && seems_utf8($content));
            if (!$is_utf8) {
                $from = $enc ?: 'GB18030';
                if (function_exists('mb_convert_encoding')) {
                    $converted = @mb_convert_encoding($content, 'UTF-8', $from);
                    if (is_string($converted) && $converted !== '') { $content = $converted; }
                } elseif (function_exists('iconv')) {
                    $converted = @iconv($from, 'UTF-8//IGNORE', $content);
                    if (is_string($converted) && $converted !== '') { $content = $converted; }
                }
            }
        } catch (\Throwable $e) {
            // ignore
        }

        \wp_send_json_success(['content' => $content]);
    }

    // AJAX：下载调试日志
    public function ajax_download_debug_log(): void
    {
        \check_ajax_referer('ai_post_debug_log');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $path = $this->resolve_debug_log_path();
        if (!$path || !@file_exists($path)) {
            \wp_send_json_error(['message' => '调试日志文件不存在']);
        }

        if (function_exists('nocache_headers')) { \nocache_headers(); }
        $filename = 'debug.log';
        $size = @filesize($path);
        \header('Content-Type: text/plain; charset=UTF-8');
        \header('Content-Disposition: attachment; filename=' . $filename);
        if ($size !== false) { \header('Content-Length: ' . $size); }
        \header('X-Content-Type-Options: nosniff');
        while (ob_get_level() > 0) { @ob_end_clean(); }
        @readfile($path);
        exit;
    }

    // AJAX：删除调试日志
    public function ajax_delete_debug_log(): void
    {
        \check_ajax_referer('ai_post_debug_log');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $path = $this->resolve_debug_log_path();
        if (!$path || !@file_exists($path)) {
            \wp_send_json_success(['message' => '日志文件不存在，无需删除']);
        }

        $ok = @unlink($path);
        if (!$ok) {
            \wp_send_json_error(['message' => '删除失败：可能无权限或文件被占用']);
        }
        \wp_send_json_success(['message' => '删除成功']);
    }

    // AJAX：基于数据库的“今日统计概况”
    public function ajax_debug_log_stats(): void
    {
        \check_ajax_referer('ai_post_debug_log');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        try {
            $now_ts = \current_time('timestamp');
            $today_start = strtotime('today', $now_ts);
            $common_args = [
                'post_type'      => 'post',
                'posts_per_page' => 1,
                'fields'         => 'ids',
                'meta_query'     => [[ 'key' => '_ai_post_generated', 'value' => '1' ]],
                'date_query'     => [[ 'after' => [
                    'year'  => (int) date('Y', $today_start),
                    'month' => (int) date('n', $today_start),
                    'day'   => (int) date('j', $today_start),
                ], 'inclusive' => true ]],
                'no_found_rows' => false,
                'ignore_sticky_posts' => true,
            ];
            $q_publish = new \WP_Query(array_merge($common_args, ['post_status' => 'publish']));
            $published = (int) ($q_publish->found_posts ?? 0);
            $q_draft = new \WP_Query(array_merge($common_args, ['post_status' => 'draft']));
            $draft = (int) ($q_draft->found_posts ?? 0);
            $generated = $published + $draft;
            \wp_send_json_success([
                'generated' => $generated,
                'published' => $published,
                'draft'     => $draft,
                'from'      => date_i18n('Y-m-d H:i:s', $today_start),
                'now'       => date_i18n('Y-m-d H:i:s', $now_ts),
            ]);
        } catch (\Throwable $e) {
            \wp_send_json_error(['message' => '统计失败：' . $e->getMessage()]);
        }
    }
}
