<?php

namespace App\Services;

use App\Models\PromptTemplate;
use Illuminate\Support\Facades\Log;

class PromptService
{
    private const DEFAULT_QUESTION_PROMPT_NAME = 'question_generation_default';
    private const DEFAULT_QUESTION_PROMPT_TYPE = 'question_generation';
    private const DEFAULT_ENRICH_PROMPT_NAME = 'question_enrich_default';
    private const DEFAULT_ENRICH_PROMPT_TYPE = 'question_enrich';
    private const DEFAULT_SOLUTION_PROMPT_NAME = 'question_solution_regen_default';
    private const DEFAULT_SOLUTION_PROMPT_TYPE = 'question_solution_regen';

    /**
     * 获取提示词列表
     */
    public function listPrompts(?string $type = null, ?string $active = null): array
    {
        if ($type === null || $type === self::DEFAULT_QUESTION_PROMPT_TYPE) {
            $this->ensureDefaultQuestionPrompt();
        }
        if ($type === null || $type === self::DEFAULT_ENRICH_PROMPT_TYPE) {
            $this->ensureDefaultEnrichPrompt();
        }
        if ($type === null || $type === self::DEFAULT_SOLUTION_PROMPT_TYPE) {
            $this->ensureDefaultSolutionPrompt();
        }

        $query = PromptTemplate::query();
        if ($type) {
            $query->where('template_type', $type);
        }
        if ($active !== null) {
            $query->where('is_active', $active === 'yes' || $active === true);
        }

        return $query->orderByDesc('updated_at')
            ->get()
            ->map(fn (PromptTemplate $prompt) => $this->mapPrompt($prompt))
            ->values()
            ->all();
    }

    /**
     * 保存提示词
     */
    public function savePrompt(array $data): array
    {
        try {
            $templateName = (string) ($data['template_name'] ?? '');
            if ($templateName === '') {
                return ['success' => false, 'message' => '模板名称不能为空'];
            }

            $payload = [
                'template_type' => $data['template_type'] ?? 'question_generation',
                'template_content' => $data['template_content'] ?? '',
                'variables' => $this->parseJsonField($data['variables'] ?? []),
                'description' => $data['description'] ?? null,
                'tags' => $this->parseJsonField($data['tags'] ?? []),
                'is_active' => ($data['is_active'] ?? 'yes') === 'yes' || ($data['is_active'] === true),
            ];

            PromptTemplate::updateOrCreate(
                ['template_name' => $templateName],
                $payload
            );

            return ['success' => true, 'message' => '提示词已保存'];
        } catch (\Exception $e) {
            Log::error('保存提示词异常', [
                'error' => $e->getMessage()
            ]);
            return ['success' => false, 'message' => '保存失败'];
        }
    }

    public function deletePrompt(string $templateName): bool
    {
        return PromptTemplate::where('template_name', $templateName)->delete() > 0;
    }

    public function importFromArray(array $prompts): array
    {
        $imported = 0;
        $updated = 0;
        $errors = [];

        foreach ($prompts as $prompt) {
            $templateName = (string) ($prompt['template_name'] ?? $prompt['name'] ?? '');
            if ($templateName === '') {
                continue;
            }

            $payload = [
                'template_name' => $templateName,
                'template_type' => $prompt['template_type'] ?? $prompt['type'] ?? 'question_generation',
                'template_content' => $prompt['template_content'] ?? '',
                'variables' => $this->parseJsonField($prompt['variables'] ?? []),
                'description' => $prompt['description'] ?? null,
                'tags' => $this->parseJsonField($prompt['tags'] ?? []),
                'is_active' => ($prompt['is_active'] ?? 'yes') === 'yes' || ($prompt['is_active'] === true),
            ];

            try {
                $existing = PromptTemplate::query()->where('template_name', $templateName)->first();
                PromptTemplate::updateOrCreate(['template_name' => $templateName], $payload);
                $existing ? $updated++ : $imported++;
            } catch (\Throwable $e) {
                $errors[] = $templateName . ': ' . $e->getMessage();
            }
        }

        return [
            'success' => true,
            'imported' => $imported,
            'updated' => $updated,
            'errors' => $errors,
        ];
    }

