<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Paper;
use App\Models\PaperQuestion;
use App\Services\ExamAnswerAnalysisService;
use App\Services\MistakeBookService;
use App\Services\QuestionBankService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

/**
 * 试卷提交分析控制器
 *
 * 接收前端提交的试卷答题数据，进行学情分析并写入错题本
 */
class PaperSubmitAnalysisController extends Controller
{
    public function __construct(
        private readonly ExamAnswerAnalysisService $analysisService,
        private readonly MistakeBookService $mistakeBookService,
        private readonly QuestionBankService $questionBankService
    ) {}

    /**
     * 提交试卷答题数据进行分析
     *
     * POST /api/paper-submit-analysis
     *
     * 请求格式：
     * {
     *     "paper_id": "paper_661325736792",
     *     "questions": [
     *         {
     *             "question_id": 876,          // 前端使用 question_id
     *             "student_answer": "C",
     *             "is_correct": [0],           // 0=错, 1=对；简答题分步骤 [1,0,1]
     *             "teacher_comment": null
     *         }
     *     ]
     * }
     */
    public function analyze(Request $request): JsonResponse
    {
        try {
            // 1. 验证请求数据（前端使用 question_id）
            $validator = Validator::make($request->all(), [
                'paper_id' => 'required|string|max:255',
                'questions' => 'required|array|min:1',
                'questions.*.question_id' => 'required|integer',  // 前端使用 question_id
                'questions.*.student_answer' => 'nullable|string',
                'questions.*.is_correct' => 'required|array|min:1',
                'questions.*.is_correct.*' => 'integer|in:0,1',
                'questions.*.teacher_comment' => 'nullable|string',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'error' => '参数验证失败',
                    'details' => $validator->errors()
                ], 422);
            }

            $paperId = $request->input('paper_id');
            $questionsData = $request->input('questions');

            Log::info('开始处理试卷提交分析', [
                'paper_id' => $paperId,
                'questions_count' => count($questionsData)
            ]);

            // 2. 通过 paperId 查询试卷获取 student_id
            $paper = Paper::where('paper_id', $paperId)->first();
            if (!$paper) {
                return response()->json([
                    'success' => false,
                    'error' => '试卷不存在',
                    'paper_id' => $paperId
                ], 404);
            }

            $studentId = $paper->student_id;
            if (!$studentId) {
                return response()->json([
                    'success' => false,
                    'error' => '试卷未关联学生',
                    'paper_id' => $paperId
                ], 400);
            }

            // 3. 转换前端数据：将 question_id 转换为 question_bank_id
            $questionsData = $this->convertQuestionIds($questionsData);

            // 4. 获取题目详情并转换数据格式
            $transformedQuestions = $this->transformQuestionsData($questionsData, $paperId);

            // 4. 调用学情分析服务（可能失败，不影响错题本写入）
            $analysisResult = [];
            $analysisError = null;
            try {
                $examData = [
                    'paper_id' => $paperId,
                    'student_id' => $studentId,
                    'questions' => $transformedQuestions['questions'],
                ];

                $analysisResult = $this->analysisService->analyzeExamAnswers($examData);
            } catch (\Exception $e) {
                $analysisError = $e->getMessage();
                Log::warning('学情分析失败，继续处理错题本', [
                    'paper_id' => $paperId,
                    'error' => $analysisError
                ]);
            }

            // 5. 将错题写入错题本
            $mistakesAdded = $this->addMistakesToBook(
                $studentId,
                $paperId,
                $questionsData,
                $transformedQuestions['question_details']
            );

            // 6. 更新试卷状态为已完成
            $this->updatePaperStatus($paperId, $questionsData);

            Log::info('试卷提交分析完成', [
                'paper_id' => $paperId,
                'student_id' => $studentId,
                'questions_analyzed' => count($transformedQuestions['questions']),
                'mistakes_added' => $mistakesAdded
            ]);

            return response()->json([
                'success' => true,
                'data' => [
                    'paper_id' => $paperId,
                    'student_id' => $studentId,
                    'analysis_summary' => $analysisResult['overall_summary'] ?? null,
                    'knowledge_point_analysis' => $analysisResult['knowledge_point_analysis'] ?? [],
                    'smart_quiz_recommendation' => $analysisResult['smart_quiz_recommendation'] ?? null,
                    'mastery_vector' => $analysisResult['mastery_vector'] ?? [],
                    'mistakes_added' => $mistakesAdded,
                    'total_questions' => count($questionsData),
                    'correct_count' => $this->countCorrectQuestions($questionsData),
                    'incorrect_count' => $mistakesAdded,
                    'analysis_error' => $analysisError,
                ],
                'message' => "分析完成，新增 {$mistakesAdded} 条错题记录" . ($analysisError ? "（学情分析暂不可用）" : "")
            ]);

        } catch (\Exception $e) {
            Log::error('试卷提交分析失败', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'request_data' => $request->all()
            ]);

