<?php

namespace HaoZiTeam\AIPost\Service;

use CGPS;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitFontTools;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitDebugLog;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitImageGenCheck;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitSelfDiagnose;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitExportImport;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitTasksRouteAndValidate;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitPromptPresets;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitRunLogPanel;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitVersionInfo;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitCronTokenPanel;
use HaoZiTeam\AIPost\Service\Settings\Traits\TraitAdminInjections;

defined('ABSPATH') || exit;

class Setting
{
    use TraitFontTools;
    use TraitDebugLog;
    use TraitImageGenCheck;
    use TraitSelfDiagnose;
    use TraitExportImport;
    use TraitTasksRouteAndValidate;
    use TraitPromptPresets;
    use TraitRunLogPanel;
    use TraitVersionInfo;
    use TraitCronTokenPanel;
    use TraitAdminInjections;

    private string $prefix = 'ai-post';
    /**
     * 标记：系统调试与日志面板是否已通过回调渲染。
     */
    protected bool $debug_panel_rendered = false;
    // CA 状态日志输出逻辑已迁移至 TraitSelfDiagnose::maybe_log_ca_status_on_admin_init()
    
    // （方法已迁移至 TraitPromptPresets）

    // （方法已迁移至 TraitPromptPresets）

    // （方法已迁移至 TraitDebugLog）

    // （方法已迁移至 TraitSelfDiagnose）

    // 通信令牌（Cron/REST）面板已迁移至 TraitCronTokenPanel::render_cron_token_panel()

    // 适配 CGPS 的 AJAX 保存：$_POST['data'] 为 JSON，含 ai-post/ai-post-tasks
    // （方法已迁移至 TraitTasksRouteAndValidate）

    // 校验：每个任务的文章步骤最后一项必须“接收回复=true 且 接收回复作为=主体(content)”
    // 若不满足：阻止保存（返回旧值），并设置一次性提示。
    // （方法已迁移至 TraitTasksRouteAndValidate）

    // 在后台顶部输出一次性提示
    // （方法已迁移至 TraitTasksRouteAndValidate）

    // 页脚注入：AJAX 保存失败后，移除灰层并展示友好提示，避免界面卡住
    // （方法已迁移至 TraitTasksRouteAndValidate）

    // AJAX：火山 Ark 文生图外网连通性自检（真调用，最小尺寸）
    // （方法已迁移至 TraitImageGenCheck）

    // AJAX：OpenAI 兼容端点连通性自检（/v1/models）
    // （方法已迁移至 TraitImageGenCheck）

    // AJAX：OpenAI 兼容端点连通性自检（/v1/models）
    public function ajax_connectivity_check(): void
    {
        \check_ajax_referer('ai_post_connectivity_check');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $opts = \get_option('ai-post', []);
        if (!is_array($opts)) { $opts = []; }

        $type = $opts['api-server-type'] ?? 'custom';
        if (!in_array($type, ['openai','custom','', null], true)) {
            \wp_send_json_error(['message' => '当前仅支持 OpenAI 兼容/自定义端点的自检']);
        }

        // 选择 server 与 key（参考 ApiClientService 的优先级，简化为全局 openai-accounts/cardPwd/cardNum）
        $server = $opts['openai-api-server'] ?? 'https://sk.slapi.cn/';
        $apiKey = '';
        if (!empty($opts['openai-accounts']) && is_array($opts['openai-accounts'])) {
            $accounts = $opts['openai-accounts'];
            if (!empty($accounts)) {
                $idx = rand(1, count($accounts));
                $acc = $accounts[$idx - 1];
                $apiKey = trim((string)($acc['account-secret-key'] ?? ''));
            }
        }
        if (!$apiKey && !empty($opts['cardPwd'])) { $apiKey = trim((string)$opts['cardPwd']); }
        if (!$apiKey && !empty($opts['cardNum'])) { $apiKey = trim((string)$opts['cardNum']); }

        if (!$apiKey) {
            \wp_send_json_error(['message' => '未找到可用的 API Key，请在设置中填写 OpenAI 兼容密钥']);
        }

        // 规范 server：确保以单一 /v1/ 结尾
        $server = trim((string)$server);
        $server = rtrim($server, "/\t\n\r ");
        if (!preg_match('#/v1/?$#', $server)) {
            $server = rtrim($server, '/') . '/v1';
        }
        if (substr($server, -1) !== '/') { $server .= '/'; }

        $url = $server . 'models';
        $args = [
            'timeout' => 30,
            'headers' => [
                'Authorization' => 'Bearer ' . $apiKey,
                'Content-Type'  => 'application/json',
            ],
        ];

        $start = microtime(true);
        $resp = \wp_remote_get($url, $args);
        $duration = (int) round((microtime(true) - $start) * 1000);

        if (is_wp_error($resp)) {
            \wp_send_json_error(['message' => '请求失败：' . $resp->get_error_message()]);
        }

        $code = (int) wp_remote_retrieve_response_code($resp);
        $body = (string) wp_remote_retrieve_body($resp);
        $snippet = mb_substr($body, 0, 500, 'UTF-8');

        \wp_send_json_success([
            'status' => $code,
            'url' => $url,
            'duration_ms' => $duration,
            'snippet' => $snippet,
        ]);
    }

    // AJAX：火山 Ark 文生图参数自检（不发起外部请求，仅校验并回显即将发送的负载）
    public function ajax_volc_imagegen_check(): void
    {
        \check_ajax_referer('ai_post_volc_imagegen_check');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $opts = \get_option('ai-post', []);
        if (!is_array($opts)) { $opts = []; }

        // 读取 ImageGenerations 相关配置（API级尺寸已移除，这里仅展示占位尺寸）
        $model = (string) ($opts['doubao-imagegen-model'] ?? 'doubao-seedream-3-0-t2i-250415');
        $size  = '1024x768';
        $watermark = (bool) ($opts['doubao-imagegen-watermark'] ?? false);

        // 检查是否存在至少一个豆包令牌
        $hasKey = false;
        if (!empty($opts['doubao-accounts']) && is_array($opts['doubao-accounts'])) {
            foreach ($opts['doubao-accounts'] as $acc) {
                $k = isset($acc['account-secret-key']) ? trim((string)$acc['account-secret-key']) : '';
                if ($k !== '') { $hasKey = true; break; }
            }
        }

        $endpoint = 'https://ark.cn-beijing.volces.com/api/v3/images/generations';
        $payload = [
            'model' => $model,
            'prompt' => 'Sanity check prompt (will not be sent).',
            'response_format' => 'url',
            'size' => $size,
            'watermark' => $watermark,
        ];

        \wp_send_json_success([
            'endpoint' => $endpoint,
            'model' => $model,
            'size' => $size,
            'watermark' => $watermark,
            'has_key' => $hasKey,
            'payload' => $payload,
            'payload_pretty' => wp_json_encode($payload, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE),
        ]);
    }

    // AJAX：阿里云（DashScope）文生图参数自检（不发起外部请求，仅校验并回显即将发送的负载）
    public function ajax_aliyun_imagegen_check(): void
    {
        \check_ajax_referer('ai_post_aliyun_imagegen_check');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $opts = \get_option('ai-post', []);
        if (!is_array($opts)) { $opts = []; }

        // 读取阿里云文生图默认配置（如未配置则采用文档示例默认）
        $model = (string)($opts['aliyun-imagegen-model'] ?? 'wan2.2-t2i-flash');
        // API级尺寸与数量已移除，由任务级决定；此处仅用于展示时给出模型对应的推荐尺寸与固定 n=1 的占位
        $size = ($model === 'qwen-image') ? '1328*1328' : '1024*1024';
        $n     = 1; // 仅展示；真实请求数量由任务级参数控制
        $promptExtend = (bool)($opts['aliyun-imagegen-prompt-extend'] ?? true);
        $watermark    = (bool)($opts['aliyun-imagegen-watermark'] ?? true);
        $style        = (string)($opts['aliyun-imagegen-style'] ?? '<auto>');

        // 检查是否存在至少一个阿里百炼令牌
        $hasKey = false;
        if (!empty($opts['bai-lian-accounts']) && is_array($opts['bai-lian-accounts'])) {
            foreach ($opts['bai-lian-accounts'] as $acc) {
                $k = isset($acc['account-secret-key']) ? trim((string)$acc['account-secret-key']) : '';
                if ($k !== '') { $hasKey = true; break; }
            }
        }

        $endpoint = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis';
        $payload = [
            'model' => $model,
            'input' => [
                'prompt' => 'Sanity check prompt (will not be sent).',
            ],
            'parameters' => array_filter([
                // 尺寸与数量由任务级决定；此处仅用于自检展示推荐值
                'size' => $size,
                'n'    => $n,
                // qwen-image 专属
                'prompt_extend' => ($model === 'qwen-image') ? $promptExtend : null,
                'watermark'     => ($model === 'qwen-image') ? $watermark : null,
                // wanx-v1 专属
                'style' => ($model === 'wanx-v1') ? $style : null,
            ], function($v){ return $v !== null; })
        ];

        \wp_send_json_success([
            'endpoint' => $endpoint,
            'model' => $model,
            'size' => $size,
            'n' => $n,
            'prompt_extend' => $promptExtend,
            'watermark' => $watermark,
            'style' => $style,
            'has_key' => $hasKey,
            'payload' => $payload,
            'payload_pretty' => wp_json_encode($payload, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE),
        ]);
    }

    // AJAX：阿里云（DashScope）文生图外网连通性自检（真调用，最小尺寸）
    public function ajax_aliyun_imagegen_connectivity(): void
    {
        \check_ajax_referer('ai_post_aliyun_imagegen_connectivity');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $opts = \get_option('ai-post', []);
        if (!is_array($opts)) { $opts = []; }

        // 选择一个可用的阿里百炼秘钥
        $apiKey = '';
        if (!empty($opts['bai-lian-accounts']) && is_array($opts['bai-lian-accounts'])) {
            foreach ($opts['bai-lian-accounts'] as $acc) {
                $k = isset($acc['account-secret-key']) ? trim((string)$acc['account-secret-key']) : '';
                if ($k !== '') { $apiKey = $k; break; }
            }
        }
        if ($apiKey === '') {
            \wp_send_json_error(['message' => '未检测到可用的阿里百炼 API Key（请在“阿里百炼 令牌列表”中配置 account-secret-key）']);
        }

        $model = (string) ($opts['aliyun-imagegen-model'] ?? 'wan2.2-t2i-flash');
        // 连接性自检为最小有效调用，这里采用各模型推荐的最小尺寸，数量固定 1。
        $size = ($model === 'qwen-image') ? '1328*1328' : '1024*1024';
        $n = 1;
        $promptExtend = (bool)($opts['aliyun-imagegen-prompt-extend'] ?? true);
        $watermark    = (bool)($opts['aliyun-imagegen-watermark'] ?? true);
        $style        = (string)($opts['aliyun-imagegen-style'] ?? '<auto>');

        $endpoint = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis';
        $payload = [
            'model' => $model,
            'input' => [
                'prompt' => 'Connectivity test from AI-Post plugin. Please generate a simple abstract background. This is a minimal test call.'
            ],
            'parameters' => array_filter([
                'size' => $size,
                'n'    => $n,
                'prompt_extend' => ($model === 'qwen-image') ? $promptExtend : null,
                'watermark'     => ($model === 'qwen-image') ? $watermark : null,
                'style' => ($model === 'wanx-v1') ? $style : null,
            ], function($v){ return $v !== null; })
        ];
        $json = \wp_json_encode($payload);

        $headers = [
            'Content-Type: application/json',
            'Accept: application/json',
            'Authorization: Bearer ' . $apiKey,
            'X-DashScope-Async: enable',
        ];

        $pluginRoot = \dirname(__DIR__);
        $caFile = $pluginRoot . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'cacert.pem';

        $ch = \curl_init($endpoint);
        if ($ch === false) {
            \wp_send_json_error(['message' => 'cURL 初始化失败']);
        }
        \curl_setopt($ch, CURLOPT_POST, true);
        \curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        \curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        \curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        \curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        if (@file_exists($caFile)) {
            \curl_setopt($ch, CURLOPT_CAINFO, $caFile);
        }

        $start = microtime(true);
        $response = \curl_exec($ch);
        $duration = (int) ((microtime(true) - $start) * 1000);
        $errno = \curl_errno($ch);
        $error = \curl_error($ch);
        $httpCode = (int) \curl_getinfo($ch, CURLINFO_HTTP_CODE);
        \curl_close($ch);

        if ($errno) {
            \wp_send_json_error(['message' => 'cURL 错误: ' . $errno . ' ' . $error]);
        }

        $snippet = is_string($response) ? mb_substr($response, 0, 1000) : '';
        $data = json_decode((string)$response, true);
        if (!is_array($data)) {
            \wp_send_json_error([
                'message' => '响应解析失败',
                'status' => $httpCode,
                'duration_ms' => $duration,
                'snippet' => $snippet,
            ]);
        }

        if ($httpCode < 200 || $httpCode >= 300) {
            $msg = $data['error']['message'] ?? ('HTTP ' . $httpCode);
            \wp_send_json_error([
                'message' => 'HTTP错误: ' . $msg,
                'status' => $httpCode,
                'duration_ms' => $duration,
                'snippet' => $snippet,
            ]);
        }

        \wp_send_json_success([
            'status' => $httpCode,
            'duration_ms' => $duration,
            'snippet' => $snippet,
        ]);
    }

    // AJAX：ImageGenerations 参数自检（不发起外部请求，仅校验并回显即将发送的负载）
    public function ajax_imagegen_check(): void
    {
        \check_ajax_referer('ai_post_imagegen_check');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }

        $opts = \get_option('ai-post', []);
        if (!is_array($opts)) { $opts = []; }

        // 读取 ImageGenerations 相关配置
        $model = (string) ($opts['imagegen-model'] ?? '');
        $size  = (string) ($opts['imagegen-size'] ?? '1024x768');
        if ($size === 'custom') {
            $w = (int) ($opts['imagegen-custom-width'] ?? 1024);
            $h = (int) ($opts['imagegen-custom-height'] ?? 768);
            $size = $w . 'x' . $h;
        }
        $watermark = (bool) ($opts['imagegen-watermark'] ?? false);

        // 检查是否存在至少一个 ImageGenerations 令牌
        $hasKey = false;
        if (!empty($opts['imagegen-accounts']) && is_array($opts['imagegen-accounts'])) {
            foreach ($opts['imagegen-accounts'] as $acc) {
                $k = isset($acc['account-secret-key']) ? trim((string)$acc['account-secret-key']) : '';
                if ($k !== '') { $hasKey = true; break; }
            }
        }

        $endpoint = 'https://api.openai.com/v1/images/generations';
        $payload = [
            'model' => $model,
            'prompt' => 'Sanity check prompt (will not be sent).',
            'response_format' => 'url',
            'size' => $size,
            'watermark' => $watermark,
        ];