    public function getPrompt(string $templateName): ?array
    {
        $prompt = PromptTemplate::where('template_name', $templateName)->first();
        return $prompt ? $this->mapPrompt($prompt) : null;
    }

    public function getPromptContent(string $templateName): ?string
    {
        $prompt = PromptTemplate::where('template_name', $templateName)->first();
        return $prompt?->template_content;
    }

    /**
     * 获取默认提示词模板
     */
    public function getDefaultPromptTemplate(): string
    {
        return '你是资深的中学数学命题专家，请为{knowledge_point}知识点生成高质量题目。

【核心要求】
1. 题目必须符合{grade_level}年级水平
2. 难度分布：基础({basic_ratio}%) + 中等({intermediate_ratio}%) + 拔高({advanced_ratio}%)
3. 题型分配：选择题({choice}道) + 填空题({fill}道) + 解答题({solution}道)

【难度提示（来源于卷子位置）】
- 若提供题目编号/位置：{question_index} / {question_position_hint}
- 可据此对难度系数做初步判断：卷首偏基础，卷中偏中等，卷末偏拔高

【技能覆盖】
{skill_coverage}

【图示处理】
- 如果题目涉及图形/示意图/坐标系/几何草图，必须在题干内内嵌一段完整的 <svg> 标签来还原图形；不要使用外链图片、base64 或占位符。
- SVG 要包含明确的宽高（建议 260~360 像素），只使用基础图元（line、rect、circle、polygon、path、text），并给出必要的坐标、角点和标注文本。
- 确保题干文本描述与 SVG 一致，例如“如图所示”后紧跟 SVG，且 SVG 放在题干末尾即可被前端直接渲染。

【质量标准】
- 准确性：100%正确
- 多样性：避免重复
- 梯度性：难度递进合理
- 实用性：贴近实际应用

【输出格式】
{
  "total": {count},
  "questions": [
    {
      "id": "唯一标识",
      "stem": "题干",
      "answer": "标准答案",
      "solution": ["详细解答1", "详细解答2", "详细解答3"],
      "difficulty": 0.6,
      "question_type": "choice/fill/answer",
      "skills": ["技能点1", "技能点2"],
      "knowledge_points": ["{knowledge_point}"]
    }
  ]
}';
    }

    public function getDefaultEnrichPromptTemplate(): string
    {
        return '你是一名“数学题目完善助手”。给定原题干与可选图片外链，请补全题目关键信息并做轻量修订。

要求：
- 只输出 JSON
- 必须包含字段：stem, options, answer, solution, question_type, difficulty, knowledge_points, solution_steps
- 可选字段：abilities（能力/技能点数组）
- stem 只做轻微修订（排版/符号/错别字），不得改题意
- 若提供图片外链（image_urls），可结合图片理解题意，但不要生成 SVG
- question_type 仅允许：choice / fill / answer
- answer 类题目必须提供 solution_steps（分步评分），每步包含 score 与 kp_codes
- knowledge_points 为题目级知识点列表

材料内容（含题干与图片）：
{content}

输出 JSON 示例：
{
  "stem": "...",
  "options": {"A": "...", "B": "..."},
  "answer": "...",
  "solution": "...",
  "question_type": "answer",
  "difficulty": 0.6,
  "knowledge_points": ["A01"],
  "solution_steps": [
    {"step_index": 1, "title": "...", "content": "...", "score": 4, "kp_codes": ["A01"]}
  ],
  "abilities": ["计算能力", "分析能力"]
}';
    }

    public function getDefaultSolutionPromptTemplate(): string
    {
        return '你是一名“中学数学解题专家”。给定题干、正确答案与可选图片外链，请生成与答案一致的详细解题过程。

要求：
- 只输出 JSON
- 必须包含字段：solution, steps
- solution 为简洁的整体思路（不写空话）
- steps 为数组，每步包含：step_index, title, content, score, kp_codes
- steps 必须给出可操作的计算/推理过程，避免“思想/方法类空话”
- 若题型为选择/填空，也要给出关键推理步骤，但 steps 不能省略核心计算
- 严格保证最终结论与 provided_answer 一致
- 若提供图片外链（image_urls），可结合图片理解题意，但不要生成 SVG

题干：
{stem}

正确答案：
{provided_answer}

图片外链（如有）：
{image_urls}

输出 JSON 示例：
{
  "solution": "整体解题思路概述",
  "steps": [
    {"step_index": 1, "title": "列式", "content": "...", "score": 4, "kp_codes": ["A01"]},
    {"step_index": 2, "title": "求解", "content": "...", "score": 6, "kp_codes": ["A01"]}
  ]
}';
    }