            return response()->json([
                'success' => false,
                'error' => '分析失败：' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 转换前端数据格式为分析服务所需格式
     * 【增强】处理未提交的题目，标记为"回答正确"
     */
    private function transformQuestionsData(array $questionsData, string $paperId): array
    {
        $transformedQuestions = [];
        $questionDetails = [];

        // 获取试卷中的所有题目
        $allPaperQuestions = PaperQuestion::where('paper_id', $paperId)->get();
        $allQuestionBankIds = $allPaperQuestions->pluck('question_bank_id')->toArray();

        // 区分已提交和未提交的题目
        $submittedIds = array_column($questionsData, 'question_bank_id');  // 转换后使用 question_bank_id
        $notSubmittedIds = array_diff($allQuestionBankIds, $submittedIds);

        Log::info('题目提交情况分析', [
            'paper_id' => $paperId,
            'total_questions' => count($allQuestionBankIds),
            'submitted_count' => count($submittedIds),
            'not_submitted_count' => count($notSubmittedIds),
            'submitted_ids' => $submittedIds,
            'not_submitted_ids' => $notSubmittedIds,
        ]);

        // 批量获取所有题目的详情（包括未提交的）
        // 【优化】使用新的通用方法直接从题库关联知识点
        $allQuestionBankData = [];
        foreach ($allQuestionBankIds as $questionBankId) {
            $questionData = $this->questionBankService->getQuestionKnowledgePoint($questionBankId);
            $allQuestionBankData[$questionBankId] = $questionData;

            // 调试日志
            Log::info('获取题目知识点', [
                'question_bank_id' => $questionBankId,
                'kp_code' => $questionData['kp_code'] ?? null,
                'kp_name' => $questionData['kp_name'] ?? null,
            ]);
        }

        // 获取所有题目的分数信息
        $allPaperQuestionsCollection = PaperQuestion::where('paper_id', $paperId)
            ->get()
            ->keyBy('question_bank_id');

        // 处理已提交的题目
        foreach ($questionsData as $index => $questionData) {
            $questionBankId = $questionData['question_bank_id'];
            $isCorrectArray = $questionData['is_correct'];
            $studentAnswer = $questionData['student_answer'] ?? null;
            $teacherComment = $questionData['teacher_comment'] ?? null;

            // 获取题目详情
            $qbData = $allQuestionBankData[$questionBankId] ?? null;
            $paperQuestion = $allPaperQuestionsCollection->get($questionBankId);

            // 确定题目分数
            $maxScore = $paperQuestion->score ?? 5.0;
            $kpCode = $qbData['kp_code'] ?? null;
            if (!$kpCode) {
                throw new \Exception("题目 {$questionBankId} 缺少知识点代码");
            }
            $kpName = $qbData['kp_name'] ?? $kpCode;
            $questionType = $qbData['question_type'] ?? 'unknown';

            // 保存详情供后续使用
            $questionDetails[$questionBankId] = [
                'question_bank_id' => $questionBankId,
                'stem' => $qbData['question_content'] ?? ($paperQuestion->question_text ?? ''),
                'answer' => $qbData['question_answer'] ?? ($paperQuestion->correct_answer ?? ''),
                'solution' => $paperQuestion->solution ?? '',
                'kp_code' => $kpCode,
                'kp_name' => $kpName,
                'question_type' => $questionType,
                'max_score' => $maxScore,
                'skills' => [],
                'is_submitted' => true,
            ];

            // 转换 is_correct 数组为 steps 格式
            $steps = [];
            $totalSteps = count($isCorrectArray);
            $scorePerStep = $maxScore / $totalSteps;
            $scoreObtained = 0;

            foreach ($isCorrectArray as $stepIndex => $isCorrect) {
                $stepCorrect = (bool) $isCorrect;
                if ($stepCorrect) {
                    $scoreObtained += $scorePerStep;
                }

                $steps[] = [
                    'step_index' => $stepIndex + 1,
                    'is_correct' => $stepCorrect,
                    'kp_id' => $kpCode,
                    'score' => $scorePerStep,
                    'weight' => 1.0,
                ];
            }

            $transformedQuestions[] = [
                'question_id' => (string) $questionBankId,
                'score' => $maxScore,
                'score_obtained' => round($scoreObtained, 2),
                'steps' => $totalSteps > 1 ? $steps : [], // 单步骤不传steps
                'kp_code' => $kpCode, // 【修复】添加知识点代码，供ExamAnswerAnalysisService使用
                'kp_name' => $kpName, // 【修复】添加知识点名称
            ];
        }

        // 【新增】处理未提交的题目：标记为"回答正确"
        foreach ($notSubmittedIds as $questionBankId) {
            // 获取题目详情
            $qbData = $allQuestionBankData[$questionBankId] ?? null;
            $paperQuestion = $allPaperQuestionsCollection->get($questionBankId);

            // 确定题目分数
            $maxScore = $paperQuestion->score ?? 5.0;
            $kpCode = $qbData['kp_code'] ?? null;
            if (!$kpCode) {
                throw new \Exception("题目 {$questionBankId} 缺少知识点代码");
            }
            $kpName = $qbData['kp_name'] ?? $kpCode;
            $questionType = $qbData['question_type'] ?? 'unknown';

            // 保存详情供后续使用
            $questionDetails[$questionBankId] = [
                'question_bank_id' => $questionBankId,
                'stem' => $qbData['question_content'] ?? ($paperQuestion->question_text ?? ''),
                'answer' => $qbData['question_answer'] ?? ($paperQuestion->correct_answer ?? ''),
                'solution' => $paperQuestion->solution ?? '',
                'kp_code' => $kpCode,
                'kp_name' => $kpName,
                'question_type' => $questionType,
                'max_score' => $maxScore,
                'skills' => [],
                'is_submitted' => false, // 未提交标记
            ];

            // 未提交的题目：标记为完全正确（说明学生已经掌握，不需要作答）
            $transformedQuestions[] = [
                'question_id' => (string) $questionBankId,
                'score' => $maxScore,
                'score_obtained' => $maxScore, // 获得满分
                'steps' => [], // 不需要步骤分析
                'is_correct' => true, // 标记为正确
                'is_submitted' => false, // 标记为未提交
                'kp_code' => $kpCode, // 【修复】添加知识点代码，供ExamAnswerAnalysisService使用
                'kp_name' => $kpName, // 【修复】添加知识点名称
            ];

            Log::info('未提交题目处理', [
                'question_bank_id' => $questionBankId,
                'kp_code' => $kpCode,
                'max_score' => $maxScore,
                'reason' => '未作答视为已掌握',
            ]);
        }

        Log::info('题目数据转换完成', [
            'paper_id' => $paperId,
            'total_transformed' => count($transformedQuestions),
            'submitted_count' => count($submittedIds),
            'not_submitted_count' => count($notSubmittedIds),
        ]);

        return [
            'questions' => $transformedQuestions,
            'question_details' => $questionDetails,
        ];
    }

    /**
     * 批量获取题库题目详情
     */
    /**
     * 将错题写入错题本
     * 【正确逻辑】只处理已提交的题目，未提交的题目默认正确，不写入错题本
     */
    private function addMistakesToBook(
        string $studentId,
        string $paperId,
        array $questionsData,
        array $questionDetails
    ): int {
        $mistakesAdded = 0;

        // 只有已提交的题目才处理错题本
        foreach ($questionsData as $questionData) {
            $isCorrectArray = $questionData['is_correct'];

            // 判断是否有错误（数组中存在0）
            $hasError = in_array(0, $isCorrectArray, true);
            if (!$hasError) {
                continue; // 全对，跳过
            }

            $questionBankId = $questionData['question_bank_id'];
            $detail = $questionDetails[$questionBankId] ?? [];

            $mistakesAdded += $this->createMistakeRecord($studentId, $paperId, $questionData, $detail);
        }

        // 【说明】未提交的题目不写入错题本，因为默认正确（已掌握）

        Log::info('错题本写入完成', [
            'paper_id' => $paperId,
            'submitted_questions' => count($questionsData),
            'mistakes_added' => $mistakesAdded,
            'note' => '未提交题目默认正确，未写入错题本',
        ]);

        return $mistakesAdded;
    }

    /**
     * 创建单个错题记录
     */
    private function createMistakeRecord(
        string $studentId,
        string $paperId,
        array $questionData,
        array $detail
    ): int {
        try {
            $payload = [
                'student_id' => $studentId,
                'question_id' => $questionData['question_bank_id'],
                'paper_id' => $paperId,
                'my_answer' => $questionData['student_answer'] ?? '',
                'correct_answer' => $detail['answer'] ?? '',
                'question_text' => $detail['stem'] ?? '',
                'knowledge_point' => $detail['kp_name'] ?? '',
                'explanation' => $detail['solution'] ?? '',
                'kp_ids' => [$detail['kp_code']],
                'source' => "paper:{$paperId}",
                'happened_at' => now()->toISOString(),
            ];

            $result = $this->mistakeBookService->createMistake($payload);

            // 如果不是重复记录，则计数
            if (!($result['duplicate'] ?? false)) {
                Log::debug('错题写入成功', [
                    'student_id' => $studentId,
                    'question_bank_id' => $questionData['question_bank_id'],
                    'duplicate' => $result['duplicate'] ?? false
                ]);
                return 1;
            }

            return 0;

        } catch (\Exception $e) {
            Log::error('写入错题本失败', [
                'student_id' => $studentId,
                'question_bank_id' => $questionData['question_bank_id'],
                'error' => $e->getMessage()
            ]);
            return 0;
        }
    }

    /**
     * 更新试卷状态和题目作答信息
     * 【正确逻辑】未提交题目视为正确（已掌握），已提交错误题目标记为错误
     */
    private function updatePaperStatus(string $paperId, array $questionsData): void
    {
        try {
            // 更新试卷状态为已完成
            Paper::where('paper_id', $paperId)->update([
                'status' => 'completed',
                'completed_at' => now(),
            ]);

            // 获取试卷中的所有题目（包括未提交的）
            $allPaperQuestions = PaperQuestion::where('paper_id', $paperId)->get();
            $allQuestionIds = $allPaperQuestions->pluck('question_bank_id')->toArray();

            // 区分已提交和未提交的题目
            $submittedIds = array_column($questionsData, 'question_bank_id');
            $notSubmittedIds = array_diff($allQuestionIds, $submittedIds);

            // 更新已提交题目的作答信息
            foreach ($questionsData as $questionData) {
                $questionBankId = $questionData['question_bank_id'];
                $isCorrectArray = $questionData['is_correct'];

                // 计算得分比例
                $correctCount = array_sum($isCorrectArray);
                $totalSteps = count($isCorrectArray);
                $scoreRatio = $totalSteps > 0 ? $correctCount / $totalSteps : 0;

                // 判断是否全对
                $isFullyCorrect = !in_array(0, $isCorrectArray, true);

                PaperQuestion::where('paper_id', $paperId)
                    ->where('question_bank_id', $questionBankId)
                    ->update([
                        'student_answer' => $questionData['student_answer'] ?? null,
                        'is_correct' => $isFullyCorrect,
                        'score_ratio' => $scoreRatio,
                        'score_obtained' => DB::raw("score * {$scoreRatio}"),
                        'teacher_comment' => $questionData['teacher_comment'] ?? null,
                        'graded_at' => now(),
                    ]);
            }

            // 【修正】更新未提交题目的状态：视为正确（已掌握）
            foreach ($notSubmittedIds as $questionBankId) {
                // 未提交题目：视为正确（已掌握），获得满分
                PaperQuestion::where('paper_id', $paperId)
                    ->where('question_bank_id', $questionBankId)
                    ->update([
                        'student_answer' => null,
                        'is_correct' => true, // 视为正确
                        'score_ratio' => 1.0, // 获得满分
                        'score_obtained' => DB::raw('score'), // 获得满分
                        'teacher_comment' => '未作答（已掌握）',
                        'graded_at' => now(),
                    ]);

                Log::debug('未提交题目状态更新', [
                    'paper_id' => $paperId,
                    'question_bank_id' => $questionBankId,
                    'is_correct' => true,
                    'score_ratio' => 1.0,
                    'note' => '未提交题目视为正确（已掌握）',
                ]);
            }

            Log::info('试卷状态更新完成', [
                'paper_id' => $paperId,
                'total_questions' => count($allQuestionIds),
                'submitted_count' => count($submittedIds),
                'not_submitted_count' => count($notSubmittedIds),
                'note' => '未提交题目视为正确（已掌握）',
            ]);

        } catch (\Exception $e) {
            Log::error('更新试卷状态失败', [
                'paper_id' => $paperId,
                'error' => $e->getMessage()
            ]);
        }
    }

    /**
     * 统计正确题目数量
     */
    private function countCorrectQuestions(array $questionsData): int
    {
        $correctCount = 0;
        foreach ($questionsData as $questionData) {
            $isCorrectArray = $questionData['is_correct'];
            // 全对才算正确
            if (!in_array(0, $isCorrectArray, true)) {
                $correctCount++;
            }
        }
        return $correctCount;
    }

    /**
     * 获取试卷分析结果
     *
     * GET /api/paper-submit-analysis/{paperId}
     */
    public function getResult(string $paperId): JsonResponse
    {
        try {
            $paper = Paper::where('paper_id', $paperId)->first();
            if (!$paper) {
                return response()->json([
                    'success' => false,
                    'error' => '试卷不存在'
                ], 404);
            }

            // 从数据库获取分析结果
            $result = DB::connection('mysql')
                ->table('exam_analysis_results')
                ->where('paper_id', $paperId)
                ->where('student_id', $paper->student_id)
                ->orderBy('created_at', 'desc')
                ->first();

            if (!$result) {
                return response()->json([
                    'success' => false,
                    'error' => '未找到分析结果，请先提交试卷进行分析'
                ], 404);
            }

            return response()->json([
                'success' => true,
                'data' => json_decode($result->analysis_data, true)
            ]);

        } catch (\Exception $e) {
            Log::error('获取试卷分析结果失败', [
                'paper_id' => $paperId,
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'error' => '获取分析结果失败：' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 转换前端 question_id 为后端 question_bank_id
     * 前端使用 question_id，后端转换为 question_bank_id 进行处理
     */
    private function convertQuestionIds(array $questionsData): array
    {
        $converted = [];

        foreach ($questionsData as $question) {
            // 将 question_id 转换为 question_bank_id
            if (isset($question['question_id'])) {
                $question['question_bank_id'] = $question['question_id'];
                unset($question['question_id']);
            }

            $converted[] = $question;
        }

        Log::info('转换 question_id 为 question_bank_id', [
            'original_count' => count($questionsData),
            'converted_count' => count($converted),
            'sample_conversion' => !empty($converted) ? [
                'from' => $questionsData[0]['question_id'] ?? null,
                'to' => $converted[0]['question_bank_id'] ?? null
            ] : null
        ]);

        return $converted;
    }
}