        \wp_send_json_success([
            'endpoint' => $endpoint,
            'model' => $model,
            'size' => $size,
            'watermark' => $watermark,
            'has_key' => $hasKey,
            'payload' => $payload,
            'payload_pretty' => wp_json_encode($payload, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE),
        ]);
    }

    // （方法已迁移至 TraitDebugLog）

    // （方法已迁移至 TraitDebugLog）

    // （方法已迁移至 TraitDebugLog）

    // （方法已迁移至 TraitDebugLog）

    public function __construct()
    {
        \add_filter('cgps_welcome_page', '__return_false');

        // 恢复：初始化、资源与保存前校验钩子
        $this->admin_init();
        \add_action('admin_enqueue_scripts', function(){
            \wp_enqueue_code_editor(['type' => 'text/css']);
        });
        // 保存前校验：文章步骤最后一步必须为“主体且接收回复”
        \add_filter('pre_update_option_ai-post', [$this, 'validate_steps_before_save'], 10, 3);
        // 兼容某些版本/分离存储：任务可能保存在 ai-post-tasks 选项
        \add_filter('pre_update_option_ai-post-tasks', [$this, 'validate_steps_before_save'], 10, 3);
        // 只读日志回显：任务保存前把关键图像生成开关与参数输出到 debug.log（不改变入库值）
        \add_filter('pre_update_option_ai-post-tasks', [$this, 'log_task_flags_on_save'], 20, 3);
        // 在 CGPS 提交阶段进行一次校验
        \add_filter('ajax_save', [$this, 'validate_steps_on_ajax_save']);
        // 错误提示与UI恢复
        \add_action('admin_notices', [$this, 'maybe_show_steps_validation_notice']);
        \add_action('admin_footer', [$this, 'inject_ajax_fail_recovery_js']);
        // 方案A：统一写入 ai-post-tasks（在通过校验之后再路由）
        \add_filter('pre_update_option_ai-post', [$this, 'route_tasks_on_save'], 20, 3);

        // 方案A（读取端合并）：任何位置读取 ai-post 时，自动把 ai-post-tasks 合并到内存视图，
        // 确保设置页/表单渲染等仍能看到任务列表，避免“刷新后任务消失”的错觉。
        \add_filter('option_ai-post', [$this, 'merge_tasks_into_ai_post'], 10, 1);

        // 展示一次性提示：任务已被路由到独立选项
        \add_action('admin_notices', [$this, 'maybe_show_tasks_routed_notice']);

        // 保存前：阻止过期卡密入库，并在后台显示一次性错误提示
        \add_filter('pre_update_option_ai-post', [$this, 'guard_expired_on_save'], 5, 3);
        \add_action('admin_notices', [$this, 'maybe_show_expired_notice']);

        // AJAX：运行日志表格与保留天数
        \add_action('wp_ajax_ai_post_get_runlog_table', [$this, 'ajax_get_runlog_table']);
        \add_action('wp_ajax_ai_post_save_retention_days', [$this, 'handle_save_retention_days']);

        // 前端：授权过期则禁用保存按钮
        \add_action('admin_footer', [$this, 'inject_license_expire_guard_js']);

        // AJAX：调试日志 预览/下载/删除
        \add_action('wp_ajax_ai_post_preview_debug_log', [$this, 'ajax_preview_debug_log']);
        \add_action('wp_ajax_ai_post_download_debug_log', [$this, 'ajax_download_debug_log']);
        \add_action('wp_ajax_ai_post_delete_debug_log', [$this, 'ajax_delete_debug_log']);
        
        // AJAX：授权即时校验
        \add_action('wp_ajax_ai_post_check_license', [$this, 'ajax_check_license']);
        
        // AJAX：连通性与参数自检
        \add_action('wp_ajax_ai_post_connectivity_check', [$this, 'ajax_connectivity_check']);
        \add_action('wp_ajax_ai_post_volc_imagegen_check', [$this, 'ajax_volc_imagegen_check']);
        \add_action('wp_ajax_ai_post_volc_imagegen_connectivity', [$this, 'ajax_volc_imagegen_connectivity']);
        \add_action('wp_ajax_ai_post_aliyun_imagegen_check', [$this, 'ajax_aliyun_imagegen_check']);
        \add_action('wp_ajax_ai_post_aliyun_imagegen_connectivity', [$this, 'ajax_aliyun_imagegen_connectivity']);
        
        // AJAX：今日统计
        \add_action('wp_ajax_ai_post_debug_log_stats', [$this, 'ajax_debug_log_stats']);

        // 导出/导入设置（AJAX）
        if (is_admin()) {
            \add_action('wp_ajax_ai_post_export_settings', [$this, 'handle_export_settings']);
            \add_action('wp_ajax_ai_post_import_settings', [$this, 'handle_import_settings']);
            \add_action('wp_ajax_ai_post_self_diagnose', [$this, 'ajax_self_diagnose']);
        }
    }
    public function admin_init(): void
    {
        // 节流：5 分钟内只打印一次“正在初始化插件设置...”，避免频繁刷屏
        $init_throttle_key = 'aipost_admin_init_log_last';
        $should_log_init = true;
        if (function_exists('get_transient')) {
            $should_log_init = !get_transient($init_throttle_key);
        }
        if ($should_log_init) {
            error_log('正在初始化插件设置...');
            if (function_exists('set_transient')) {
                set_transient($init_throttle_key, time(), 5 * MINUTE_IN_SECONDS);
            }
        }

        // 仅在本插件设置页输出“方式二字体工具”前端脚本（从 Plugin.php 迁移）
        if (isset($_GET['page']) && $_GET['page'] === 'ai-post') { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            \add_action('admin_footer', [$this, 'render_font_tools_inline']);
            // 兜底：若 CGPS 未调用回调渲染“系统调试与日志”面板，则在页脚兜底输出一次
            \add_action('admin_footer', [$this, 'maybe_fallback_render_debug_panel'], 99);
        }

        // 追加（节流）：初始化阶段输出一次当前 CA 状态（逻辑迁移至 TraitSelfDiagnose）
        if (method_exists($this, 'maybe_log_ca_status_on_admin_init')) {
            $this->maybe_log_ca_status_on_admin_init();
        } else {
            // 兼容旧缓存环境，避免致命错误
            error_log('AI Post SSL: maybe_log_ca_status_on_admin_init() not available yet (cache/autoload), skip this round.');
        }
        // 初始化后台菜单与设置（占位符已移除）
        
        // 构建版本显示文本（迁移至 TraitVersionInfo）
        $version_text = $this->build_version_footer_text();

        // 修改菜单注册方式，以支持多站点
        $menu_type = 'submenu';
        $menu_parent = 'options-general.php';
        $capability = 'manage_options';

        // 如果是在子站点中，使用子站点菜单
        if (is_multisite() && !is_main_site() && !is_network_admin()) {
            $menu_type = 'submenu';
            $menu_parent = 'options-general.php';
            $capability = 'manage_options';
        }

        CGPS::createOptions($this->prefix, [
            'framework_title' => '<script src="https://prompt.suqianweb.cn/carousel.js" defer></script>
            <div id="carousel-text" style="display:inline-flex; align-items:center; gap:8px;">
                <span class="loading-spinner" style="
                    display: inline-block;
                    width: 16px;
                    height: 16px;
                    border: 2px solid #2271b1;
                    border-radius: 50%;
                    border-top-color: transparent;
                    animation: spin 0.8s linear infinite;
                "></span>
                正在初始化插件设置...
            </div>
            <style>
                @keyframes spin {
                    to { transform: rotate(360deg); }
                }
                .loading-spinner {
                    vertical-align: middle;
                }
            </style>',
            'menu_title' => 'AI Post',
            'menu_slug' => 'ai-post',
            'menu_type' => $menu_type,
            'menu_parent' => $menu_parent,
            'capability' => $capability,
            'show_bar_menu' => false,
            'show_sub_menu' => false,
            'show_search' => false,
            'footer_text' => $version_text,
            'theme' => 'light',
        ]);

        CGPS::createSection($this->prefix, [
            'title' => '插件授权',
            'fields' => [
                [
                    'type' => 'callback',
                    'title' => '授权操作',
                    'function' => [$this, 'render_license_block'],
                ],

                [
                    'id' => 'cardNum',
                    'type' => 'text',
                    'title' => '授权卡号',
                    'desc' => '输入购买的授权卡号：为19为纯数字',
                ],
                [
                    'id' => 'cardPwd',
                    'type' => 'text',
                    'title' => '授权卡密',
                    'desc' => '输入购买的授权卡密：字母和数字组合，保存后刷新页面查看授权期限',
                ]

            ],
        ]);

        CGPS::createSection($this->prefix, [
            'title' => 'API设置',
            'fields' => [
                // API 服务器类型选择
                [
                    'id' => 'api-server-type',
                    'type' => 'button_set',
                    'title' => 'API 服务器类型',
                    'options' => [
                        'custom' => '<div class="server-type-block"><img src="' . plugins_url('/assets/images/slapi.png', __FILE__) . '" class="api-logo" alt="自定义服务器"><span>自定义服务器</span><small>支持gpt及满血版deepseek</small></div>',
                        'deepseek' => '<div class="server-type-block"><img src="' . plugins_url('/assets/images/deepseek-copy.png', __FILE__) . '" class="api-logo" alt="DeepSeek API"><span>DeepSeek API</span><small>使用 DeepSeek 官方 API</small></div>',
                        'doubao' => '<div class="server-type-block"><img src="' . plugins_url('/assets/images/huoshan.png', __FILE__) . '" class="api-logo" alt="豆包 API"><span>豆包 API <span class="t2i-badge" title="支持文生图">文生图</span></span><small>使用火山方舟豆包 API</small></div>',
                        'bai-lian' => '<div class="server-type-block"><img src="' . plugins_url('/assets/images/alibaba.png', __FILE__) . '" class="api-logo" alt="阿里百炼 API"><span>阿里百炼 API <span class="t2i-badge" title="支持文生图">文生图</span></span><small>使用阿里云百炼 API</small></div>',
                        // 使用内联 SVG 图标，避免缺失 baidu.png
                        'wenxin' => '<div class="server-type-block"><img src="data:image/svg+xml;utf8,<?xml version=\'1.0\' encoding=\'UTF-8\'?><svg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\'><defs/><rect x=\'0\' y=\'0\' width=\'24\' height=\'24\' rx=\'4\' fill=\'%232271b1\'/><text x=\'50%\' y=\'50%\' dominant-baseline=\'middle\' text-anchor=\'middle\' font-family=\'system-ui, -apple-system, Segoe UI, Roboto\' font-size=\'12\' fill=\'%23ffffff\'>度</text></svg>" class="api-logo" alt="文心一言 API"><span>文心一言 API</span><small>使用百度文心一言 API</small></div>'
                    ],
                    'default' => 'custom',
                    'desc' => '选择要使用的 API 服务器类型',
                    'class' => 'server-type-selector',
                    'after' => '<style>
                        .server-type-selector .cgps--button-group {
                            display: flex;
                            gap: 10px;
                            margin-bottom: 15px;
                        }
                        .server-type-selector .cgps--button {
                            flex: 1;
                            max-width: 180px;
                            border: 1px solid #ddd;
                            border-radius: 6px;
                            padding: 10px;
                            text-align: center;
                            cursor: pointer;
                            transition: all 0.3s ease;
                            background: #fff; /* 确保背景是白色 */
                            height: auto; /* 允许按钮自适应高度 */
                        }
                        .server-type-selector .cgps--button:hover {
                            border-color: #2271b1;
                            background: #f0f6fc;
                        }
                        .server-type-selector .cgps--active {
                            border-color: #2271b1;
                            background: #f0f6fc;
                        }
                        .server-type-block {
                            display: flex;
                            flex-direction: column;
                            align-items: center;
                            gap: 5px; /* 增加一点间距 */
                        }
                        /* 移除旧的 i 标签样式 */
                        /* .server-type-block i { ... } */
                        .api-logo { /* 新增图片样式 */
                            width: 24px; /* 或您希望的尺寸 */
                            height: 24px; /* 或您希望的尺寸 */
                            margin-bottom: 5px; /* 图片下方间距 */
                            object-fit: contain; /* 保持图片比例 */
                        }
                        .server-type-block span {
                            font-size: 13px;
                            font-weight: 500;
                            color: #2271b1;
                        }
                        .server-type-block small {
                            font-size: 11px;
                            color: #666;
                        }
                        .t2i-badge {
                            display: inline-block;
                            margin-left: 6px;
                            padding: 1px 6px;
                            font-size: 10px;
                            line-height: 1.6;
                            color: #fff;
                            background: #2271b1; /* WP blue */
                            border-radius: 9999px;
                            vertical-align: middle;
                        }
                        /* 提高优先级，避免被 .server-type-block span 的颜色覆盖 */
                        .server-type-block .t2i-badge { color: #fff !important; }
                    </style>'
                ],
                // 自定义服务器配置
                [
                    'id' => 'openai-api-server',
                    'type' => 'text',
                    'title' => 'API 服务器',
                    'subtitle' => 'API 接口地址',
                    'desc' => '使用默认API服务器地址https://sk.slapi.cn/</code>',
                    'default' => 'https://sk.slapi.cn/',
                    'dependency' => [['api-server-type', '==', 'custom']]
                ],
                // DeepSeek API 和豆包 API 地址已内置，无需用户配置
                // 自定义服务器令牌配置
                [
                    'id' => 'openai-accounts',
                    'type' => 'group',
                    'title' => '令牌列表',
                    'subtitle' => '添加 AI 令牌',
                    'desc' => '添加多个 AI 令牌，将会自动进行轮询，以降低账号被限制的风险',
                    'button_title' => '添加令牌',
                    'accordion_title_number' => true,
                    'dependency' => [['api-server-type', '==', 'custom']],
                    'fields' => [
                        [
                            'id' => 'account-note',
                            'type' => 'text',
                            'title' => '令牌备注',
                            'desc' => '令牌备注，用于区分令牌',
                        ],
                        [
                            'id' => 'account-secret-key',
                            'type' => 'text',
                            'title' => '令牌',
                            'subtitle' => 'sk-开头的Key',
                            'desc' => '前后都不要有空格！！！,<a href="https://sk.slapi.cn/" target="_blank">链接直达</a>',
                        ],
                        [
                            'id' => 'model-selection',
                            'type' => 'select',
                            'title' => '选择模型',
                            'options' => [
                                'gpt-4o-mini' => 'gpt-4o-mini低价稳定高效',
                                'gpt-4o-mini-2024-07-18' => 'gpt-4o-mini-2024-07-18',
                                'gpt-4o' => 'gpt-4o',
                                'gpt-4o-2024-05-13' => 'gpt-4o-2024-05-13',
                                'gpt-3.5-turbo-0613' => 'gpt-3.5-turbo-0613',
                                'custom' => '自定义模型/不懂请勿配置'
                            ],
                            'desc' => '选择要使用的 AI 模型，强烈推荐使用gpt-4o-mini，或选择自定义模型',
                        ],
                        [
                            'id' => 'custom-model-name',
                            'type' => 'text',
                            'title' => '自定义模型名称',
                            'subtitle' => '输入自定义的模型名称',
                            'desc' => '当选择"自定义模型"时，请在此输入完整的模型名称',
                            'dependency' => [['model-selection', '==', 'custom']],
                        ],
                    ],
                ],
                // 文心一言 账号配置
                [
                    'id' => 'wenxin-accounts',
                    'type' => 'group',
                    'title' => '文心一言 账号列表',
                    'subtitle' => '添加 文心一言 账号（支持多账号轮询）',
                    'desc' => '添加百度智能云千帆（文心一言）账号的 API Key 与 Secret Key。支持为每个账号单独设置默认参数。',
                    'button_title' => '添加账号',
                    'accordion_title_number' => true,
                    'dependency' => [['api-server-type', '==', 'wenxin']],
                    'fields' => [
                        [
                            'id' => 'account-note',
                            'type' => 'text',
                            'title' => '账号备注',
                            'desc' => '用于区分不同账号，可留空',
                        ],
                        [
                            'id' => 'api-key',
                            'type' => 'text',
                            'title' => 'API Key',
                            'subtitle' => '百度智能云 千帆平台 API Key',
                            'desc' => '在百度智能云千帆平台控制台创建应用后获取 API Key。获取页面：<a href="https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application/v1" target="_blank">千帆控制台 → 应用与APIKey</a>',
                        ],
                        [
                            'id' => 'secret-key',
                            'type' => 'text',
                            'title' => 'Secret Key',
                            'subtitle' => '百度智能云 千帆平台 Secret Key',
                            'desc' => '与 API Key 配对使用。若选择直签鉴权（signature），将用 AK/SK 进行签名。获取页面：<a href="https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application/v1" target="_blank">千帆控制台 → 应用与APIKey</a>',
                        ],
                        [
                            'id' => 'model-selection',
                            'type' => 'select',
                            'title' => '选择模型',
                            'options' => \HaoZiTeam\AIPost\Service\Features\WenXinModelCatalog::optionsForSelect(),
                            'desc' => '选择千帆模型（接入点ID全部为小写）。将根据模型自动应用最大输出上限，实际可用模型以账号开通为准。',
                        ],
                        [
                            'id' => 'temperature',
                            'type' => 'number',
                            'title' => '温度 (temperature)',
                            'subtitle' => '控制随机性，范围 0.0 - 1.0，建议 0.7',
                            'min' => 0.0,
                            'max' => 1.0,
                            'step' => 0.1,
                            'unit' => ' ',
                        ],
                        // 已移除：top_p, penalty_score, max_output_tokens, timeout, auth_mode, stream, stop, user_id, disable_search, enable_citation
                    ],
                ],
                // DeepSeek 令牌配置
                [
                    'id' => 'deepseek-accounts',
                    'type' => 'group',
                    'title' => 'DeepSeek 令牌列表',
                    'subtitle' => '添加 DeepSeek 令牌',
                    'desc' => '添加 DeepSeek API 令牌',
                    'button_title' => '添加令牌',
                    'accordion_title_number' => true,
                    'dependency' => [['api-server-type', '==', 'deepseek']],
                    'fields' => [
                        [
                            'id' => 'account-note',
                            'type' => 'text',
                            'title' => '令牌备注',
                            'desc' => '令牌备注，用于区分令牌',
                        ],
                        [
                            'id' => 'account-secret-key',
                            'type' => 'text',
                            'title' => '令牌',
                            'subtitle' => 'DeepSeek API Key',
                            'desc' => '前后都不要有空格！！！,<a href="https://console.deepseek.com/apikey" target="_blank">链接直达</a>',
                        ],
                        [
                            'id' => 'model-selection',
                            'type' => 'select',
                            'title' => '选择模型',
                            'options' => [
                                'deepseek-chat' => 'DeepSeek-V3',
                                'deepseek-reasoner' => 'DeepSeek-R1',
                                'custom' => '自定义模型/不懂请勿配置'
                            ],
                            'desc' => '选择要使用的 DeepSeek 模型，或选择自定义模型',
                        ],
                        [
                            'id' => 'custom-model-name',
                            'type' => 'text',
                            'title' => '自定义模型名称',
                            'subtitle' => '输入自定义的模型名称',
                            'desc' => '当选择"自定义模型"时，请在此输入完整的模型名称<br>deepseek模型和定价：https://api-docs.deepseek.com/zh-cn/quick_start/pricing',
                            'dependency' => [['model-selection', '==', 'custom']],
                        ],
                    ],
                ],
                // 豆包 令牌配置 (移动到这里)
                [
                    'id' => 'doubao-accounts',
                    'type' => 'group',
                    'title' => '豆包 令牌列表',
                    'subtitle' => '添加 豆包 令牌',
                    'desc' => '添加 豆包 API 令牌',
                    'button_title' => '添加令牌',
                    'accordion_title_number' => true,
                    'dependency' => [['api-server-type', '==', 'doubao']],
                    'fields' => [
                        [
                            'id' => 'account-note',
                            'type' => 'text',
                            'title' => '令牌备注',
                            'desc' => '令牌备注，用于区分令牌',
                        ],
                        [
                            'id' => 'account-secret-key',
                            'type' => 'text',
                            'title' => '令牌',
                            'subtitle' => '豆包 API Key',
                            'desc' => '前后都不要有空格！！！:<a href="https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey" target="_blank">链接直达</a>',
                        ],
                        [
                            'id' => 'model-selection',
                            'type' => 'select',
                            'title' => '选择模型',
                            'options' => [
                                'doubao-1.5-pro-32k-250115' => 'doubao-1.5-pro-32k-250115 (32k上下文, 高质量)',
                                'doubao-1.5-pro-256k' => 'doubao-1.5-pro-256k (256k上下文, 高质量)',
                                'custom' => '自定义模型/不懂请勿配置'
                            ],
                            'desc' => '选择要使用的豆包模型，或选择自定义模型',
                        ],
                        [
                            'id' => 'custom-model-name',
                            'type' => 'text',
                            'title' => '自定义模型名称',
                            'subtitle' => '输入自定义的模型名称',
                            'desc' => '当选择"自定义模型"时，请在此输入完整的模型名称<br>豆包模型列表及定价：https://www.volcengine.com/docs/82379/1330310',
                            'dependency' => [['model-selection', '==', 'custom']],
                        ],
                        // 新增：豆包温度设置
                        [
                            'id' => 'temperature',
                            'type' => 'number',
                            'title' => '温度 (Temperature)',
                            'subtitle' => '控制生成文本的随机性',
                            'desc' => '值越高越随机，越低越确定。范围 0.0 - 2.0，建议 0.7',
                            'default' => 0.7,
                            'min' => 0.0,
                            'max' => 2.0,
                            'step' => 0.1,
                            'unit' => ' ', // 避免显示默认单位
                        ],
                    ],
                ],
                // 火山引擎/豆包 文生图（ImageGenerations）配置
                [
                    'id' => 'doubao-imagegen-model',
                    'type' => 'text',
                    'title' => '文生图默认模型',
                    'subtitle' => 'ImageGenerations 模型',
                    'desc' => '<div style="border-left:4px solid #d63638;background:#fff5f5;padding:10px 12px;margin:6px 0 12px;line-height:1.6">
<strong style="color:#d63638;">文生图（ImageGenerations）默认配置</strong><br>
以下配置仅在任务级未覆盖时生效。
<div style="margin-top:6px;font-size:12px;">
文档：<a href="https://api.volcengine.com/api-docs/view?serviceCode=ark&version=2024-01-01&action=ImageGenerations" target="_blank">Volcengine Ark ImageGenerations</a>
</div>
</div>
默认使用 doubao-seedream-3-0-t2i-250415，可在任务级覆盖。',
                    'default' => 'doubao-seedream-3-0-t2i-250415',
                    'dependency' => [['api-server-type', '==', 'doubao']]
                ],
                // 移除豆包 API 级尺寸设置（改由任务级/实现逻辑决定，避免与任务级配置冲突）
                // 阿里百炼 令牌配置
                [
                    'id' => 'bai-lian-accounts',
                    'type' => 'group',
                    'title' => '阿里百炼 令牌列表',
                    'subtitle' => '添加 阿里百炼 令牌',
                    'desc' => '添加阿里百炼 API 令牌',
                    'button_title' => '添加令牌',
                    'accordion_title_number' => true,
                    'dependency' => [['api-server-type', '==', 'bai-lian']],
                    'fields' => [
                        [
                            'id' => 'account-note',
                            'type' => 'text',
                            'title' => '令牌备注',
                            'desc' => '令牌备注，用于区分令牌',
                        ],
                        [
                            'id' => 'account-secret-key',
                            'type' => 'text',
                            'title' => '令牌',
                            'subtitle' => '阿里百炼 API Key',
                            'desc' => '前后都不要有空格！！！<a href="https://bailian.console.aliyun.com/?tab=model#/api-key" target="_blank">链接直达</a>',
                        ],
                        [
                            'id' => 'model-selection',
                            'type' => 'select',
                            'title' => '选择模型',
                            'options' => [
                                'qwen-max' => 'Qwen Max (通义千问旗舰版) - 适合复杂任务，能力最强',
                                'qwen-max-latest' => 'Qwen Max Latest (旗舰版最新) - 始终使用最新版本',
                                'qwen-max-2024-09-19' => 'Qwen Max 2024-09-19 - 稳定旗舰版',
                                'qwen-plus' => 'Qwen Plus (通义千问高性能) - 效果、速度、成本均衡',
                                'qwen-plus-latest' => 'Qwen Plus Latest (高性能最新) - 始终使用最新版本',
                                'qwen-plus-2025-01-25' => 'Qwen Plus 2025-01-25 - 稳定高性能版',
                                'qwen-turbo' => 'Qwen Turbo (通义千问流畅版) - 适合简单任务，速度快、成本低',
                                'qwen-turbo-latest' => 'Qwen Turbo Latest (流畅版最新) - 始终使用最新版本',
                                'qwen-long' => 'Qwen Long (通义千问长文本) - 适合大规模文本分析，支持千万级Token',
                                'qwen-long-latest' => 'Qwen Long Latest (长文本最新) - 始终使用最新版本',
                                'custom' => '自定义模型/不懂请勿配置'
                            ],
                            'desc' => '选择要使用的阿里百炼模型，或选择自定义模型。<br>推荐使用：<br>- 普通文章：Qwen Plus (均衡性能和成本)<br>- 复杂内容：Qwen Max (最强能力)<br>- 简单任务：Qwen Turbo (速度快成本低)<br>- 长文档：Qwen Long (支持超长文本)',
                        ],
                        [
                            'id' => 'custom-model-name',
                            'type' => 'text',
                            'title' => '自定义模型名称',
                            'subtitle' => '输入自定义的模型名称',
                            'desc' => '当选择"自定义模型"时，请在此输入完整的模型名称，如：deepseek-r1、deepseek-v3、deepseek-r1-distill-llama-8b等<br>阿里百炼模型及定价<a href="https://help.aliyun.com/zh/model-studio/models" target="_blank">查看详情</a>',
                            'dependency' => [['model-selection', '==', 'custom']],
                        ],
                        // 百炼温度设置
                        [
                            'id' => 'temperature',
                            'type' => 'number',
                            'title' => '温度 (Temperature)',
                            'subtitle' => '控制生成文本的随机性',
                            'desc' => '值越高越随机，越低越确定。范围 0.0 - 2.0，建议 0.7',
                            'default' => 0.7,
                            'min' => 0.0,
                            'max' => 2.0,
                            'step' => 0.1,
                            'unit' => ' ', // 避免显示默认单位
                        ],
                    ],
                ],
                // 阿里百炼 文生图（Text-to-Image）全局默认配置（任务级未覆盖时生效）
                [
                    'id' => 'aliyun-imagegen-model',
                    'type' => 'select',
                    'title' => '阿里云文生图 默认模型',
                    'subtitle' => 'qwen-image / wanx-v1 / wan2.2-t2i-flash',
                    'desc' => '<div style="border-left:4px solid #2563eb;background:#eff6ff;padding:10px 12px;margin:6px 0 12px;line-height:1.6">仅在任务级未配置时生效。<br>文档：<a href="https://help.aliyun.com/zh/model-studio/text-to-image-v2-api-reference" target="_blank">通义万相V2</a> · <a href="https://help.aliyun.com/zh/model-studio/text-to-image-api-reference" target="_blank">通义万相V1</a> · <a href="https://help.aliyun.com/zh/model-studio/qwen-image-api" target="_blank">通义千问·图像</a></div>',
                    'options' => [
                        // 千问图像
                        'qwen-image' => '通义千问·图像（qwen-image） · 参考价 ¥0.25/张',
                        // 万相 V2（wan2.2）
                        'wan2.2-t2i-plus' => '通义万相 V2 Plus（wan2.2-t2i-plus） · 参考价 ¥0.20/张',
                        'wan2.2-t2i-flash' => '通义万相 V2 Flash（wan2.2-t2i-flash） · 参考价 ¥0.14/张',
                        // 万相 2.1 系列
                        'wanx2.1-t2i-plus' => '通义万相 2.1 Plus（wanx2.1-t2i-plus） · 参考价 ¥0.20/张',
                        'wanx2.1-t2i-turbo' => '通义万相 2.1 Turbo（wanx2.1-t2i-turbo） · 参考价 ¥0.14/张',
                        // 兼容保留 V1
                        'wanx-v1' => '通义万相 V1（wanx-v1）',
                    ],
                    'default' => 'wan2.2-t2i-flash',
                    'dependency' => [['api-server-type', '==', 'bai-lian']],
                ],
                // 移除阿里云 API 级尺寸与数量设置（改由任务级控制）
                // 条件参数：仅 qwen-image 支持
                [
                    'id' => 'aliyun-imagegen-prompt-extend',
                    'type' => 'switcher',
                    'title' => 'Prompt 扩写（仅 qwen-image）',
                    'default' => true,
                    'dependency' => [
                        ['api-server-type', '==', 'bai-lian'],
                    ],
                ],
                [
                    'id' => 'aliyun-imagegen-watermark',
                    'type' => 'switcher',
                    'title' => '水印（仅 qwen-image）',
                    'default' => true,
                    'dependency' => [
                        ['api-server-type', '==', 'bai-lian'],
                    ],
                ],
                // 条件参数：仅 wanx-v1 支持
                [
                    'id' => 'aliyun-imagegen-style',
                    'type' => 'text',
                    'title' => '风格（仅 wanx-v1）',
                    'default' => '<auto>',
                    'dependency' => [
                        ['api-server-type', '==', 'bai-lian'],
                    ],
                ],
            ],
        ]);

        CGPS::createSection($this->prefix, [
            'title' => '令牌余额',
            'fields' => [
                [
                    'id' => 'new-field-id',
                    'type' => 'text',
                    'title' => '令牌余额查询',
                    'subtitle' => '也可在https://tool.slapi.cn/中查询',
                    'default' => '输入令牌保存后方便下次复制',
                    'desc' => '<div style="position: relative; height: 500px; width: 100%;">
													<img src="https://www.suqian5188.cn/wp-content/uploads/2024/10/loading.gif" alt="Loading Animation" class="loading-gif" />
													<iframe id="myIframe"  style="width: 100%; height: 500px; border: none;" src="https://tool.slapi.cn/" style="width: 100%; height: 500px; border: none;" class="hide"></iframe>
													<div style="position: absolute; top: 0; left: 0; height: 70px; width: 100%; background-color: white;">令牌输入这里保存后，方便下次复制查询
													<p style="font-size: 14px;width: 100%; line-height:70px">仅支持来自https://sk.slapi.cn/的令牌</p></div></div>
													<script>
													document.addEventListener("DOMContentLoaded", function() {
													var iframe = document.getElementById("myIframe");
													var loadingGif = document.querySelector(".loading-gif");

													// 初始显示加载动画和隐藏iframe
													iframe.classList.add("hide");
													loadingGif.style.display = "block";

													// 当 iframe 加载完成时移除 loading 动画并显示 iframe
													iframe.onload = function() {
													loadingGif.style.display = "none";
													iframe.classList.remove("hide");
													};

													// 为防止缓存导致 onload 不触发，可强制刷新 iframe 内容
													iframe.src = iframe.src;
													});
													</script>',
                ],
            ],
        ]);

        CGPS::createSection($this->prefix, [
            'title' => '任务管理',
            'fields' => [
                [
                    'id' => 'tasks',
                    'type' => 'group',
                    'title' => '任务列表',
                    'subtitle' => '添加自动发布任务',
                    'desc' => '可以添加多个任务，每个任务都会按照设定的频率/时间段自动发布文章',
                    'button_title' => '添加任务',
                    'accordion_title_number' => true,
                    'fields' => [
                        [
                            'id' => 'task-note',
                            'type' => 'text',
                            'title' => '任务备注',
                            'desc' => '建议填写任务备注，用于区分任务，可以留空',
                        ],
                        [
                            'id' => 'task-status',
                            'type' => 'switcher',
                            'title' => '任务开关',
                            'desc' => '任务开关，开启后才会自动发布文章',
                            'default' => true,
                        ],
                        [
                            'id' => 'task-schedule-type',
                            'type' => 'radio',
                            'title' => '调度类型',
                            'options' => [
                                'frequency' => '按频率',
                                'timespan' => '按时间段'
                            ],
                            'default' => 'frequency',  // 默认值设为按频率
                            'inline' => true,
                        ],
                        [
                            'id' => 'task-frequency',
                            'type' => 'number',
                            'title' => '运行频率',
                            'subtitle' => '单位：分',
                            'desc' => '每隔多少分钟运行一次。最小值为 1，最大不限。WordPress的计划任务不能做到精准运行，仅供参考。',
                            'default' => 1,
                            'min' => 1,
                            'max' => 99999999,
                            'dependency' => [['task-schedule-type', '==', 'frequency']],
                        ],
                        [
                            'id' => 'task-timespans',
                            'type' => 'group',
                            'title' => '时间段设置',
                            'subtitle' => '添加多个时间段及其执行频率',
                            'desc' => '采用24小时制，时分用小写冒号分隔，可以添加多个时间段，每个时间段设置开始时间、结束时间和执行频率',
                            'button_title' => '增加',
                            'accordion_title_number' => true,
                            'dependency' => [['task-schedule-type', '==', 'timespan']],
                            'fields' => [
                                [
                                    'id' => 'start-time',
                                    'type' => 'text',
                                    'title' => '开始时间',
                                    'desc' => '格式：HH:MM，例如：03:00',
                                ],
                                [
                                    'id' => 'end-time',
                                    'type' => 'text',
                                    'title' => '结束时间',
                                    'desc' => '格式：HH:MM，例如：05:00',
                                ],
                                [
                                    'id' => 'timespan-frequency',
                                    'type' => 'number',
                                    'title' => '执行频率',
                                    'subtitle' => '在此时间段内每隔X分钟执行一次',
                                    'default' => 1,
                                    'min' => 1,
                                ],
                            ],
                        ],
                        [
                            'id' => 'post-category',
                            'type' => 'select',
                            'title' => '文章分类',
                            'subtitle' => '选择文章分类',
                            'desc' => '选择文章要发布到的分类',
                            'options' => 'categories',
                        ],
                        [
                            'id' => 'post-tags-language',
                            'type' => 'select', // 使用下拉选择框
                            'title' => '文章语言',
                            'subtitle' => '选择生成文章的语言',
                            'desc' => '选择语言后，生成的标签也是该语言，无需单独指定',
                            'options' => [
                                'tags-zh' => '中文简体', // 中文简体选项
                                'tags-zh-fan' => '中文繁体', // 中文繁体选项
                                'tags-en' => '英文', // 英文选项
                                'tags-vi' => '越南语',
                                'tags-ja' => '日语',
                                'tags-ko-KR' => '韩语',
                                'tags-sa-IN' => '梵文-印度',
                                'tags-pt-BR' => '葡萄牙语',
                                'tags-pt-BR-BR' => '巴西葡萄牙语',
                                'tags-es' => '西班牙语',
                                'custom' => '自定义语言',
                            ],
                            'default' => 'tags-zh', // 默认选择中文
                        ],
                        [
                            'id' => 'custom-language-code',
                            'type' => 'text',
                            'title' => '自定义语言代码',
                            'subtitle' => '输入自定义语言的代码',
                            'desc' => '请输入符合ISO标准的语言代码，例如：fr（法语）、de（德语）、ru（俄语）等',
                            'dependency' => [['post-tags-language', '==', 'custom']],
                        ],
                        [
                            'id' => 'custom-language-description',
                            'type' => 'textarea',
                            'title' => '自定义语言规范描述',
                            'subtitle' => '描述该语言的写作规范和特点',
                            'desc' => '请输入对该语言的详细描述，包括语法特点、写作风格等，AI将根据此描述生成相应语言的内容',
                            'dependency' => [['post-tags-language', '==', 'custom']],
                            'placeholder' => '例如：这是一种使用西里尔字母的语言，句子结构为主谓宾，形容词放在名词前，注重使用正式用语和礼貌表达...',
                        ],

                        [
                            'id' => 'post-tags',
                            'type' => 'switcher',
                            'title' => '自动文章标签',
                            'subtitle' => '自动生成文章标签',
                            'desc' => '开启后根据文章内容生成精准高频关键词',
                            'default' => true,
                        ],
                        [
                            'id' => 'post-tags-diy',
                            'type' => 'switcher',
                            'title' => '追加自定义标签',
                            'subtitle' => '追加到自动标签后',
                            'desc' => '是否使用自定义标签进行追加显示',
                            'default' => false,
                        ],
                        [
                            'id' => 'post-tags-diy-text',
                            'type' => 'text',
                            'title' => '输入自定义标签',
                            'desc' => '多个标签使用小写逗号分割',
                            'dependency' => [
                                [
                                    'post-tags-diy',
                                    '==',
                                    'true',
                                ],
                            ],
                        ],
                        [
                            'id' => 'post-author',
                            'type' => 'select',
                            'title' => '文章作者',
                            'subtitle' => '选择文章作者',
                            'desc' => '选择发布文章的作者',
                            'options' => 'users',
                        ],

                        [
                            'id' => 'enable-image-url',
                            'type' => 'switcher',
                            'title' => '配图方式一',
                            'subtitle' => '根据随机API地址获取图片',
                            'desc' => '开启后请输入配图网址API',
                            'default' => true,
                        ],
                        [
                            'id' => 'post-image-url',
                            'type' => 'text',
                            'title' => '文章配图API',
                            'subtitle' => '输入网址获取随机图片',
                            'desc' => '输入一个有效的图片网址，以"/"结尾，系统将随机调用该网址的随机图片缓存在本地。<br>推荐自定义图库API;<a href="https://www.2090ai.com/peitu1" target="_blank">自建图库API教程</a>',
                            'default' => 'https://img.suqian5188.cn/',
                            'placeholder' => 'https://img.suqian5188.cn/',
                            'dependency' => [
                                [
                                    'enable-image-url',
                                    '==',
                                    'true',
                                ],
                            ],
                        ],
                        [
                            'id' => 'post-image-url-n',
                            'type' => 'number',
                            'title' => '图片数量',
                            'subtitle' => '希望插入几张图片',
                            'desc' => '最小1张，最大5张，默认为2张。',
                            'default' => '2',
                            'min' => 1,
                            'max' => 5,
                            'dependency' => [
                                [
                                    'enable-image-url',
                                    '==',
                                    'true',
                                ],
                            ],
                        ],

 

                        [
                            'id' => 'enable-image-url-2',
                            'type' => 'switcher',
                            'title' => '配图方式二',
                            'subtitle' => '生成一幅带有标题的图片',
                            'desc' => '开启后会根据标题生成图片，系统生成不消耗令牌',
                            'default' => false,
                        ],
                        [
                            'id' => 'enable-image-url-position',
                            'type' => 'select', // 使用下拉选择框
                            'title' => '图片位置',
                            'subtitle' => '选择图片在文章中的位置',
                            'options' => [
                                '1' => '开头',
                                '2' => '中间',
                                '3' => '结尾',
                                '4' => '随机',
                            ],
                            'default' => '1', // 默认选择开头
                            'dependency' => [
                                [
                                    'enable-image-url-2',
                                    '==',
                                    'true',
                                ],
                            ],
                        ],
                        
                        [
                            'id' => 'font-selection',
                            'type' => 'select', // 使用下拉选择框
                            'title' => '选择字体',
                            'subtitle' => '选择您要使用的字体',
                            'options' => $this->get_fonts_list(), // 获取字体列表
                            'default' => '', // 默认选项
                            'dependency' => [
                                [
                                    'enable-image-url-2',
                                    '==',
                                    'true',
                                ],
                            ],
                        ],
                        
                        [
                            'id' => 'post-image-font-size',
                            'type' => 'number',
                            'title' => '文字大小',
                            'subtitle' => '单位：px',
                            'desc' => '生成图片给中的文字大小，数字越大，字越大',
                            'default' => 30,
                            'min' => 1,
                            'max' => 999,
                            'dependency' => [
	                            [
		                            'enable-image-url-2',
		                            '==',
		                            'true',
	                            ],
                            ],
                        ],
                        [
                            'id' => 'post-image-font-color',
                            'type' => 'text',
                            'title' => '文字颜色',
                            'subtitle' => '设置生成图片中的文字颜色',
                            'desc' => '输入一个有效的16进制颜色编码',
                            'default' => '#ffffff',
                            'placeholder' => '#ffffff',
                            'validate' => 'color',
                            'dependency' => [
                                [
                                    'enable-image-url-2',
                                    '==',
                                    'true',
                                ],
                                [
                                    'post-image-url-2-radio',
                                    '==',
                                    'diy-background',
                                ],
                            ],
                        ],
                        [
                            'id' => 'post-image-url-2-radio',
                            'type' => 'radio',
                            'title' => '选择配图方式',
                            'options' => [
                                'diy-background' => '自定义背景图',
                                'diy-background-color' => '随机背景颜色和标题颜色',
                            ],
                            'default' => 'diy-background-color',
                            'inline' => true,
                            'dependency' => [
                                [
                                    'enable-image-url-2',
                                    '==',
                                    'true',
                                ],
                            ],
                        ],

                        [
                            'id' => 'post-image-url-2-background',
                            'type' => 'text',
                            'title' => '输入本地图片存储路径',
							'subtitle' => '默认为插件目录下的title-img文件夹<br>你可以根据需要修改为其它路径',
                            'desc' => '以wordpress安装目录作为根目录，推荐使用大小统一的横向图片',
                            'default' => '/wp-content/plugins/ai-post/title-img',
                            'placeholder' => '/wp-content/plugins/ai-post/title-img',
                            'dependency' => [
                                [
                                    'enable-image-url-2',
                                    '==',
                                    'true',
                                ],
                                [
                                    'post-image-url-2-radio',
                                    '==',
                                    'diy-background',
                                ],
                            ],
                        ],
                        [
                            'id' => 'post-image-url-2-color',
                            'type' => 'textarea',
                            'title' => '背景颜色|标题颜色',
                            'desc' => '每行一个设置，每个设置可以使用|分隔背景颜色和标题颜色。如果设置只包含一种颜色，则会使用默认的文字颜色',
                            'dependency' => [
                                [
                                    'enable-image-url-2',
                                    '==',
                                    'true',
                                ],
                                [
                                    'post-image-url-2-radio',
                                    '==',
                                    'diy-background-color',
                                ],
                            ],
                            'placeholder' => '#5b8982|#ffffff
#45545f|#cec6b6
#d47655|#e1f8e1
#7379b0|#c6edec',
                            'default' => '#5b8982|#ffffff
#45545f|#cec6b6
#d47655|#e1f8e1
#7379b0|#c6edec',
                        ],
                       // 任务级：火山引擎/豆包 文生图开关
                       [
                        'id' => 'enable-doubao-imagegen',
                        'type' => 'switcher',
                        'title' => '配图方式三',
                        'subtitle' => '火山引擎/豆包文生图',
                        'desc' => '启用后将根据任务提示生成配图。生成图片会消耗令牌额度',
                        'default' => false,
                    ],
                    [
                        'id' => 'imagegen-provider',
                        'type' => 'select',
                        'title' => '文生图模型提供商',
                        'subtitle' => '选择用于本任务的文生图后端',
                        'options' => [
                            'doubao' => '火山引擎/豆包 · 参考价 ¥0.259/张',
                            'aliyun' => '阿里云百炼（DashScope）',
                        ],
                        'default' => 'doubao',
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                        ],
                    ],
                    // 任务级：当选择阿里云百炼时的模型与参数（覆盖全局默认）
                    [
                        'id' => 'aliyun-imagegen-model-task',
                        'type' => 'select',
                        'title' => '阿里云模型（任务覆盖）',
                        'subtitle' => 'qwen-image / wanx-v1 / wan2.2-t2i-flash',
                        'options' => [
                            // 千问图像
                            'qwen-image' => '通义千问·图像（qwen-image） · 参考价 ¥0.25/张',
                            // 万相 V2（wan2.2）
                            'wan2.2-t2i-plus' => '通义万相 V2 Plus（wan2.2-t2i-plus） · 参考价 ¥0.20/张',
                            'wan2.2-t2i-flash' => '通义万相 V2 Flash（wan2.2-t2i-flash） · 参考价 ¥0.14/张',
                            // 万相 2.1 系列
                            'wanx2.1-t2i-plus' => '通义万相 2.1 Plus（wanx2.1-t2i-plus） · 参考价 ¥0.20/张',
                            'wanx2.1-t2i-turbo' => '通义万相 2.1 Turbo（wanx2.1-t2i-turbo） · 参考价 ¥0.14/张',
                            // 兼容保留 V1
                            'wanx-v1' => '通义万相 V1（wanx-v1）',
                        ],
                        'default' => 'wan2.2-t2i-flash',
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'aliyun' ],
                        ],
                    ],
                    [
                        'id' => 'aliyun-imagegen-aspect-qwen-task',
                        'type' => 'select',
                        'title' => '画幅比例（任务覆盖，qwen-image）',
                        'subtitle' => '仅提供常用比例；后端将映射为官方允许的像素尺寸',
                        'options' => [
                            '16:9' => '16:9（横图）',
                            '4:3'  => '4:3（横图）',
                            '1:1'  => '1:1（方图，推荐）',
                        ],
                        'default' => '1:1',
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'aliyun' ],
                            [ 'aliyun-imagegen-model-task', '==', 'qwen-image' ],
                        ],
                    ],
                    [
                        'id' => 'aliyun-imagegen-aspect-wan-task',
                        'type' => 'select',
                        'title' => '画幅比例（任务覆盖，万相系列）',
                        'subtitle' => '仅提供常用比例；后端将映射为 1024x576/1024x768/1024x1024 等合法尺寸',
                        'options' => [
                            '16:9' => '16:9（横图）',
                            '4:3'  => '4:3（横图）',
                            '1:1'  => '1:1（方图，推荐）',
                        ],
                        'default' => '1:1',
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'aliyun' ],
                            [ 'aliyun-imagegen-model-task', 'any', 'wan2.2-t2i-flash,wan2.2-t2i-plus,wanx2.1-t2i-plus,wanx2.1-t2i-turbo,wanx-v1' ],
                        ],
                    ],
                    [
                        'id' => 'aliyun-imagegen-n-task',
                        'type' => 'number',
                        'title' => '数量 n（任务覆盖）',
                        'subtitle' => '一次请求生成图片的数量（qwen-image 固定为 1，插件将自动纠正）',
                        'default' => 1,
                        'min' => 1,
                        'max' => 4,
                        'step' => 1,
                        // 仅在阿里云 + 万相系列任务模型时显示；qwen-image 固定为 1
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'aliyun' ],
                            [ 'aliyun-imagegen-model-task', 'any', 'wan2.2-t2i-flash,wan2.2-t2i-plus,wanx2.1-t2i-plus,wanx2.1-t2i-turbo,wanx-v1' ],
                        ],
                    ],
                    // 条件参数：qwen-image 专属
                    [
                        'id' => 'aliyun-imagegen-prompt-extend-task',
                        'type' => 'switcher',
                        'title' => 'Prompt 扩写（任务覆盖，仅 qwen-image）',
                        'default' => true,
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'aliyun' ],
                            [ 'aliyun-imagegen-model-task', '==', 'qwen-image' ],
                        ],
                    ],
                    [
                        'id' => 'aliyun-imagegen-watermark-task',
                        'type' => 'switcher',
                        'title' => '水印（任务覆盖，仅 qwen-image）',
                        'default' => true,
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'aliyun' ],
                            [ 'aliyun-imagegen-model-task', '==', 'qwen-image' ],
                        ],
                    ],
                    // 条件参数：wanx-v1 专属
                    [
                        'id' => 'aliyun-imagegen-style-task',
                        'type' => 'text',
                        'title' => '风格（任务覆盖，仅 wanx-v1）',
                        'subtitle' => '填写 <auto> 或其他风格标签',
                        'default' => '<auto>',
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'aliyun' ],
                            [ 'aliyun-imagegen-model-task', '==', 'wanx-v1' ],
                        ],
                    ],
                    [
                        'id' => 'doubao-imagegen-image-count',
                        'type' => 'number',
                        'title' => '生成图片数量',
                        'subtitle' => '豆包文生图一次生成的图片张数',
                        'desc' => '范围建议 1-4，默认 1。注意：是否支持多图由服务端能力与调用策略决定。',
                        'default' => 1,
                        'min' => 1,
                        'max' => 4,
                        'step' => 1,
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'doubao' ],
                        ],
                    ],
                    // 任务级：豆包文生图尺寸下拉（映射由后端解析为具体像素）
                    [
                        'id' => 'doubao-imagegen-size-task',
                        'type' => 'select',
                        'title' => '尺寸（豆包）',
                        'subtitle' => '选择宽高比例（后端将映射为 1024x768 / 1024x576 / 1024x1024）',
                        'options' => [
                            '4:3'  => '4:3（1024x768 推荐）',
                            '16:9' => '16:9（1024x576）',
                            '1:1'  => '1:1（1024x1024）',
                        ],
                        'default' => '4:3',
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                            [ 'imagegen-provider', '==', 'doubao' ],
                        ],
                    ],
                    // 任务级：文生图 → 是否下载到媒体库
                    [
                        'id' => 'doubao-imagegen-download-to-media',
                        'type' => 'switcher',
                        'title' => '文生图下载到媒体库',
                        'subtitle' => '下载生成图片为本地附件',
                        'desc' => '开启后，将把火山引擎返回的图片URL侧载为媒体库附件（未附加到文章）；关闭则直接使用豆包返回的原始图片URL。',
                        'default' => true,
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                        ],
                    ],

                    // 任务级：文生图 → 是否保留AI水印
                    [
                        'id' => 'doubao-imagegen-watermark',
                        'type' => 'switcher',
                        'title' => '文生图保留AI水印',
                        'subtitle' => 'watermark 参数',
                        'desc' => '关闭可尝试去除右下角AI水印（由服务端决定是否支持）。',
                        'default' => false,
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                        ],
                    ],

                    // 任务级：文生图 → AI标题叠加功能
                    [
                        'id' => 'enable-ai-title-overlay',
                        'type' => 'switcher',
                        'title' => 'AI图片标题叠加',
                        'subtitle' => '在生成的图片上叠加文章标题',
                        'desc' => '开启后，将在AI生成的图片上叠加文章标题文字，提升图片与内容的关联性。',
                        'default' => false,
                        'dependency' => [
                            [ 'enable-doubao-imagegen', '==', 'true' ],
                        ],
                    ],


                        [
                            'id' => 'system-prompt',
                            'type' => 'textarea',
                            'default' => '我要你担任作家。我将为你提供文章的主题和逻辑关系并指导你完成撰文，你需要尽可能详细地直接回复我你撰写的文章内容，不要加其他无关的东西。',
                            'title' => 'AI 设定',
                            'desc' => '可留空，不影响文章生成，如果你有特殊需求，可在此填入指令；<br>当前任务的ai设定，将作为prompt伴随当前任务',
                            'after' => $this->render_system_prompt_presets(),
                        ],
                        [
                            'id' => 'post-content-shield',
                            'type' => 'textarea',
                            'title' => '内容过滤词',
                            'subtitle' => '输入希望文章中不要出现的词语',
                            'desc' => '每行一个<br>插件已经内置了一部分过滤词，如果你觉得需要追加，请填在这里',
                        ],
                        [
                            'id' => 'enable-custom-content',
                            'type' => 'switcher',
                            'title' => '插入自定义文章段落',
                            'desc' => '开启后可在文章中插入自定义内容（开头、中间、结尾）',
                            'default' => false,
                        ],
                        [
                            'id' => 'custom-content-tabs',
                            'type' => 'tabbed',
                            'title' => '自定义文章段落',
                            'subtitle' => '选择需要编辑的文章段落位置',
                            'desc' => '在对应选项卡中编辑内容，支持富文本编辑器',
                            'dependency' => [
                                ['enable-custom-content', '==', 'true']
                            ],
                            'tabs' => [
                                [
                                    'title' => '文章开头',
                                    'fields' => [
                                        [
                                            'id' => 'custom-before-content',
                                            'type' => 'wp_editor',
                                            'title' => '',
                                            'subtitle' => '',
                                            'desc' => '此内容将显示在文章开头',
                                            'sanitize' => false,
                                            'settings' => [
                                                'media_buttons' => true,
                                                'textarea_rows' => 10,
                                                'tinymce' => [
                                                    'toolbar1' => 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,wp_more,spellchecker,wp_adv',
                                                    'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help'
                                                ]
                                            ]
                                        ]
                                    ]
                                ],
                                [
                                    'title' => '文章中间',
                                    'fields' => [
                                        [
                                            'id' => 'custom-middle-content',
                                            'type' => 'wp_editor',
                                            'title' => '',
                                            'subtitle' => '',
                                            'desc' => '此内容将显示在文章中间（50%位置）',
                                            'sanitize' => false,
                                            'settings' => [
                                                'media_buttons' => true,
                                                'textarea_rows' => 10,
                                                'tinymce' => [
                                                    'toolbar1' => 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,wp_more,spellchecker,wp_adv',
                                                    'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help'
                                                ]
                                            ]
                                        ]
                                    ]
                                ],
                                [
                                    'title' => '文章结尾',
                                    'fields' => [
                                        [
                                            'id' => 'custom-after-content',
                                            'type' => 'wp_editor',
                                            'title' => '',
                                            'subtitle' => '',
                                            'desc' => '此内容将显示在文章结尾',
                                            'sanitize' => false,
                                            'settings' => [
                                                'media_buttons' => true,
                                                'textarea_rows' => 10,
                                                'tinymce' => [
                                                    'toolbar1' => 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,wp_more,spellchecker,wp_adv',
                                                    'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help'
                                                ]
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ],
                        [
                            'id' => 'post-steps',
                            'type' => 'group',
                            'title' => '文章步骤',
                            'subtitle' => '设置自动发布文章的任务步骤<br>无论添加几个步骤<br>第一个必选标题<br>随后都选主体',
                            'desc' => '设置自动发布文章的任务步骤',
                            'button_title' => '添加',
                            'accordion_title_number' => true,
                            'fields' => [
                                [
                                    'id' => 'send',
                                    'type' => 'textarea',
                                    'title' => '发送内容',
                                    'subtitle' => '设置发送给 AI 的内容',
                                    'desc' => '设置发送给 AI 的内容',
                                ],
                                [
                                    'id' => 'receive',
                                    'type' => 'switcher',
                                    'title' => '接收回复',
                                    'subtitle' => '是否使用 AI 的回复内容',
                                    'desc' => '是否使用 AI 的回复内容，对于设定类发送，可以不使用回复内容',
                                    'default' => true,
                                ],
                                [
                                    'id' => 'receive-type',
                                    'type' => 'radio',
                                    'title' => '接收回复作为',
                                    'subtitle' => '设置接收 AI 回复作为',
                                    'inline' => true,
                                    'default' => 'title',
                                    'options' => [
                                        'title' => '标题',
                                        'content' => '主体',
                                    ],
                                    'dependency' => [
                                        [
                                            'receive',
                                            '==',
                                            'true',
                                        ],
                                    ],
                                ],
                                // 当选择 "标题" 时显示的提示
                                [
                                    'id' => 'receive-type-desc-title',
                                    'type' => 'notice',
                                    'style' => 'info',
                                    'content' => '当选择回复类型为标题时，AI 的回复将作为文章的标题。',
                                    'dependency' => [
                                        ['receive', '==', 'true'],
                                        ['receive-type', '==', 'title'],
                                    ],
                                ],
                                // 当选择 "主体" 时显示的提示
                                [
                                    'id' => 'receive-type-desc-content',
                                    'type' => 'notice',
                                    'style' => 'info',
                                    'content' => '当选择回复类型为主体时，AI 的回复将作为文章的内容。主体可重复使用，将自动追加上一次的回复内容。',
                                    'dependency' => [
                                        ['receive', '==', 'true'],
                                        ['receive-type', '==', 'content'],
                                    ],
                                ],
                            ],
                        ],
                        [
                            'id' => 'post-final-status',
                            'type' => 'select',
                            'title' => '文章最终状态',
                            'subtitle' => '选择文章生成后的状态',
                            'desc' => '设置任务生成的文章最终是存为草稿还是直接发布。默认为直接发布。',
                            'options' => [
                                'publish' => '立即发布',
                                'draft' => '存为草稿',
                            ],
                            'default' => 'publish',
                        ]
                    ],
                ],
            ],
        ]);

        CGPS::createSection($this->prefix, [
            'title' => '全局设定',
            'fields' => [
                [
                    'type' => 'callback',
                    'function' => function() {
                        echo '<div class="ad-section" style="margin-bottom: 10px; position: relative;">';
                        echo '<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; margin-bottom: -22px;">';
                        echo '<a href="https://www.2090ai.com/" target="_blank" class="button button-primary" style="height:30px; padding:0 10px; line-height:1; display:flex; align-items:center; justify-content:center;">';
                        echo '<span class="dashicons dashicons-admin-links" style="font-size:20px; margin-right:5px;"></span>';
                        echo '效果演示';
                        echo '</a>';
                        
                       // echo '<a href="https://www.aidamoxing.cn/" target="_blank" class="button button-primary" style="height:30px; padding:0 10px; line-height:1; display:flex; align-items:center; justify-content:center;">';
                        //echo '<span class="dashicons dashicons-admin-site" style="font-size:20px; margin-right:5px;"></span>';
                       ///echo '效果演示二';
                       // echo '</a>';
                        
                        echo '<a href="https://www.2090ai.com/video-tutorials" target="_blank" class="button button-primary" style="height:30px; padding:0 10px; line-height:1; display:flex; align-items:center; justify-content:center;">';
                        echo '<span class="dashicons dashicons-video-alt3" style="font-size:20px; margin-right:5px;"></span>';
                        echo '视频教程';
                        echo '</a>';
                        
                        echo '<a href="https://www.2090ai.com/doc" target="_blank" class="button button-primary" style="height:30px; padding:0 10px; width:100%; line-height:1; display:flex; align-items:center; justify-content:center;">';
                        echo '<span class="dashicons dashicons-media-document" style="font-size:20px; margin-right:5px;"></span>';
                        echo '文档教程';
                        echo '</a></div></div>';
                    },
                    'after' => '<style>
                        .ad-section .button {
                            box-sizing: border-box;
                            flex-direction: row !important;
                            transition: all 0.2s ease;
                        }
                        .ad-section .dashicons {
                            vertical-align: middle;
                            position: relative;
                            top: -1px;
                        }
                    </style>',
                ],
                [
                    'id'     => 'global_tabs',
                    'type'   => 'tabbed',
                    'tabs'   => [
                        [
                            'title'  => '基础优化',
                            'icon' => 'dashicons dashicons-search',
                            'fields' => [
                                [
                                    'type' => 'heading',
                                    'content' => '优化设置'
                                ],
                                [
                                    'type'    => 'content',
                                    'content' => '在开启相关选项前，请确认其他插件是否也有相同的参数，如果有，请不要重复开启，否则可能导致重复设置。<br>
                                    '
                                ],
                                [
                                    'id'      => 'meta_description_generation_method', // New ID
                                    'type'    => 'radio', // Changed to radio
                                    'title'   => 'Meta Description 生成方式', // New title
                                    'options' => [
                                        'extract' => '截取内容（默认）',
                                        'ai'      => 'AI 生成（需API，可能增加消耗）',
                                        'none'    => '不生成 Meta Description' // Added option to disable
                                    ],
                                    'default' => 'extract', // Default to extract
                                    'desc'    => '选择如何生成文章的 Meta Description 标签。'
                                ],
                                [
                                    'id'      => 'publish-content-encoding',
                                    'type'    => 'radio',
                                    'title'   => '发布内容编码方式',
                                    'options' => [
                                        'utf8'        => 'UTF-8 可阅读文本',
                                        'html-entity' => 'HTML 十进制实体编码',
                                    ],
                                    'default' => 'utf8',
                                    'desc'    => '仅正文会根据此选项编码入库：选择“HTML 实体”时，正文中的非 ASCII 字符按 &#NNNN; 存储；选择“UTF-8 正常文本”时，保持可阅读中文。标题始终保持 UTF-8。',
                                ],
                                [
                                    'id' => 'seo_keywords_enabled', // New ID for keywords switch
                                    'type' => 'switcher',
                                    'title' => '生成 Meta Keywords',
                                    'desc' => '是否生成 Meta Keywords 标签（Google 已不再使用，建议关闭）。',
                                    'default' => false // Default to off
                                ],
                                [
                                    'id' => 'auto-alt-enabled',
                                    'type' => 'switcher',
                                    'title' => '自动添加图片ALT属性',
                                    'desc' => '开启后自动为文章图片添加alt属性，格式为文章标题+序号（如：alt="标题1" alt="标题2"）',
                                    'default' => false
                                ],
                                [
                                    'id' => 'auto-featured-image-enabled',
                                    'type' => 'switcher',
                                    'title' => '开启自动特色图片',
                                    'desc' => '自动提取文章图片作为特色图片',
                                    'default' => false,
                                ],
                                [
                                    'id' => 'featured-image-position',
                                    'type' => 'select',
                                    'title' => '选择图片位置',
                                    'options' => [
                                        '1' => '第一幅图片',
                                        '2' => '第二幅图片',
                                        '3' => '第三幅图片'
                                    ],
                                    'default' => '1',
                                    'sanitize' => function($value) {
                                        return (string)max(1, min(3, absint($value))); // 强制值在1-3之间
                                    },
                                    'dependency' => [['auto-featured-image-enabled', '==', 'true']]
                                ],
                                [
                                    'id' => 'thumbnail-width',
                                    'type' => 'number',
                                    'title' => '缩略图宽度',
                                    'default' => 300,
                                    'unit' => 'px',
                                    'dependency' => [['auto-featured-image-enabled', '==', 'true']]
                                ],
                                [
                                    'id' => 'thumbnail-height', 
                                    'type' => 'number',
                                    'title' => '缩略图高度',
                                    'default' => 225,
                                    'unit' => 'px',
                                    'dependency' => [['auto-featured-image-enabled', '==', 'true']]
                                ],
                                
                            ]
                        ],
                        [
                            'title'  => '内链设置',
                            'icon' => 'dashicons dashicons-admin-links',
                            'fields' => [
                                [
                                    'type' => 'heading',
                                    'content' => '内链设置'
                                ],
                                [
                                    'id' => 'enable-internal-links',
                                    'type' => 'switcher',
                                    'title' => '启用文章互链功能',
                                    'desc' => '开启后自动为文章添加内链，内链URL为你设置的固定链接结构，<br>如：https://example.com/archives/123，与tag标签链接结构不同',
                                    'default' => true
                                ],
                                [
                                    'id' => 'auto-tag-linking',
                                    'type' => 'switcher',
                                    'title' => '自动标签tag内链',
                                    'desc' => '如果文章中出现当前文章tag关键词，则自动将tag标签URL转换为固定链接结构，<br>如：将https://www.example.com/tag/tagname转换为https://www.example.com/archives/123',
                                    'default' => true,
                                    'dependency' => [['enable-internal-links', '==', 'true']]
                                ],
                                [
                                    'id' => 'custom-links',
                                    'type' => 'textarea',
                                    'title' => '自定义内链规则',
                                    'subtitle' => '每行格式：关键词|URL<br>优先级高于文章内链和tag内链<br>可设置站内站外链接',
                                    'desc' => '示例：<br>人工智能|https://example.com/ai<br>机器学习|https://example.com/ml<br>只有文章包含该关键词才会添加指定链接',
                                    'sanitize' => false,
                                    'dependency' => [['enable-internal-links', '==', 'true']],
                                    'attributes' => [
                                        'placeholder' => '关键词|URL',
                                        'rows' => 5
                                    ]
                                ],
                                [
                                    'id' => 'link-nofollow',
                                    'type' => 'switcher',
                                    'title' => '添加nofollow属性',
                                    'desc' => '为文章内链添加rel="nofollow"属性，告诉搜索引擎不要将权重传递给该链接目标页面',
                                    'dependency' => [['enable-internal-links', '==', 'true']],
                                    'default' => false
                                ],
                                [
                                    'id' => 'link-replace-count',
                                    'type' => 'number',
                                    'title' => '关键词替换次数',
                                    'desc' => '每个关键词在文章中最多替换为链接的次数',
                                    'default' => 2,
                                    'min' => 1,
                                    'max' => 100,
                                    'dependency' => [['enable-internal-links', '==', 'true']]
                                ],
                                [
                                    'id' => 'related-post-criteria',
                                    'type' => 'select',
                                    'title' => '文章内链匹配逻辑',
                                    'options' => [
                                        'date' => '最新文章',
                                        'comment_count' => '最多评论',
                                        'rand' => '随机文章'
                                    ],
                                    'default' => 'date',
                                    'dependency' => [['enable-internal-links', '==', 'true']]
                                ],
                                [
                                    'id' => 'related-post-fallback',
                                    'type' => 'switcher',
                                    'title' => '启用备用链接',
                                    'desc' => '当没有找到关键词匹配的文章时，使用标签TAG链接：格式为https://www.example.com/tag/tagname',
                                    'default' => true,
                                    'dependency' => [['enable-internal-links', '==', 'true']]
                                ],
                            ]
                        ],
                        [
                            'title' => '标题处理',
                            'icon' => 'dashicons dashicons-editor-textcolor',
                            'fields' => [
                                [
                                    'type' => 'heading',
                                    'content' => '标题处理设置'
                                ],
                                [
                                    'id' => 'custom-title-examples',
                                    'type' => 'textarea',
                                    'title' => '自定义示例标题',
                                    'subtitle' => '每行一个示例标题（留空使用默认示例）',
                                    'desc' => '可以用汉语标题，建议输入和站点语言相同的标题<br>输入您希望AI参考的标题样式，生成的标题将自动匹配这些示例的语义风格<br>示例标题越多越好，建议找50-80个不同风格的示例标题，ai会随机抽取一个作为参照示例生成标题',
                                    'placeholder' => '',
                                    'default' => '
老师现场提了一个问题，同学的回答亮了；
那些整天熬夜加班的人注意了；
这个小技巧，99%的人都不知道；
掌握这3点，轻松玩转母婴行业私域运营；
我用了2个月，做坏了6次热点营销；
上海和深圳对比，未来你更看好谁?
',
                                    'sanitize' => false
                                ],
                                [
                                    'id' => 'enable-time-line',
                                    'type' => 'switcher',
                                    'title' => '启用时间线',
                                    'desc' => '开启后可自定义时间线（如：2025年），AI生成内容会参考此时间线',
                                    'default' => true,
                                ],
                                [
                                    'id' => 'time-line',
                                    'type' => 'text',
                                    'title' => '时间线',
                                    'desc' => '请输入当前时间线，如：2025年',
                                    'default' => '2025年',
                                    'dependency' => [
                                        ['enable-time-line', '==', 'true']
                                    ],
                                ],
                                [
                                    'id' => 'zh-title-limit',
                                    'type' => 'number',
                                    'title' => '中文标题限制',
                                    'desc' => '中文字符最大长度（1个汉字=3字节）96字节为32个汉字',
                                    'default' => 96,
                                    'unit' => '字节',
                                ],
                                [
                                    'id' => 'en-title-limit',
                                    'type' => 'number',
                                    'title' => '英文标题限制',
                                    'desc' => '英文字符最大长度（1字母=1字符）',
                                    'default' => 65,
                                    'unit' => '字符',
                                ],
                                [
                                    'id' => 'title-rewrite-enabled',
                                    'type' => 'switcher',
                                    'title' => 'AI改写超长标题',
                                    'desc' => '标题超长时自动调用AI改写',
                                    'default' => true,
                                    'dependency' => [
                                        ['zh-title-limit', '>', 0],
                                        ['en-title-limit', '>', 0]
                                    ]
                                ],
                                [
                                    'id' => 'empty-title-action',
                                    'type' => 'select',
                                    'title' => '空标题处理方式',
                                    'options' => [
                                        'trash' => '放入回收站',
                                        'draft' => '存入草稿箱',
                                        'ai-rewrite' => 'AI自动改写',
                                        'first-heading' => '正文第一个标题（h1/h2/h3/h4）'
                                    ],
                                    'default' => 'trash'
                                ],
                                [
                                    'id' => 'duplicate-check-enabled',
                                    'type' => 'switcher',
                                    'title' => '启用重复标题检查',
                                    'desc' => '开启标题重复检查功能',
                                    'default' => true,
                                ],
                                [
                                    'id' => 'duplicate-action',
                                    'type' => 'select',
                                    'title' => '重复标题处理方式',
                                    'options' => [
                                        'trash' => '放入回收站',
                                        'draft' => '存入草稿箱',
                                        'rewrite' => 'AI自动改写'
                                    ],
                                    'default' => 'trash',
                                    'dependency' => [
                                        ['duplicate-check-enabled', '==', 'true']
                                    ]
                                ],
                                [
                                    'id' => 'duplicate-check-days',
                                    'type' => 'number',
                                    'title' => '重复检查范围',
                                    'subtitle' => '单位：天',
                                    'desc' => '检查最近多少天内的文章标题（0表示检查所有文章）',
                                    'default' => 30,
                                    'min' => 0,
                                    'dependency' => [
                                        ['duplicate-check-enabled', '==', 'true']
                                    ]
                                ],
                            ]
                        ],
                        [
                            'title' => '内容处理',
                            'icon' => 'dashicons dashicons-edit-page',
                            'fields' => [
                                [
                                    'type' => 'heading',
                                    'content' => '内容处理设置'
                                ],
 
                                [
                                    'id' => 'content-replace-rules',
                                    'type' => 'textarea',
                                    'title' => '替换规则',
                                    'desc' => '每行一条规则，格式：旧内容 => 新内容（使用UTF-8编码）',
                                    'sanitize' => false,
                                    // 'dependency' => [['content-check-enabled', '==', 'true']]
                                ],
                                // --- 新增：长文本生成控制 --- 
                                [
                                    'id' => 'enable_long_text_generation',
                                    'type' => 'switcher',
                                    'title' => '启用长文本生成模式',
                                    'desc' => '开启后，AI 将生成更长、段落更详细的文章内容，同时也会消耗更多 Token（实验性功能）。',
                                    'default' => false,
                                    // 'dependency' => [['content-check-enabled', '==', 'true']] // 依赖于内容检查总开关
                                ],
                                // --- 修改：表格生成设置 --- 
                                // 1. 添加总开关
                                [
                                    'id' => 'enable_table_generation', 
                                    'type' => 'switcher',
                                    'title' => '启用AI生成表格',
                                    'desc' => '开启后，将根据下方选择的格式，在生成主体内容的指令中建议AI插入表格。',
                                    'default' => false,
                                    // 'dependency' => [['content-check-enabled', '==', 'true']]
                                ],
                                // 2. 添加格式选择（依赖总开关）
                                [
                                    'id' => 'table_generation_format', 
                                    'type' => 'radio', // 使用 radio 更清晰
                                    'title' => '表格生成方式',
                                    'options' => [
                                        //'none' => '禁用', // 移除 none，由总开关控制
                                        'div' => 'DIV 结构 (实验性,外观整洁但某些AI可能不遵从)',
                                        'html' => 'HTML <table> 标签',
                                        'markdown' => 'Markdown 语法'
                                    ],
                                    'default' => 'html', // 默认选中 HTML
                                    'inline' => true, // 横向排列选项
                                    'desc' => '选择希望AI使用的表格格式。注意：AI不一定能完美遵从DIV格式指令。',
                                    // 依赖于总开关为 true
                                    'dependency' => [ 
                                        ['enable_table_generation', '==', 'true'] 
                                    ]
                                ],
                                [
                                    'id' => 'table_format_desc_div',
                                    'type' => 'notice',
                                    'style' => 'warning', // 使用警告样式强调实验性
                                    'content' => '<strong>DIV 结构 (实验性):</strong> 外观可能更整洁美观，但部分 AI 模型可能无法很好地遵循此格式指令。',
                                    'dependency' => [
                                        ['enable_table_generation', '==', 'true'],
                                        ['table_generation_format', '==', 'div'] // 依赖于选中 DIV
                                    ]
                                ],
                                // 为 HTML 选项添加描述
                                // 为 Markdown 选项添加描述
                                [
                                    'id' => 'table_format_desc_markdown',
                                    'type' => 'notice',
                                    'style' => 'info',
                                    'content' => '<strong>Markdown 语法:</strong> 不推荐/格式简洁，易于阅读和编辑。但最终显示效果依赖于前端 Markdown 解析器的支持。',
                                    'dependency' => [
                                        ['enable_table_generation', '==', 'true'],
                                        ['table_generation_format', '==', 'markdown'] // 依赖于选中 Markdown
                                    ]
                                ],
                                [
                                    'id' => 'table_format_desc_html',
                                    'type' => 'notice',
                                    'style' => 'info',
                                    'content' => '<strong>HTML &lt;table&gt; 标签:</strong> 推荐使用，最通用和兼容性最好的方式，大多数 AI 模型都能理解并生成。推荐在需要稳定输出时使用。',
                                    'dependency' => [
                                        ['enable_table_generation', '==', 'true'],
                                        ['table_generation_format', '==', 'html'] // 依赖于选中 HTML
                                    ]
                                ],
                                [
                                    'type' => 'heading',
                                    'content' => '文章目录设置'
                                ],
                                [
                                    'id' => 'enable-toc',
                                    'type' => 'switcher',
                                    'title' => '启用文章目录',
                                    'desc' => '在文章开头自动生成内容目录',
                                    'default' => false
                                ],
                                [
                                    'id' => 'toc-title-text',
                                    'type' => 'text',
                                    'title' => '目录标题文字',
                                    'default' => '文章目录',
                                    'dependency' => [['enable-toc', '==', 'true']]
                                ],
                                [
                                    'id' => 'toc-background-color',
                                    'type' => 'color', // 使用 color 类型选择器
                                    'title' => '目录背景颜色',
                                    'default' => '#f9f9f9',
                                    'dependency' => [['enable-toc', '==', 'true']]
                                ],
                                [
                                    'id' => 'toc-link-color', // 重命名 ID
                                    'type' => 'color', // 使用 color 类型选择器
                                    'title' => '目录链接颜色', // 修改标题
                                    'default' => '#1a0dab', // 修改默认值为常见的链接蓝色
                                    'dependency' => [['enable-toc', '==', 'true']]
                                ],
                                [
                                    'id' => 'toc-min-headings',
                                    'type' => 'number',
                                    'title' => '最小生成目录标题数',
                                    'desc' => '文章中至少需要多少个H2/H3标题才生成目录',
                                    'default' => 3,
                                    'min' => 1,
                                    'dependency' => [['enable-toc', '==', 'true']]
                                ],
                                // 新增：目录默认状态
                                [
                                    'id' => 'toc-default-state',
                                    'type' => 'radio',
                                    'title' => '目录默认状态',
                                    'options' => [
                                        'expanded' => '展开',
                                        'collapsed' => '折叠'
                                    ],
                                    'default' => 'expanded',
                                    'inline' => true,
                                    'dependency' => [['enable-toc', '==', 'true']]
                                ],
                                [
                                    'type' => 'heading',
                                    'content' => '图片WebP格式转换'
                                ],
                                [
                                    'id' => 'enable-webp-conversion',
                                    'type' => 'switcher',
                                    'title' => '开启图片WebP格式转换',
                                    // 更新描述，添加扩展要求提示
                                    'desc' => '自动将文章中的本地图片转换为WebP格式以优化加载速度。<br><strong>重要：</strong>此功能需要服务器 PHP 安装并启用 <strong>GD 和EXIF 扩展（并支持 WebP 功能）</strong> 或 <strong>Imagick 扩展</strong>。<br>如未开启扩展，请不要启用此功能<br><a href="https://www.2090ai.cn/exif" target="_blank"><查看宝塔站点如何开启exif扩展></a>',
                                    'default' => false,
                                    // Add sanitize callback to explicitly save 1 or 0
                                    'sanitize' => function( $value ) {
                                        return $value ? '1' : '0';
                                    }
                                ],
                                // 新增：使用 callback 字段显示服务器状态
                                [
                                    'id' => 'webp-support-status', // 给个ID以防万一
                                    'type' => 'callback',
                                    // 'title' => '服务器状态', // 不设置标题，使其紧随上方开关
                                    'function' => [$this, 'get_webp_support_status_html']
                                ],
                                // 为 DIV 选项添加描述
                            ]
                        ],
                        [
                            'title' => 'Google SEO设置',
                            'icon' => 'dashicons dashicons-admin-tools',
                            'fields' => [
                                [
                                    'type'    => 'content',
                                    'content' => '优化文章的搜索引擎表现，包括 Schema.org 结构化数据和社交媒体 Meta 标签等相关设置，可显著提高google评分。<br>
                                    注意：<br>
                                  某些主题自带以下标签，开启前请检查当前文章页面是否已开启相关功能，否则可能导致重复设置。<br>
                                    '
                                ],
                                [
                                    'id'      => 'enable_schema_org',
                                    'type'    => 'switcher',
                                    'title'   => '启用 Schema.org 结构化数据',
                                    'desc'    => '为文章和FAQ（如果生成）添加JSON-LD格式的结构化数据，有助于搜索引擎理解内容。',
                                    'default' => false
                                ],
                                [
                                    'id'      => 'schema_enable_publisher',
                                    'type'    => 'switcher',
                                    'title'   => 'Schema: 添加 Publisher 信息',
                                    'desc'    => '在结构化数据中包含网站发布者信息 (Organization)。',
                                    'default' => true, // Publisher info is generally good
                                    'dependency' => [['enable_schema_org', '==', 'true']]
                                ],
                                [
                                    'id'      => 'schema_enable_author',
                                    'type'    => 'switcher',
                                    'title'   => 'Schema: 添加 Author 信息',
                                    'desc'    => '在结构化数据中包含文章作者信息 (Person)。',
                                    'default' => true, // Author info is good
                                    'dependency' => [['enable_schema_org', '==', 'true']]
                                ],
                                [
                                    'id'      => 'schema_enable_inlanguage',
                                    'type'    => 'switcher',
                                    'title'   => 'Schema: 添加 Language 信息',
                                    'desc'    => '在结构化数据中包含文章内容的语言代码 (inLanguage)，例如 zh-CN, en-US。',
                                    'default' => true, // Language info helps targeting
                                    'dependency' => [['enable_schema_org', '==', 'true']]
                                ],
                                [
                                    'id'      => 'enable_og_twitter_meta',
                                    'type'    => 'switcher',
                                    'title'   => '启用 Open Graph & Twitter Card',
                                    'desc'    => '为文章添加 Open Graph (og:*) 和 Twitter Card (twitter:*) Meta 标签，增强社交媒体分享效果。',
                                    'default' => false
                                ],
                            ]
                        ],
                        [
                            'title' => '全局内容插',
                            'icon' => 'dashicons dashicons-editor-insertmore',
                            'fields' => [
                                [
                                    'type' => 'callback',
                                    'title' => '在全站文章中自定义内容',
                                    'function' => function() {
                                        echo '<p>在全站文章中插入自定义内容文本，支持HTML代码，支持站内站外自定义链接</p>';
                                        echo '<div class="notice notice-info inline" style="margin: 10px 0; padding: 10px;">';
                                        echo '<p><strong>随机段落功能说明：</strong></p>';
                                        echo '<p>1. 使用 <code>**段落内容**</code> 格式标记一个段落</p>';
                                        echo '<p>2. 使用 <code>|</code> 分隔多个段落，例如：<code>**段落一**|**段落二**|**段落三**</code></p>';
                                        echo '<p>3. 如果检测到多个段落标记，系统会在每次显示时随机选择其中一个段落</p>';
                                        echo '<p>4. 段落内可以包含HTML代码和任何格式化内容</p>';
                                        echo '</div>';
                            // 冗余说明保留在下方块中，不再在其它无关段落输出
                                    }
                                ],
                                [
                                    'id' => 'global_before_content',
                                    'type' => 'textarea',
                                    'title' => '全局内容前插入',
                                    'subtitle' => '在所有文章开头添加内容',
                                    'desc' => '支持HTML代码，例如：<br>&lt;div class="notice"&gt;全局公告...&lt;/div&gt;<br>使用 <code>**段落内容**|**另一段落**</code> 格式可实现随机显示其中一个段落',
                                    'sanitize' => false
                                ],
                                [
                                    'id' => 'global_middle_content',
                                    'type' => 'textarea',
                                    'title' => '全局内容中间插入',
                                    'subtitle' => '在所有文章50%位置插入',
                                    'desc' => '内容将插入到文章中间位置<br>支持HTML代码<br>使用 <code>**段落内容**|**另一段落**</code> 格式可实现随机显示其中一个段落',
                                    'sanitize' => false
                                ],
                                [
                                    'id' => 'global_after_content',
                                    'type' => 'textarea',
                                    'title' => '全局内容结尾插入',
                                    'subtitle' => '在所有文章结尾添加内容',
                                    'desc' => '支持HTML代码，例如统计代码等<br>使用 <code>**段落内容**|**另一段落**</code> 格式可实现随机显示其中一个段落',
                                    'sanitize' => false
                                ],
                            ]
                        ],
                        [
                            'title' => '自定义CSS',
                            'icon' => 'dashicons dashicons-art',
                            'fields' => [
                                [
                                    'type' => 'heading',
                                    'content' => 'CSS代码设置'
                                ],
                                [
                                    'id' => 'global_custom_css',
                                    'type' => 'code_editor',
                                    'title' => '自定义CSS代码',
                                    'subtitle' => '',
                                    'desc' => '输入自定义CSS代码，将自动应用到全站',
                                    'default' => '.li {list-style-type: none;}',
                                    'options' => [
                                        'language' => 'css',
                                        'theme' => 'dracula',
                                        'tabSize' => 2,
                                        'height' => 400,
                                        'toolbar' => false
                                    ],
                                    'settings' => [
                                        'codemirror' => [
                                            'lineNumbers' => true,
                                            'foldGutter' => true,
                                            'styleActiveLine' => true
                                        ]
                                    ]
                                ]
                            ]
                        ],
                        // 新增：导入导出选项卡
                        [
                            'title' => '导入导出',
                            'icon' => 'dashicons dashicons-download', // 使用下载图标
                            'fields' => [
                                [
                                    'type' => 'heading',
                                    'content' => '导出配置'
                                ],
                                // 导出按钮
                                [
                                    'id' => 'export_settings_button_wrapper',
                                    'type' => 'callback',
                                    'title' => '导出当前配置',
                                    'function' => function() {
                                        echo '<button type="button" class="button button-primary" onclick="exportAiPostSettings(this); return false;">导出配置到文件</button>';
                                    }
                                ],
                                [
                                    'type' => 'heading',
                                    'content' => '导入配置'
                                ],
                                // 导入文件选择
                                [
                                    'id' => 'import_settings_file_wrapper',
                                    'type' => 'callback',
                                    'title' => '选择配置文件',
                                    'function' => function() {
                                        // 注意 ID 用于 JS 选择器
                                        echo '<input type="file" id="ai_post_import_file_input" accept=".json" />';
                                        echo '<p class="description">选择一个 .json 格式的配置文件进行导入。<a href="https://version.suqianweb.cn/ai-post-settings-example.json" target="_blank">点击下载配置示例（右键另存为）</a></p>';
                                    }
                                ],
                                // 重新添加导入按钮
                                [
                                    'id' => 'import_settings_button_wrapper',
                                    'type' => 'callback',
                                    'title' => '导入配置', // 标题用于左侧标签
                                    'function' => function() {
                                        // 确保按钮的 onclick 调用正确的 JS 函数
                                        echo '<button type="button" class="button button-primary" onclick="importAiPostSettings(this); return false;">点击导入</button>';
                                    }
                                ],
                                // 添加说明和风险提示文本
                                [
                                    'id' => 'import_export_notes',
                                    'type' => 'callback',
                                    'function' => function() {
                                        // 使用 Flexbox 创建两列布局
                                        echo '<div style="display: flex; align-items: flex-start; gap: 20px; padding: 10px; border: 1px solid #ccd0d4; border-left-width: 4px; border-left-color: #d63638; margin-top: 15px;">';
                                        
                                        // 左侧内容区域
                                        echo '<div style="flex: 1;">'; // 占据剩余空间
                                        echo '<p><strong>说明：</strong></p>';
                                        echo '<ul style="list-style: disc; margin-left: 20px; margin-bottom: 15px;">'; // 增加下边距
                                        echo '<li>导出功能会将当前插件的所有配置（授权信息除外）保存为一个 .json 文件，方便备份或迁移。</li>';
                                        echo '<li>导入功能允许您上传之前导出的 .json 文件来恢复配置。</li>';
                                        echo '<li>导入功能不会覆盖你的授权信息和api令牌，只会覆盖插件基础设置。</li>';
                                        echo '</ul>';
                                        echo '<p><strong><span style="color: #d63638;">风险提示：</span></strong></p>';
                                        echo '<ul style="list-style: disc; margin-left: 20px;">';
                                        echo '<li>导入配置将会<strong>覆盖</strong>当前的基础设置，此操作不可逆，请谨慎操作！</li>';
                                        echo '<li>请确保导入的文件是使用<strong>相同版本</strong>的插件导出的，导入不兼容版本的配置文件可能导致未知错误或功能异常。</li>';
                                        echo '<li>导入来源不可靠的配置文件可能存在安全风险。</li>';
                                        echo '</ul>';
                                        echo '</div>'; // 结束左侧内容区域

                                        // 右侧图标区域
                                        echo '<div style="flex-shrink: 0; text-align: center; padding-top: 20px;">'; // 不收缩，居中，增加上边距
                                        // 使用 WordPress Dashicons 作为示例图标 (信息图标)
                                        echo '<span class="dashicons dashicons-info-outline" style="font-size: 64px; color: #787c82; width: 64px; height: 64px;"></span>'; 
                                        echo '</div>'; // 结束右侧图标区域

                                        echo '</div>'; // 结束 Flexbox 容器
                                    }
                                ],
                                // JavaScript for handling export/import
                                [
                                    'type' => 'callback',
                                    // 这个字段不需要 title，因为它只输出 JS
                                    'function' => function() {
                                        // 检查 $this 是否可用，如果不可用则需要传递 prefix
                                        $prefix = isset($this) && isset($this->prefix) ? $this->prefix : 'ai-post'; // 确保 prefix 可用
                                        $export_nonce = \wp_create_nonce('ai_post_export_settings_nonce');
                                        $import_nonce = \wp_create_nonce('ai_post_import_settings_nonce');
                                        ?>
                                        <script>
                                            // --- Export Function --- 
                                            if (typeof exportAiPostSettings !== 'function') {
                                                function exportAiPostSettings(btn) {
                                                    btn.disabled = true;
                                                    btn.textContent = '正在导出...';
                                                    if (typeof ajaxurl === 'undefined') {
                                                        alert('AJAX URL 未定义，无法导出。');
                                                        btn.disabled = false;
                                                        btn.textContent = '导出配置到文件';
                                                        return;
                                                    }
                                                    jQuery.post(ajaxurl, {
                                                        action: 'ai_post_export_settings',
                                                        nonce: '<?php echo $export_nonce; ?>'
                                                    }, function(response) {
                                                        if (response.success && response.data.settings_json) {
                                                            // 创建 Blob 对象
                                                            const blob = new Blob([response.data.settings_json], { type: 'application/json' });
                                                            const url = URL.createObjectURL(blob);
                                                            
                                                            // 创建临时链接并触发下载
                                                            const a = document.createElement('a');
                                                            a.href = url;
                                                            // 获取当前日期和时间用于文件名
                                                            const now = new Date();
                                                            const timestamp = now.getFullYear().toString() +
                                                                            (now.getMonth() + 1).toString().padStart(2, '0') +
                                                                            now.getDate().toString().padStart(2, '0') + '_' +
                                                                            now.getHours().toString().padStart(2, '0') +
                                                                            now.getMinutes().toString().padStart(2, '0') +
                                                                            now.getSeconds().toString().padStart(2, '0');
                                                            a.download = `ai-post-settings-${timestamp}.json`;
                                                            document.body.appendChild(a);
                                                            a.click();
                                                            
                                                            // 清理
                                                            document.body.removeChild(a);
                                                            URL.revokeObjectURL(url);
                                                            alert('配置文件已开始下载。');
                                                        } else {
                                                            alert('导出失败: ' + (response.data && response.data.message ? response.data.message : '未知错误'));
                                                        }
                                                        btn.disabled = false;
                                                        btn.textContent = '导出配置到文件';
                                                    }).fail(function(jqXHR, textStatus, errorThrown) {
                                                        console.error("Export AJAX Error:", textStatus, errorThrown);
                                                        alert('导出请求失败，请检查网络或查看浏览器控制台获取更多信息。');
                                                        btn.disabled = false;
                                                        btn.textContent = '导出配置到文件';
                                                    });
                                                }
                                            }

                                            // --- Import Function --- 
                                            if (typeof importAiPostSettings !== 'function') {
                                                function importAiPostSettings(btn) {
                                                    const fileInput = document.getElementById('ai_post_import_file_input');
                                                    
                                                    if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
                                                        alert('请先选择要导入的 .json 配置文件。');
                                                        return;
                                                    }
                                                    
                                                    const file = fileInput.files[0];
                                                    if (file.type !== 'application/json') {
                                                         alert('请选择一个有效的 .json 文件。');
                                                        return;
                                                    }

                                                    if (!confirm('确定要导入配置吗？当前设置将被覆盖！此操作不可恢复！')) {
                                                        return;
                                                    }

                                                    const reader = new FileReader();
                                                    reader.onload = function(event) {
                                                        const settingsJson = event.target.result;
                                                        
                                                        // 基础 JSON 格式验证
                                                        try {
                                                            JSON.parse(settingsJson);
                                                        } catch (e) {
                                                            alert('导入失败：文件内容不是有效的 JSON 格式。');
                                                            return;
                                                        }

                                                        btn.disabled = true;
                                                        btn.textContent = '正在导入...';
                                                        if (typeof ajaxurl === 'undefined') {
                                                            alert('AJAX URL 未定义，无法导入。');
                                                            btn.disabled = false;
                                                            btn.textContent = '点击导入';
                                                            return;
                                                        }
                                                        jQuery.post(ajaxurl, {
                                                            action: 'ai_post_import_settings',
                                                            nonce: '<?php echo $import_nonce; ?>',
                                                            settings_json: settingsJson // 发送文件内容
                                                        }, function(response) {
                                                            if (response.success) {
                                                                alert('配置已成功导入！页面将刷新以应用更改。');
                                                                location.reload();
                                                            } else {
                                                                alert('导入失败: ' + (response.data && response.data.message ? response.data.message : '未知错误'));
                                                                btn.disabled = false;
                                                                btn.textContent = '点击导入';
                                                            }
                                                        }).fail(function(jqXHR, textStatus, errorThrown) {
                                                            console.error("Import AJAX Error:", textStatus, errorThrown);
                                                            alert('导入请求失败，请检查网络或查看浏览器控制台获取更多信息。');
                                                            btn.disabled = false;
                                                            btn.textContent = '点击导入';
                                                        });
                                                    };
                                                    
                                                    reader.onerror = function() {
                                                        alert('读取文件时发生错误。');
                                                    };
                                                    
                                                    reader.readAsText(file); // 读取文件内容为文本
                                                }
                                            }
                                        </script>
                                        <?php
                                    }
                                ]
                            ]
                        ] // 结束导入导出选项卡
                        ,
                        // 新增：系统调试与日志（放在全局设定的最后一个选项卡）
                        [
                            'title' => '系统调试与日志',
                            'icon' => 'dashicons dashicons-admin-generic',
                            'fields' => [
                                [
                                    'type' => 'callback',
                                    'title' => '一键自检（WP-Cron/Loopback/证书/权限）',
                                    'subtitle' => '检测系统环境是否满足定时任务运行条件',
                                    'function' => [$this, 'render_self_diagnose_panel'],
                                ],
                                [
                                    'id' => 'enable-debug-log',
                                    'type' => 'switcher',
                                    'title' => '启用调试日志（不修改 wp-config）',
                                    'label' => '开启后将在站点根目录生成 debug.log（不可写则回退到 uploads/ai-post/logs/debug.log）',
                                    'default' => false,
                                    'desc' => '调试完毕请关闭，否则会生成大量日志文件，影响性能',
                                ],
                                [
                                    'type' => 'callback',
                                    'title' => '调试日志操作',
                                    'function' => [$this, 'render_debug_log_panel'],
                                ],
                                [
                                    'type' => 'callback',
                                    'title' => '通信令牌（Cron/REST）',
                                    'function' => [$this, 'render_cron_token_panel'],
                                ],
                            ],
                        ]
                    ]
                ]
            ]
        ]);

        // 运行日志 Tab（迁移为独立回调 render_run_log_panel）
        CGPS::createSection($this->prefix, [
            'id'    => 'log',
            'title' => '运行日志',
            'fields' => [
                [
                    'type' => 'callback',
                    'title' => '',
                    'function' => [$this, 'render_run_log_panel'],
                ],
            ],
        ]);
    }

    // （方法已迁移至 TraitExportImport）

    // 一键自检：WP-Cron/Loopback/证书/权限/任务注册等
    // （方法已迁移至 TraitSelfDiagnose）

    // （方法已迁移至 TraitExportImport）

    // 获取字体列表的方法（方式二专用）：优先扫描 uploads/aipost-fonts，其次扫描插件内 fonts 目录
    private function get_fonts_list() {
        $fonts_options = [];

        // 1) 优先：uploads/aipost-fonts 顶层（不递归）
        try {
            if (!function_exists('wp_upload_dir')) {
                require_once ABSPATH . 'wp-includes/functions.php';
            }
            $uploads = \wp_upload_dir();
            if (is_array($uploads) && !empty($uploads['basedir'])) {
                $upload_fonts_dir = rtrim($uploads['basedir'], '/\\') . DIRECTORY_SEPARATOR . 'aipost-fonts' . DIRECTORY_SEPARATOR;
                if (@is_dir($upload_fonts_dir)) {
                    $files = @scandir($upload_fonts_dir) ?: [];
                    foreach ($files as $f) {
                        if ($f === '.' || $f === '..') continue;
                        if (preg_match('/\.(ttf|otf|ttc)$/i', $f)) {
                            $fonts_options[$f] = $f; // 仅返回文件名，生成时会拼接目录
                        }
                    }
                }
            }
        } catch (\Throwable $e) {
            // 静默
        }

        // 2) 兜底：插件自带 fonts 目录（若存在）
        $plugin_fonts_dir = plugin_dir_path(__FILE__) . '../fonts/';
        if (@is_dir($plugin_fonts_dir)) {
            $plugin_fonts = @glob($plugin_fonts_dir . '*.{ttf,TTF,otf,OTF,ttc,TTC}', GLOB_BRACE) ?: [];
            foreach ($plugin_fonts as $file) {
                $font_name = basename($file);
                if (!isset($fonts_options[$font_name])) {
                    $fonts_options[$font_name] = $font_name;
                }
            }
        }

        // 3) 若仍为空，则提供友好占位提示
        if (empty($fonts_options)) {
            // 注意：部分 UI 框架不支持禁用选项，这里仅返回占位文案；保存时若值为空将视为未选择
            $fonts_options[''] = '未检测到字体文件，请上传字体文件至/wp-content/uploads/aipost-fonts目录下';
        }

        return $fonts_options;
    }

    public function ai_post_cron($task_key)
    {
        // 获取任务信息
        $tasks = get_option($this->prefix . '-tasks', []);
        
        // 从任务键中提取索引
        $task_index = str_replace($this->prefix . '-task-', '', $task_key);
        $task = isset($tasks[$task_index]) ? $tasks[$task_index] : null;
        
        if (!$task) {
            error_log("AI Post: 找不到任务：{$task_index}");
            return;
        }
        
        // 添加调度类型检查，默认为frequency
        $schedule_type = $task['task-schedule-type'] ?? 'frequency';
        
        if ($schedule_type === 'timespan') {
            $should_run = false;
            $current_time = current_time('H:i');
            
            error_log("AI Post Debug: 当前时间 {$current_time}，检查时间段");
            
            if (isset($task['task-timespans']) && is_array($task['task-timespans'])) {
                foreach ($task['task-timespans'] as $timespan) {
                    $start_time = $timespan['start-time'] ?? '';
                    $end_time = $timespan['end-time'] ?? '';
                    $timespan_frequency = intval($timespan['timespan-frequency'] ?? 1);
                    
                    error_log("AI Post Debug: 检查时间段 {$start_time} 至 {$end_time}，频率 {$timespan_frequency}分钟");
                    
                    if ($start_time && $end_time) {
                        // 检查当前时间是否在时间段内
                        if ($this->is_time_between($current_time, $start_time, $end_time)) {
                            error_log("AI Post Debug: 当前时间在时间段 {$start_time} 至 {$end_time} 内");
                            
                            // 检查最后执行时间
                            $last_run = get_option("{$this->prefix}_last_run_{$task_key}", 0);
                            $time_diff = floor((time() - $last_run) / 60);
                            
                            if ($time_diff >= $timespan_frequency) {
                                error_log("AI Post Debug: 时间差 {$time_diff} 分钟，满足执行频率 {$timespan_frequency} 分钟");
                                $should_run = true;
                                break;
                            } else {
                                error_log("AI Post Debug: 时间差 {$time_diff} 分钟，不满足执行频率 {$timespan_frequency} 分钟");
                            }
                        } else {
                            error_log("AI Post Debug: 当前时间不在时间段 {$start_time} 至 {$end_time} 内");
                        }
                    }
                }
            }
            
            if (!$should_run) {
                error_log("AI Post Debug: 当前时间不在任何执行时间段内或未达到执行频率，跳过执行");
                return;
            }
        }
        
        // 更新最后执行时间
        update_option("{$this->prefix}_last_run_{$task_key}", time());
        
        // 继续执行原有的任务逻辑...
    }

    /**
     * 检查当前时间是否在给定的时间段内
     */
    private function is_time_between($current, $start, $end)
    {
        // 将时间转换为分钟数进行比较
        $current_minutes = $this->time_to_minutes($current);
        $start_minutes = $this->time_to_minutes($start);
        $end_minutes = $this->time_to_minutes($end);
        
        error_log("AI Post Debug: 当前分钟数 {$current_minutes}，开始分钟数 {$start_minutes}，结束分钟数 {$end_minutes}");
        
        // 处理跨天的情况
        if ($end_minutes < $start_minutes) {
            return $current_minutes >= $start_minutes || $current_minutes <= $end_minutes;
        }
        
        return $current_minutes >= $start_minutes && $current_minutes <= $end_minutes;
    }

    /**
     * 将时间字符串转换为分钟数
     */
    private function time_to_minutes($time)
    {
        list($hours, $minutes) = explode(':', $time);
        return (intval($hours) * 60) + intval($minutes);
    }

    public function update_plugin(): void
    {
        // 获取当前版本
        $current_version = get_option($this->prefix . '-version');
        $plugin_version = defined('HAOZI_AIPOST_VERSION') ? HAOZI_AIPOST_VERSION : '2.8.5';
        
        // 如果是从旧版本更新（没有调度类型选项）
        if (version_compare($current_version, '1.x.x', '<')) { // 替换为实际的版本号
            // 获取现有任务
            $tasks = get_option($this->prefix . '-tasks', []);
            
            // 为每个任务添加调度类型
            foreach ($tasks as &$task) {
                if (!isset($task['task-schedule-type'])) {
                    $task['task-schedule-type'] = 'frequency';
                }
            }
            
            // 保存更新后的任务
            update_option($this->prefix . '-tasks', $tasks);
            
            // 记录迁移日志
            error_log("AI Post: 更新完成，已为现有任务设置默认调度类型为'按频率'");
        }
        
        // 更新版本号
        update_option($this->prefix . '-version', $plugin_version);
    }

    /**
     * 获取 WebP 支持状态的 HTML 提示
     * @return string
     */
    private function get_webp_support_status_html(): string
    {
        $gd_ok = extension_loaded('gd') && function_exists('imagewebp');
        $imagick_ok = extension_loaded('imagick');
        if ($gd_ok || $imagick_ok) {
            $support_details = [];
            if ($gd_ok) $support_details[] = 'GD (支持 WebP)';
            if ($imagick_ok) $support_details[] = 'Imagick';
            return '<span style="color: #46b450; margin-left: 10px; font-weight: bold;">(服务器支持: ' . implode(' / ', $support_details) . ')</span>';
        } else {
            return '<span style="color: #dc3232; margin-left: 10px; font-weight: bold;">(服务器不支持: 未启用 GD[WebP]/Imagick)</span>';
        }
    }

    // 日志表格渲染方法已迁移至 TraitRunLogPanel
    /**
     * 只读日志回显：当保存 ai-post-tasks 时，把本次即将入库的任务中与“配图方式三（文生图）”相关的关键字段打印到 debug.log。
     * 注意：不修改 $new_value，仅用于可观测性，便于判断运行时是否命中方式三。
     *
     * @param mixed  $new_value
     * @param mixed  $old_value
     * @param string $option  预期为 'ai-post-tasks'
     * @return mixed 原样返回 $new_value
     */
    // （方法已迁移至 TraitTasksRouteAndValidate）

    // （方法已迁移至 TraitTasksRouteAndValidate）

    // 顶部提示已取消：不再渲染“任务已保存到独立选项（ai-post-tasks）...”的管理提示。
    public function maybe_show_tasks_routed_notice(): void
    {
        return; // no-op
    }

    // 渲染：授权操作（即时校验）
    public function render_license_block(): void
    {
        $nonce = \wp_create_nonce('ai_post_check_license');
        $adminAjax = \admin_url('admin-ajax.php');
        // 初始渲染：预填当前授权状态（如可用）
        $initialHtml = '';
        if (function_exists('auth_info')) {
            ob_start();
            try { auth_info(); } catch (\Throwable $e) { echo '授权检查异常：' . esc_html($e->getMessage()); }
            $initialHtml = ob_get_clean();
        }
        ?>
        <div class="ai-post-license-panel" style="background:#f8f9fa;border:1px solid #e5e7eb;border-radius:6px;padding:12px;">
            <div style="display:flex;gap:8px;align-items:center;margin-bottom:8px;">
                <button type="button" class="button button-primary" id="ai-post-validate-license">立即校验授权</button>
                <span style="color:#666;">无需刷新页面，保存并校验当前输入的卡号/卡密</span>
            </div>
            <div id="ai-post-live-auth" style="padding:8px;border-radius:4px;background:#fff;border:1px solid #e5e7eb;"><?php echo $initialHtml; ?></div>
        </div>
        <script>
        (function($){
            $('#ai-post-validate-license').on('click', function(){
                var $btn = $(this);
                var num = $('input[name="ai-post[cardNum]"]').val() || '';
                var pwd = $('input[name="ai-post[cardPwd]"]').val() || '';
                $btn.prop('disabled', true).text('正在校验...');
                $.post('<?php echo esc_js($adminAjax); ?>', {
                    action: 'ai_post_check_license',
                    _wpnonce: '<?php echo esc_js($nonce); ?>',
                    cardNum: num,
                    cardPwd: pwd
                }).done(function(res){
                    var $live = $('#ai-post-live-auth');
                    if(res && res.success){
                        $live.html(res.data && res.data.html ? res.data.html : '已保存并校验');
                    } else {
                        $live.html((res && res.data && res.data.message) ? res.data.message : '校验失败');
                    }
                    $live.show();
                }).fail(function(){
                    alert('请求失败');
                }).always(function(){
                    $btn.prop('disabled', false).text('立即校验授权');
                });
            });
        })(jQuery);
        </script>
        <?php
    }

    // AJAX：保存并即时校验授权
    public function ajax_check_license(): void
    {
        \check_ajax_referer('ai_post_check_license');
        if (!\current_user_can('manage_options')) {
            \wp_send_json_error(['message' => '权限不足'], 403);
        }
        @error_log('[ai-post][license] ajax_check_license entry');
        $cardNum = isset($_POST['cardNum']) ? trim((string) $_POST['cardNum']) : '';
        $cardPwd = isset($_POST['cardPwd']) ? trim((string) $_POST['cardPwd']) : '';

        // 授权调试日志：记录当前环境与入参（敏感字段做哈希脱敏）
        try {
            $logDir = (defined('WP_CONTENT_DIR') ? rtrim(WP_CONTENT_DIR, '/\\') : dirname(__DIR__, 3) . '/wp-content') . '/uploads/ai-post/logs';
            if (!@is_dir($logDir)) { @wp_mkdir_p($logDir); }
            if (!@is_dir($logDir)) { @mkdir($logDir, 0775, true); }
            $logFile = $logDir . '/license-debug.log';
            $meta = [
                'ts' => date('Y-m-d H:i:s'),
                'stage' => 'before_save',
                'plugin' => 'ai-post',
                'siteurl' => get_option('siteurl'),
                'home' => get_option('home'),
                'http_host' => $_SERVER['HTTP_HOST'] ?? null,
                'server_name' => $_SERVER['SERVER_NAME'] ?? null,
                'server_addr' => $_SERVER['SERVER_ADDR'] ?? null,
                'remote_addr' => $_SERVER['REMOTE_ADDR'] ?? null,
                'https' => isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : null,
                'x_forwarded_host' => $_SERVER['HTTP_X_FORWARDED_HOST'] ?? null,
                'x_forwarded_proto' => $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? null,
                'request_uri' => $_SERVER['REQUEST_URI'] ?? null,
                'wp_is_ssl' => function_exists('is_ssl') ? is_ssl() : null,
                'multisite' => function_exists('is_multisite') ? is_multisite() : null,
                'cardNum_hash' => $cardNum !== '' ? substr(sha1($cardNum), 0, 12) : null,
                'cardPwd_hash' => $cardPwd !== '' ? substr(sha1($cardPwd), 0, 12) : null,
                'user' => wp_get_current_user() ? (wp_get_current_user()->user_login ?? null) : null,
            ];
            if (@file_put_contents($logFile, json_encode($meta, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND) === false) {
                @error_log('[ai-post][license] write before_save failed: ' . $logFile);
            }
            @error_log('[ai-post][license] wrote before_save to: ' . $logFile);
        } catch (\Throwable $e) {
            // 忽略日志错误
            @error_log('[ai-post][license] before_save exception: ' . $e->getMessage());
        }

        // 先进行硬校验：利用 cgps-framework 注入的 verify 过滤器（model-selection）
        // 但若用户提供了“新的卡号/卡密”与已保存值不同，则放宽预检（soft-bypass），
        // 允许继续进入 auth_info() 的真实校验，以便用户能用新卡密“自救”。
        try {
            $precheck = apply_filters('model-selection', true);
            if ($precheck === false) {
                $saved = \get_option('ai-post', []);
                $savedNum = is_array($saved) && !empty($saved['cardNum']) ? trim((string)$saved['cardNum']) : '';
                $savedPwd = is_array($saved) && !empty($saved['cardPwd']) ? trim((string)$saved['cardPwd']) : '';
                $providedBoth = ($cardNum !== '' && $cardPwd !== '');
                $isDifferent = ($cardNum !== '' && $cardNum !== $savedNum) || ($cardPwd !== '' && $cardPwd !== $savedPwd);
                if ($providedBoth && $isDifferent) {
                    @error_log('[ai-post][license] precheck failed but soft-bypass with new credentials for live auth_info check');
                    // 继续后续流程：不立即阻断
                } else {
                    @error_log('[ai-post][license] precheck(model-selection) failed, block saving');
                    // 返回 200 + success=false，避免前端网络层 .fail 导致界面卡死
                    \wp_send_json_error(['message' => '设备认证失败：该卡密已被其他域名绑定或校验不通过']);
                }
            }
        } catch (\Throwable $e) {
            @error_log('[ai-post][license] precheck exception: ' . $e->getMessage());
        }

        // 暂不保存：先渲染校验，再决定是否写入
        $pendingOpts = \get_option('ai-post', []);
        if (!is_array($pendingOpts)) { $pendingOpts = []; }
        $pendingOpts['cardNum'] = $cardNum;
        $pendingOpts['cardPwd'] = $cardPwd;

        // 复用现有授权状态渲染（如存在）
        $html = '';
        if (function_exists('auth_info')) {
            // 在 auth_info() 执行期间捕获所有外发 HTTP 请求
            $logDir = (defined('WP_CONTENT_DIR') ? rtrim(WP_CONTENT_DIR, '/\\') : dirname(__DIR__, 3) . '/wp-content') . '/uploads/ai-post/logs';
            if (!@is_dir($logDir)) { @wp_mkdir_p($logDir); }
            if (!@is_dir($logDir)) { @mkdir($logDir, 0775, true); }
            $logFile = $logDir . '/license-debug.log';
            // 记录 auth_info 的来源（文件/起始行）
            try {
                $ref = new \ReflectionFunction('auth_info');
                $src = [
                    'ts' => date('Y-m-d H:i:s'),
                    'stage' => 'auth_info_reflection',
                    'file' => $ref->getFileName(),
                    'start_line' => $ref->getStartLine(),
                ];
                @file_put_contents($logFile, json_encode($src, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND);
            } catch (\Throwable $e) {
                @error_log('[ai-post][license] reflection error: ' . $e->getMessage());
            }
            // 注册 shutdown 捕捉意外终止
            $shutdownCb = function() use ($logFile) {
                $err = error_get_last();
                $entry = [
                    'ts' => date('Y-m-d H:i:s'),
                    'stage' => 'shutdown',
                    'last_error' => $err ? ($err['message'] ?? 'unknown') : null,
                ];
                @file_put_contents($logFile, json_encode($entry, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND);
            };
            register_shutdown_function($shutdownCb);
            $callback = function($response, $context, $class, $parsed_args, $url) use ($logFile) {
                try {
                    $entry = [
                        'ts' => date('Y-m-d H:i:s'),
                        'stage' => 'http_api_debug',
                        'url' => $url,
                        'method' => $parsed_args['method'] ?? 'GET',
                        'headers' => $parsed_args['headers'] ?? [],
                        'body_len' => isset($parsed_args['body']) ? strlen((string)$parsed_args['body']) : 0,
                        'response_code' => is_wp_error($response) ? -1 : (int) wp_remote_retrieve_response_code($response),
                        'response_len' => is_wp_error($response) ? 0 : strlen((string) wp_remote_retrieve_body($response)),
                        'error' => is_wp_error($response) ? $response->get_error_message() : null,
                    ];
                    @file_put_contents($logFile, json_encode($entry, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND);
                } catch (\Throwable $e) {}
            };
            \add_action('http_api_debug', $callback, 10, 5);

            // 使用 pre_option_ai-post 临时注入卡密，不修改数据库
            $inject = function($pre) use ($pendingOpts) {
                return $pendingOpts;
            };
            \add_filter('pre_option_ai-post', $inject, 10, 1);

            ob_start();
            try { auth_info(); } catch (\Throwable $e) { echo '授权检查异常：' . esc_html($e->getMessage()); @error_log('[ai-post][license] auth_info exception: ' . $e->getMessage()); }
            $html = ob_get_clean();

            \remove_action('http_api_debug', $callback, 10);
            \remove_filter('pre_option_ai-post', $inject, 10);
            // 正常结束：写入标记并返回，避免 shutdown 再次写入混淆
            try {
                $entry = [
                    'ts' => date('Y-m-d H:i:s'),
                    'stage' => 'auth_info_done'
                ];
                @file_put_contents($logFile, json_encode($entry, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND);
            } catch (\Throwable $e) {}
        } else {
            $html = '<div class="notice notice-info"><p>已保存卡号与卡密，如未显示详细授权信息，请刷新页面。</p></div>';
        }

        // 授权调试日志：记录渲染结果片段
        try {
            $logDir = (defined('WP_CONTENT_DIR') ? rtrim(WP_CONTENT_DIR, '/\\') : dirname(__DIR__, 3) . '/wp-content') . '/uploads/ai-post/logs';
            if (!@is_dir($logDir)) { @wp_mkdir_p($logDir); }
            if (!@is_dir($logDir)) { @mkdir($logDir, 0775, true); }
            $logFile = $logDir . '/license-debug.log';
            $snippet = is_string($html) ? mb_substr(strip_tags($html), 0, 200, 'UTF-8') : '';
            $meta = [
                'ts' => date('Y-m-d H:i:s'),
                'stage' => 'after_render',
                'snippet' => $snippet,
            ];
            if (@file_put_contents($logFile, json_encode($meta, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND) === false) {
                @error_log('[ai-post][license] write after_render failed: ' . $logFile);
            }
            @error_log('[ai-post][license] wrote after_render to: ' . $logFile);
        } catch (\Throwable $e) {
            // 忽略日志错误
            @error_log('[ai-post][license] after_render exception: ' . $e->getMessage());
        }

        // 过期判定：从渲染片段中提取“到期时间”并与当前时间比较
        $expired = false;
        $deviceFail = false; // 新增：设备认证失败（被其他域名绑定/校验不通过）
        if (is_string($html)) {
            if (preg_match('/到期时间\s*->\s*([0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}:[0-9]{2})/u', strip_tags($html), $m)) {
                $expTs = strtotime($m[1]);
                $nowTs = function_exists('current_time') ? current_time('timestamp') : time();
                if ($expTs !== false && $expTs < $nowTs) {
                    $expired = true;
                }
            }
            // 设备认证失败的多样文案容错：设备认证失败 / 已被其他域名绑定 / 校验不通过
            $plain = strip_tags($html);
            if (preg_match('/设备认证失败|其他域名绑定|已被其他域名绑定|校验不通过/u', $plain)) {
                $deviceFail = true;
            }
        }
        
        if ($expired || $deviceFail) {
            if ($expired) {
                @error_log('[ai-post][license] expired detected, block saving');
                \wp_send_json_error(['message' => '设备认证失败：该卡密已过期，请更换有效卡密', 'expired' => true]);
            } else {
                @error_log('[ai-post][license] device verification failed, block saving');
                \wp_send_json_error(['message' => '设备认证失败：该卡密已被其他域名绑定或校验不通过', 'expired' => false]);
            }
        }

        // 校验通过后再保存
        $opts = \get_option('ai-post', []);
        if (!is_array($opts)) { $opts = []; }
        $opts['cardNum'] = $cardNum;
        $opts['cardPwd'] = $cardPwd;
        \update_option('ai-post', $opts);

        \wp_send_json_success(['html' => $html, 'log_path' => isset($logFile) ? $logFile : null, 'expired' => false]);
    }

    // 服务器端兜底：保存前阻止过期卡密入库
    public function guard_expired_on_save($new_value, $old_value, $option)
    {
        try {
            if ($option !== 'ai-post' || !is_array($new_value)) { return $new_value; }

            // 仅在“用户发起的设置保存”时才执行拦截：后台、存在 POST 提交
            if (!is_admin()) { return $new_value; }
            if (empty($_POST)) { return $new_value; }
            // AJAX 情况：仅当为 cgps-import（CGPS 配置保存）时才拦截，其它 AJAX 直接放行
            if (function_exists('wp_doing_ajax') && wp_doing_ajax()) {
                $act = isset($_POST['action']) ? (string)$_POST['action'] : '';
                if ($act !== 'cgps-import') { return $new_value; }
            }

            // 只要 POST 中提交了卡号/卡密，就执行检测
            $cardNum = isset($new_value['cardNum']) ? (string)$new_value['cardNum'] : '';
            $cardPwd = isset($new_value['cardPwd']) ? (string)$new_value['cardPwd'] : '';
            if ($cardNum === '' && $cardPwd === '') { return $new_value; }

            // 临时注入待保存值，调用 auth_info() 获取到期时间
            $pendingOpts = $new_value;
            $inject = function($pre) use ($pendingOpts) { return $pendingOpts; };
            \add_filter('pre_option_ai-post', $inject, 10, 1);

            $html = '';
            // 写入 guard 日志
            try {
                $logDir = (defined('WP_CONTENT_DIR') ? rtrim(WP_CONTENT_DIR, '/\\') : dirname(__DIR__, 3) . '/wp-content') . '/uploads/ai-post/logs';
                if (!@is_dir($logDir)) { @wp_mkdir_p($logDir); }
                if (!@is_dir($logDir)) { @mkdir($logDir, 0775, true); }
                $logFile = $logDir . '/license-debug.log';
                @file_put_contents($logFile, json_encode([
                    'ts' => date('Y-m-d H:i:s'),
                    'stage' => 'pre_update_guard',
                    'cardNum_hash' => $cardNum !== '' ? substr(sha1($cardNum),0,12) : null,
                    'cardPwd_hash' => $cardPwd !== '' ? substr(sha1($cardPwd),0,12) : null,
                ], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) . "\n", FILE_APPEND);
            } catch (\Throwable $e) {}
            if (function_exists('auth_info')) {
                ob_start();
                try { auth_info(); } catch (\Throwable $e) { /* ignore */ }
                $html = ob_get_clean();
            }
            \remove_filter('pre_option_ai-post', $inject, 10);

            $expired = false;
            $deviceFail = false; // 新增
            if (is_string($html)) {
                if (preg_match('/到期时间\s*->\s*([0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}:[0-9]{2})/u', strip_tags($html), $m)) {
                    $expTs = strtotime($m[1]);
                    $nowTs = function_exists('current_time') ? current_time('timestamp') : time();
                    if ($expTs !== false && $expTs < $nowTs) { $expired = true; }
                }
                $plain = strip_tags($html);
                if (preg_match('/设备认证失败|其他域名绑定|已被其他域名绑定|校验不通过/u', $plain)) { $deviceFail = true; }
            }
            if ($expired || $deviceFail) {
                if ($expired) {
                    @error_log('[ai-post][license] guard_expired_on_save blocked: expired');
                    \update_option('ai_post_expired_notice', '卡密已过期，如需继续使用，请联系客服续期。');
                } else {
                    @error_log('[ai-post][license] guard_expired_on_save blocked: device verification failed');
                    \update_option('ai_post_expired_notice', '设备认证失败：该卡密已被其他域名绑定或校验不通过');
                }
                return $old_value; // 阻止保存
            }
        } catch (\Throwable $e) {
            // 安全失败：不中断正常保存
            @error_log('[ai-post][license] guard_expired_on_save exception: ' . $e->getMessage());
        }
        return $new_value;
    }

    public function maybe_show_expired_notice(): void
    {
        $msg = \get_option('ai_post_expired_notice');
        if ($msg) {
            echo '<div class="notice notice-error is-dismissible"><p>' . esc_html($msg) . '</p></div>';
            \delete_option('ai_post_expired_notice');
        }
    }

    // 在设置页注入前端脚本：授权过期则禁用保存按钮
    public function inject_license_expire_guard_js(): void
    {
        if (!is_admin()) { return; }
        $screen = function_exists('get_current_screen') ? get_current_screen() : null;
        if (!$screen || strpos((string)$screen->id, 'ai-post') === false) { return; }
        $nonce = function_exists('wp_create_nonce') ? wp_create_nonce('ai_post_check_license') : '';
        ?>
        <script>
        (function($){
          var AIPO_NC = <?php echo json_encode($nonce); ?>;
          function markExpired(msg){
            // 顶部保存按钮
            var $btnTop = $('.cgps-header-right .cgps-buttons .cgps-top-save.cgps-save-ajax');
            if($btnTop.length){
              $btnTop.prop('disabled', true).addClass('button-disabled');
            }
            // 底部保存按钮
            var $btnBottom = $(".cgps-buttons input[name='cgps_transient[save]'].cgps-save-ajax");
            if($btnBottom.length){
              $btnBottom.prop('disabled', true).addClass('button-disabled');
            }
            // 顶部统一提示
            if($('.notice.aipost-expired-notice').length===0){
              var tip = msg && (msg+'').trim()!=='' ? msg+'' : '卡密已过期，如需继续使用，请联系客服续期。';
              var $notice = $('<div class="notice notice-error aipost-expired-notice"><p></p></div>');
              $notice.find('p').text(tip);
              $('#wpbody-content').find('.wrap').first().prepend($notice);
            } else {
              // 更新已有提示文案
              var tip = msg && (msg+'').trim()!=='' ? msg+'' : '卡密已过期，如需继续使用，请联系客服续期。';
              $('.notice.aipost-expired-notice').find('p').text(tip);
            }
          }

          // 修复：当用户输入新的未过期卡密并校验通过后，需要恢复保存按钮可用状态并移除过期提示
          function unmarkExpired(){
            // 顶部保存按钮
            var $btnTop = $('.cgps-header-right .cgps-buttons .cgps-top-save.cgps-save-ajax');
            if($btnTop.length){
              $btnTop.prop('disabled', false).removeClass('button-disabled');
            }
            // 底部保存按钮
            var $btnBottom = $(".cgps-buttons input[name='cgps_transient[save]'].cgps-save-ajax");
            if($btnBottom.length){
              $btnBottom.prop('disabled', false).removeClass('button-disabled');
            }
            // 移除顶部过期提示
            $('.notice.aipost-expired-notice').remove();
          }

          function findField(names){
            for(var i=0;i<names.length;i++){
              var sel = 'input[name="'+names[i]+'"]';
              var $el = $(sel);
              if($el.length && $.trim($el.val())!==''){ return $el; }
            }
            // 兜底：猜测以 [cardNum]/[cardPwd] 结尾
            var $guess = $('input[name$="[cardNum]"],input[name$="[cardPwd]"]');
            if($guess.length){ return $guess; }
            return $();
          }

          function autoCheck(){
            // 尝试多种常见命名
            var $num = findField(['ai-post[cardNum]','aipost[cardNum]','cardNum']);
            var $pwd = findField(['ai-post[cardPwd]','aipost[cardPwd]','cardPwd']);
            var num = $.trim($num.val()||'');
            var pwd = $.trim($pwd.val()||'');
            if(!num || !pwd){ return; }
            $.post(ajaxurl, {
              action: 'ai_post_check_license',
              _ajax_nonce: AIPO_NC,
              cardNum: num,
              cardPwd: pwd
            }).done(function(res){
              try{
                if(typeof res === 'string') res = JSON.parse(res);
              }catch(e){}
              if(res && res.success===false){
                var msg = res.data && res.data.message ? (res.data.message+'') : '';
                var expired = (res.data && res.data.expired===true) || (msg.indexOf('已过期')!==-1);
                var deviceFail = (msg.indexOf('设备认证失败')!==-1) || (msg.indexOf('已被其他域名绑定')!==-1) || (msg.indexOf('绑定')!==-1 && msg.indexOf('域名')!==-1) || (msg.indexOf('校验不通过')!==-1);
                if(expired || deviceFail){ markExpired(msg); }
              } else if(res && res.success===true){
                // 成功则恢复可保存状态
                var notExpired = !(res.data && res.data.expired===true);
                if(notExpired){ unmarkExpired(); }
              }
            });
          }

          // 代理全局 AJAX：专门识别 ai_post_check_license 的返回
          $(document).ajaxSuccess(function(e, xhr, settings){
            try{
              if(!settings || !settings.data) return;
              if(typeof settings.data === 'string' && settings.data.indexOf('action=ai_post_check_license') !== -1){
                var res = {};
                try{ res = JSON.parse(xhr.responseText || '{}'); }catch(ex){}
                var blocked = false;
                if(res && res.success===false){
                  var msg = res.data && res.data.message ? res.data.message+'' : '';
                  var expired = (res.data && res.data.expired===true) || (msg.indexOf('已过期') !== -1);
                  var deviceFail = (msg.indexOf('设备认证失败')!==-1) || (msg.indexOf('已被其他域名绑定')!==-1) || (msg.indexOf('绑定')!==-1 && msg.indexOf('域名')!==-1) || (msg.indexOf('校验不通过')!==-1);
                  blocked = expired || deviceFail;
                }
                if(blocked){ markExpired(res && res.data && res.data.message ? res.data.message+'' : ''); }
                else if(res && res.success===true){ unmarkExpired(); }
              }
            }catch(ex){}
          });

          // 页面加载后自动校验一次
          $(function(){ autoCheck(); });
        })(jQuery);
        </script>
        <?php
    }
}