    /**
     * 检查服务健康状态
     */
    public function checkHealth(): bool
    {
        return true;
    }

    private function parseJsonField($value): array
    {
        if (is_array($value)) {
            return $value;
        }

        if (is_string($value) && $value !== '') {
            try {
                $decoded = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
                return is_array($decoded) ? $decoded : [];
            } catch (\Throwable) {
                return [];
            }
        }

        return [];
    }

    private function ensureDefaultQuestionPrompt(): void
    {
        $exists = PromptTemplate::query()
            ->where('template_name', self::DEFAULT_QUESTION_PROMPT_NAME)
            ->exists();
        if ($exists) {
            return;
        }

        $this->savePrompt([
            'template_name' => self::DEFAULT_QUESTION_PROMPT_NAME,
            'template_type' => self::DEFAULT_QUESTION_PROMPT_TYPE,
            'template_content' => $this->getDefaultPromptTemplate(),
            'variables' => json_encode([
            'knowledge_point',
            'grade_level',
            'basic_ratio',
            'intermediate_ratio',
            'advanced_ratio',
            'choice',
            'fill',
            'solution',
            'skill_coverage',
            'question_index',
            'question_position_hint',
            'count',
        ], JSON_UNESCAPED_UNICODE),
            'description' => '默认知识点题目生成模板（题型+难度分布）',
            'tags' => json_encode(['default', 'knowledge_point'], JSON_UNESCAPED_UNICODE),
            'is_active' => 'yes',
        ]);
    }

    private function ensureDefaultEnrichPrompt(): void
    {
        $exists = PromptTemplate::query()
            ->where('template_name', self::DEFAULT_ENRICH_PROMPT_NAME)
            ->exists();
        if ($exists) {
            return;
        }

        $this->savePrompt([
            'template_name' => self::DEFAULT_ENRICH_PROMPT_NAME,
            'template_type' => self::DEFAULT_ENRICH_PROMPT_TYPE,
            'template_content' => $this->getDefaultEnrichPromptTemplate(),
            'variables' => json_encode(['content'], JSON_UNESCAPED_UNICODE),
            'description' => '基于题干+图片的题目信息补全模板',
            'tags' => json_encode(['default', 'enrich'], JSON_UNESCAPED_UNICODE),
            'is_active' => 'yes',
        ]);
    }

    private function ensureDefaultSolutionPrompt(): void
    {
        $exists = PromptTemplate::query()
            ->where('template_name', self::DEFAULT_SOLUTION_PROMPT_NAME)
            ->exists();
        if ($exists) {
            return;
        }

        $this->savePrompt([
            'template_name' => self::DEFAULT_SOLUTION_PROMPT_NAME,
            'template_type' => self::DEFAULT_SOLUTION_PROMPT_TYPE,
            'template_content' => $this->getDefaultSolutionPromptTemplate(),
            'variables' => json_encode(['stem', 'provided_answer', 'image_urls'], JSON_UNESCAPED_UNICODE),
            'description' => '基于答案重写解题思路的系统模板',
            'tags' => json_encode(['default', 'solution'], JSON_UNESCAPED_UNICODE),
            'is_active' => 'yes',
        ]);
    }

    private function mapPrompt(PromptTemplate $prompt): array
    {
        $variables = $prompt->variables ?? [];
        $tags = $prompt->tags ?? [];

        return [
            'template_name' => $prompt->template_name,
            'template_type' => $prompt->template_type,
            'template_content' => $prompt->template_content,
            'variables' => json_encode($variables, JSON_UNESCAPED_UNICODE),
            'description' => $prompt->description,
            'tags' => json_encode($tags, JSON_UNESCAPED_UNICODE),
            'is_active' => $prompt->is_active ? 'yes' : 'no',
            'updated_at' => $prompt->updated_at,
        ];
    }
}
