<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\StudentKnowledgeMastery;
use App\Models\KnowledgePoint;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class StudentKnowledgeController extends Controller
{
    /**
     * 获取学生知识点掌握详情
     *
     * @param string $studentId
     * @param Request $request
     * @return JsonResponse
     */
    public function getKnowledgePointsDetail(string $studentId, Request $request): JsonResponse
    {
        try {
            // 验证学生是否存在
            $student = \App\Models\Student::where('student_id', $studentId)->first();
            if (!$student) {
                return response()->json([
                    'success' => false,
                    'message' => '学生不存在',
                ], 404);
            }

            // 获取查询参数
            $level = $request->query('level'); // 筛选特定层级的知识点
            $sort = $request->query('sort', 'mastery_asc'); // 排序方式

            // 构建查询（解决字符集不匹配问题）
            // 【修复】显式选择mastery_level和mastery_change字段，避免访问器转换
            $query = StudentKnowledgeMastery::forStudent($studentId)
                ->with('knowledgePoint') // 预加载知识点信息
                ->select([
                    'student_knowledge_mastery.*',
                    'knowledge_points.name as kp_name',
                    'knowledge_points.parent_kp_code',
                    // 显式选择原始字段，避免访问器
                    DB::raw('CAST(student_knowledge_mastery.mastery_level AS DECIMAL(10,4)) as mastery_level_raw'),
                    DB::raw('CAST(student_knowledge_mastery.mastery_change AS DECIMAL(10,4)) as mastery_change_raw'),
                ])
                ->join('knowledge_points', 'student_knowledge_mastery.kp_code', '=', DB::raw('CAST(knowledge_points.kp_code AS CHAR)'));

            // 按层级筛选
            if ($level) {
                if ($level === 'top') {
                    // 只查询顶级知识点（没有父级）
                    $query->whereNull('knowledge_points.parent_kp_code');
                } elseif ($level === 'leaf') {
                    // 只查询叶子知识点（没有子级）
                    $query->whereNotIn('knowledge_points.kp_code', function ($q) {
                        $q->select('parent_kp_code')
                          ->from('knowledge_points')
                          ->whereNotNull('parent_kp_code');
                    });
                }
            }

            // 排序
            switch ($sort) {
                case 'mastery_desc':
                    $query->orderBy('mastery_level', 'desc');
                    break;
                case 'name_asc':
                    $query->orderBy('kp_name', 'asc');
                    break;
                case 'name_desc':
                    $query->orderBy('kp_name', 'desc');
                    break;
                case 'attempts_desc':
                    $query->orderBy('total_attempts', 'desc');
                    break;
                case 'mastery_asc':
                default:
                    $query->orderBy('mastery_level', 'asc');
                    break;
            }

            $masteryRecords = $query->get();

            // 构建返回数据
            $knowledgePoints = [];
            foreach ($masteryRecords as $record) {
                // 计算正确率
                $correctRate = $record->total_attempts > 0
                    ? round(($record->correct_attempts / $record->total_attempts) * 100, 2) / 100
                    : 0.0;

                // 计算稳定度（基于近期的变化趋势）
                $stability = $this->calculateStability($record);

                // 获取层级信息
                $level = $record->knowledgePoint->parent_kp_code ? '子级' : '顶级';

                // 获取父子关系
                $parentName = null;
                if ($record->knowledgePoint->parent_kp_code) {
                    $parentKp = KnowledgePoint::where('kp_code', $record->knowledgePoint->parent_kp_code)->first();
                    $parentName = $parentKp?->name ?? $record->knowledgePoint->parent_kp_code;
                }

                // 【修复】使用CAST后的原始字段，避免访问器转换
                $rawMasteryLevel = $record->mastery_level_raw;
                $rawMasteryChange = $record->mastery_change_raw;

                $masteryLevel = is_numeric($rawMasteryLevel) ? (float)$rawMasteryLevel : 0.0;
                $masteryChange = is_numeric($rawMasteryChange) ? (float)$rawMasteryChange : 0.0;

                $knowledgePoints[] = [
                    'kp_code' => $record->kp_code,
                    'knowledge_point' => $record->kp_name ?: $record->kp_code, // 使用名称，如果没有名称则使用代码
                    'mastery' => round($masteryLevel, 4),
                    'stability' => $stability,
                    'level' => $level,
                    'parent_kp_code' => $record->knowledgePoint->parent_kp_code,
                    'parent_kp_name' => $parentName,
                    'last_updated' => $record->last_mastery_update?->toISOString(),
                    'practice_count' => (int)$record->total_attempts,
                    'correct_rate' => $correctRate,
                    'mastery_change' => $masteryChange,
                    'mastery_trend' => $record->mastery_trend,
                    'trend_label' => $record->trend_label ?? '稳定',
                ];
            }

            // 【新功能】获取父节点掌握度
            $parentMasteryLevels = $this->getParentMasteryLevels($studentId, $knowledgePoints);

            Log::info('获取学生知识点掌握详情', [
                'student_id' => $studentId,
                'count' => count($knowledgePoints),
                'parent_count' => count($parentMasteryLevels),
                'level' => $level,
                'sort' => $sort,
            ]);

            return response()->json([
                'success' => true,
                'data' => [
                    'student_id' => $studentId,
                    'student_name' => $student->name,
                    'knowledge_points' => array_values($knowledgePoints), // 重新索引
                    'parent_mastery_levels' => $parentMasteryLevels, // 新增：父节点掌握度
                    'total_count' => count($knowledgePoints),
                ],
            ]);

        } catch (\Exception $e) {
            Log::error('获取学生知识点掌握详情失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

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

    /**
     * 计算稳定度
     */
    private function calculateStability(StudentKnowledgeMastery $record): float
    {
        // 如果数据不足，返回默认值
        if ($record->total_attempts < 3) {
            return 0.5;
        }

        // 基于掌握度变化计算稳定度
        // 变化越小，稳定度越高
        $changeAbs = abs($record->mastery_change ?? 0);

        // 稳定度 = 1 - (变化幅度 * 10)，范围0-1
        $stability = max(0, min(1, 1 - ($changeAbs * 10)));

        return round($stability, 4);
    }

    /**
     * 获取学生知识点层级关系
     *
     * @param string $studentId
     * @return JsonResponse
     */
    public function getKnowledgeHierarchy(string $studentId): JsonResponse
    {
        try {
            // 获取学生的所有知识点
            $masteryRecords = StudentKnowledgeMastery::forStudent($studentId)
                ->with('knowledgePoint')
                ->get();

            // 构建父子关系
            $hierarchy = [];
            $processed = [];

            foreach ($masteryRecords as $record) {
                $kpCode = $record->kp_code;

                // 避免重复处理
                if (isset($processed[$kpCode])) {
                    continue;
                }

                $kp = $record->knowledgePoint;
                if (!$kp) {
                    continue;
                }

                $processed[$kpCode] = true;

                // 如果是顶级知识点
                if (!$kp->parent_kp_code) {
                    $hierarchy[] = [
                        'kp_code' => $kpCode,
                        'kp_name' => $kp->name ?: $kpCode,
                        'mastery' => round($record->mastery_level, 4),
                        'level' => 'top',
                        'children' => $this->getChildKnowledgePoints($masteryRecords, $kpCode),
                    ];
                }
            }

            // 如果没有顶级知识点，尝试构建其他层级的结构
            if (empty($hierarchy)) {
                foreach ($masteryRecords as $record) {
                    $kpCode = $record->kp_code;

                    $kp = $record->knowledgePoint;
                    if (!$kp) {
                        continue;
                    }

                    $hierarchy[] = [
                        'kp_code' => $kpCode,
                        'kp_name' => $kp->name ?: $kpCode,
                        'mastery' => round($record->mastery_level, 4),
                        'level' => $kp->parent_kp_code ? 'child' : 'top',
                        'parent_kp_code' => $kp->parent_kp_code,
                    ];
                }
            }

            return response()->json([
                'success' => true,
                'data' => [
                    'student_id' => $studentId,
                    'hierarchy' => $hierarchy,
                    'total_count' => count($hierarchy),
                ],
            ]);

        } catch (\Exception $e) {
            Log::error('获取学生知识点层级关系失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage(),
            ]);

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

    /**
     * 获取子知识点
     */
    private function getChildKnowledgePoints($masteryRecords, string $parentKpCode): array
    {
        $children = [];

        foreach ($masteryRecords as $record) {
            $kp = $record->knowledgePoint;
            if ($kp && $kp->parent_kp_code === $parentKpCode) {
                $children[] = [
                    'kp_code' => $kp->kp_code,
                    'kp_name' => $kp->name ?: $kp->kp_code,
                    'mastery' => round($record->mastery_level, 4),
                    'level' => 'child',
                    'children' => $this->getChildKnowledgePoints($masteryRecords, $kp->kp_code),
                ];
            }
        }

        return $children;
    }

    /**
     * 【新功能】获取父节点掌握度
     */
    private function getParentMasteryLevels(string $studentId, array $knowledgePoints): array
    {
        try {
            $parentMasteryLevels = [];

            // 收集所有父节点代码
            $parentKpCodes = [];
            foreach ($knowledgePoints as $kp) {
                if (!empty($kp['parent_kp_code'])) {
                    $parentKpCodes[$kp['parent_kp_code']] = true;
                }
            }

            if (empty($parentKpCodes)) {
                return $parentMasteryLevels;
            }

            // 查询父节点的掌握度
            $parentRecords = StudentKnowledgeMastery::forStudent($studentId)
                ->whereIn('kp_code', array_keys($parentKpCodes))
                ->get();

            foreach ($parentRecords as $record) {
                // 使用CAST后的原始字段
                $rawMasteryLevel = $record->getAttributeValue('mastery_level');
                $rawMasteryChange = $record->getAttributeValue('mastery_change');

                $masteryLevel = is_numeric($rawMasteryLevel) ? (float)$rawMasteryLevel : 0.0;
                $masteryChange = is_numeric($rawMasteryChange) ? (float)$rawMasteryChange : 0.0;

                // 获取父节点的父节点
                $kp = $record->knowledgePoint;
                $grandParentKpCode = $kp?->parent_kp_code;

                $parentMasteryLevels[] = [
                    'kp_code' => $record->kp_code,
                    'knowledge_point' => $kp?->name ?: $record->kp_code,
                    'mastery' => round($masteryLevel, 4),
                    'mastery_change' => $masteryChange,
                    'mastery_trend' => $record->mastery_trend,
                    'trend_label' => $record->trend_label ?? '稳定',
                    'level' => '父级',
                    'parent_kp_code' => $grandParentKpCode,
                    'practice_count' => (int)$record->total_attempts,
                    'correct_rate' => $record->total_attempts > 0
                        ? round(($record->correct_attempts / $record->total_attempts), 4)
                        : 0.0,
                    'is_calculated' => ($record->mastery_trend === 'calculated'), // 标记为计算得出
                    'last_updated' => $record->last_mastery_update?->toISOString(),
                ];
            }

            return $parentMasteryLevels;

        } catch (\Exception $e) {
            Log::error('获取父节点掌握度失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage(),
            ]);
            return [];
        }
    }
}
