<?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
     *
     * 请求格式：
     * {
     *     "paperId": "paper_661325736792",
     *     "questions": [
     *         {
     *             "question_bank_id": 876,
     *             "student_answer": "C",
     *             "is_correct": [0],           // 0=错, 1=对；简答题分步骤 [1,0,1]
     *             "teacher_comment": null
     *         }
     *     ]
     * }
     */
    public function analyze(Request $request): JsonResponse
    {
        try {
            // 1. 验证请求数据
            $validator = Validator::make($request->all(), [
                'paperId' => 'required|string|max:255',
                'questions' => 'required|array|min:1',
                'questions.*.question_bank_id' => 'required|integer',
                '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('paperId');
            $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. 获取题目详情并转换数据格式
            $transformedQuestions = $this->transformQuestionsData($questionsData, $paperId);

            // 4. 调用学情分析服务（可能失败，不影响错题本写入）
            $analysisResult = [];
            $analysisError = null;
            try {
                $examData = [
                    'exam_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 = [];
        $questionBankIds = array_column($questionsData, 'question_bank_id');

        // 批量获取题目详情
        $questionBankData = $this->fetchQuestionBankData($questionBankIds);

        // 获取试卷中题目的分数信息
        $paperQuestions = PaperQuestion::where('paper_id', $paperId)
            ->whereIn('question_bank_id', $questionBankIds)
            ->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 = $questionBankData[$questionBankId] ?? null;
            $paperQuestion = $paperQuestions->get($questionBankId);

            // 确定题目分数
            $maxScore = $paperQuestion->score ?? ($qbData['score'] ?? 5.0);
            $kpCode = $qbData['kp_code'] ?? ($paperQuestion->knowledge_point ?? 'K-GENERAL');
            $kpName = $qbData['kp_name'] ?? $kpCode;
            $questionType = $qbData['question_type'] ?? ($paperQuestion->question_type ?? 'unknown');

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

            // 转换 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
            ];
        }

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

    /**
     * 批量获取题库题目详情
     */
    private function fetchQuestionBankData(array $questionBankIds): array
    {
        try {
            $response = $this->questionBankService->getQuestionsByIds($questionBankIds);
            $questions = $response['data'] ?? $response;

            // 转换为以 id 为 key 的数组
            $result = [];
            foreach ($questions as $question) {
                $id = $question['id'] ?? $question['question_id'] ?? null;
                if ($id) {
                    $result[$id] = $question;
                }
            }
            return $result;
        } catch (\Exception $e) {
            Log::warning('获取题库详情失败，使用空数据', [
                'error' => $e->getMessage(),
                'question_bank_ids' => $questionBankIds
            ]);
            return [];
        }
    }

    /**
     * 将错题写入错题本
     */
    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] ?? [];

            try {
                $payload = [
                    'student_id' => $studentId,
                    'question_id' => $questionBankId,
                    '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'] ?? 'K-GENERAL'],
                    'source' => "paper:{$paperId}",
                    'happened_at' => now()->toISOString(),
                ];

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

                // 如果不是重复记录，则计数
                if (!($result['duplicate'] ?? false)) {
                    $mistakesAdded++;
                }

                Log::debug('错题写入成功', [
                    'student_id' => $studentId,
                    'question_bank_id' => $questionBankId,
                    'duplicate' => $result['duplicate'] ?? false
                ]);

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

        return $mistakesAdded;
    }

    /**
     * 更新试卷状态和题目作答信息
     */
    private function updatePaperStatus(string $paperId, array $questionsData): void
    {
        try {
            // 更新试卷状态为已完成
            Paper::where('paper_id', $paperId)->update([
                'status' => 'completed',
                'completed_at' => now(),
            ]);

            // 更新每道题目的作答信息
            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(),
                    ]);
            }

            Log::info('试卷状态更新完成', ['paper_id' => $paperId]);

        } 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);
        }
    }
}
