<?php

namespace App\Services;

use App\Models\MistakeRecord;
use App\Models\Student;
use App\Models\Teacher;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;

class MistakeBookService
{
    protected string $learningAnalyticsBase;
    protected int $timeout;

    // 缓存时间（秒）
    const CACHE_TTL_LIST = 60; // 5分钟
    const CACHE_TTL_SUMMARY = 600; // 10分钟
    const CACHE_TTL_PATTERNS = 1800; // 30分钟

    public function __construct(
        ?string $learningAnalyticsBase = null,
        ?int $timeout = null
    ) {
        // 已迁移到本地，不再使用LearningAnalytics
        $this->learningAnalyticsBase = '';
        $this->timeout = 20;
    }

    /**
     * 新增错题
     */
    public function createMistake(array $payload): array
    {
        $studentId = $payload['student_id'] ?? null;
        $questionId = $payload['question_id'] ?? null;
        $paperId = $payload['paper_id'] ?? null;
        $myAnswer = $payload['my_answer'] ?? null;
        $correctAnswer = $payload['correct_answer'] ?? null;
        $questionText = $payload['question_text'] ?? null;
        $knowledgePoint = $payload['knowledge_point'] ?? null;
        $explanation = $payload['explanation'] ?? null;
        $kpIds = $payload['kp_ids'] ?? null;
        $source = $payload['source'] ?? MistakeRecord::SOURCE_PRACTICE;
        $happenedAt = $payload['happened_at'] ?? now();

        if (!$studentId) {
            throw new \InvalidArgumentException('学生ID不能为空');
        }

        // 使用事务确保数据一致性
        return \DB::transaction(function () use (
            $studentId, $questionId, $paperId, $myAnswer, $correctAnswer,
            $questionText, $knowledgePoint, $explanation, $kpIds, $source, $happenedAt
        ) {
            // 检查是否已存在相同错题（避免重复）
            $query = MistakeRecord::where('student_id', $studentId)
                ->where('source', $source)
                ->where('created_at', '>=', now()->subDay());

            // 如果有 question_id，用它去重；否则用 question_text
            if ($questionId) {
                $query->where('question_id', $questionId);
            } elseif ($questionText) {
                $query->where('question_text', $questionText);
            }

            $existingMistake = $query->first();

            if ($existingMistake) {
                return [
                    'duplicate' => true,
                    'mistake_id' => $existingMistake->id,
                    'message' => '错题已存在',
                ];
            }

            // 创建错题记录
            $mistake = MistakeRecord::create([
                'student_id' => $studentId,
                'question_id' => $questionId,
                'paper_id' => $paperId,
                'student_answer' => $myAnswer,
                'correct_answer' => $correctAnswer,
                'question_text' => $questionText,
                'knowledge_point' => $knowledgePoint,
                'explanation' => $explanation,
                'kp_ids' => $kpIds,
                'source' => $source,
                'created_at' => $happenedAt,
                'review_status' => MistakeRecord::REVIEW_STATUS_PENDING,
                'review_count' => 0,
            ]);

            // 清除相关缓存
            $this->clearCache($studentId);

            return [
                'duplicate' => false,
                'mistake_id' => $mistake->id,
                'created_at' => $mistake->created_at,
            ];
        });
    }

    /**
     * 获取错题列表
     */
    public function listMistakes(array $params = []): array
    {
        $studentId = $params['student_id'] ?? null;
        $page = (int) ($params['page'] ?? 1);
        $perPage = (int) ($params['per_page'] ?? 20);

        if (!$studentId) {
            return [
                'data' => [],
                'meta' => ['total' => 0, 'page' => $page, 'per_page' => $perPage],
                'statistics' => [  // ✅ 无 student_id 时也返回空统计
                    'total' => 0,
                    'pending' => 0,
                    'reviewed' => 0,
                    'mastered' => 0,
                    'favorites' => 0,
                    'in_retry_list' => 0,
                    'this_week' => 0,
                    'mastery_rate' => 0.0,
                ],
            ];
        }

        // 构建缓存键
        $cacheKey = $this->buildCacheKey('list', $params);

        // 尝试从缓存获取
        if (Cache::has($cacheKey)) {
            return Cache::get($cacheKey);
        }

        try {
            $query = MistakeRecord::forStudent($studentId)
                ->with(['student']) // 预加载学生信息
                ->orderByDesc('created_at');

            // 应用筛选条件
            $this->applyFilters($query, $params);

            // 获取总数
            $total = $query->count();

            // 分页获取数据
            $mistakes = $query->skip(($page - 1) * $perPage)
                ->take($perPage)
                ->get();

            // 转换数据格式
            $data = $mistakes->map(function ($mistake) {
                return $this->transformMistakeRecord($mistake, false);
            })->toArray();

            // 获取统计信息
            $summary = $this->summarize($studentId);

            $result = [
                'data' => $data,
                'meta' => [
                    'total' => $total,
                    'page' => $page,
                    'per_page' => $perPage,
                    'last_page' => (int) ceil($total / $perPage),
                ],
                'statistics' => $summary,  // ✅ 添加统计信息
            ];

            // 缓存结果
            Cache::put($cacheKey, $result, self::CACHE_TTL_LIST);

            return $result;

        } catch (\Throwable $e) {
            Log::error('获取错题列表失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage(),
                'params' => $params,
            ]);

            return [
                'data' => [],
                'meta' => ['total' => 0, 'page' => $page, 'per_page' => $perPage],
                'statistics' => [  // ✅ 错误时也返回空统计
                    'total' => 0,
                    'pending' => 0,
                    'reviewed' => 0,
                    'mastered' => 0,
                    'favorites' => 0,
                    'in_retry_list' => 0,
                    'this_week' => 0,
                    'mastery_rate' => 0.0,
                ],
            ];
        }
    }

    /**
     * 获取错题详情
     */
    public function getMistakeDetail(string $mistakeId, ?string $studentId = null): array
    {
        try {
            $query = MistakeRecord::with(['student']);

            if ($studentId) {
                $query->forStudent($studentId);
            }

            $mistake = $query->find($mistakeId);

            if (!$mistake) {
                return [];
            }

            return $this->transformMistakeRecord($mistake, true);

        } catch (\Throwable $e) {
            Log::error('获取错题详情失败', [
                'mistake_id' => $mistakeId,
                'student_id' => $studentId,
                'error' => $e->getMessage(),
            ]);

            return [];
        }
    }

    /**
     * 获取错题统计概要
     */
    public function summarize(string $studentId): array
    {
        $cacheKey = "mistake_book:summary:{$studentId}";

        return Cache::remember($cacheKey, self::CACHE_TTL_SUMMARY, function () use ($studentId) {
            return MistakeRecord::getSummary($studentId);
        });
    }

    /**
     * 获取错误模式分析
     */
    public function getMistakePatterns(string $studentId): array
    {
        $cacheKey = "mistake_book:patterns:{$studentId}";

        return Cache::remember($cacheKey, self::CACHE_TTL_PATTERNS, function () use ($studentId) {
            return MistakeRecord::getMistakePatterns($studentId);
        });
    }

    /**
     * 收藏/取消收藏错题
     */
    public function toggleFavorite(string $mistakeId, bool $favorite = true): bool
    {
        try {
            $mistake = MistakeRecord::find($mistakeId);
            if (!$mistake) {
                return false;
            }

            $mistake->update(['is_favorite' => $favorite]);

            // 清除缓存
            $this->clearCache($mistake->student_id);

            return true;

        } catch (\Throwable $e) {
            Log::error('收藏错题失败', [
                'mistake_id' => $mistakeId,
                'favorite' => $favorite,
                'error' => $e->getMessage(),
            ]);

            return false;
        }
    }

    /**
     * 标记已复习
     */
    public function markReviewed(string $mistakeId): bool
    {
        try {
            $mistake = MistakeRecord::find($mistakeId);
            if (!$mistake) {
                return false;
            }

            $mistake->markAsReviewed();

            // 清除缓存
            $this->clearCache($mistake->student_id);

            return true;

        } catch (\Throwable $e) {
            Log::error('标记已复习失败', [
                'mistake_id' => $mistakeId,
                'error' => $e->getMessage(),
            ]);

            return false;
        }
    }

    /**
     * 修改复习状态
     */
    public function updateReviewStatus(string $mistakeId, string $action = 'increment', bool $forceReview = false): array
    {
        try {
            $mistake = MistakeRecord::find($mistakeId);
            if (!$mistake) {
                return [
                    'success' => false,
                    'error' => '错题记录不存在',
                ];
            }

            match ($action) {
                'increment' => $mistake->markAsReviewed(),
                'mastered' => $mistake->markAsMastered(),
                'reset' => $mistake->update([
                    'review_status' => MistakeRecord::REVIEW_STATUS_PENDING,
                    'review_count' => 0,
                    'mastery_level' => null,
                    'reviewed_at' => null,
                    'next_review_at' => null,
                ]),
                default => throw new \InvalidArgumentException('无效的操作类型'),
            };

            // ⚠️ 重要：重新加载模型数据以获取最新状态
            $mistake->refresh();

            return [
                'success' => true,
                'mistake_id' => $mistakeId,
                'review_status' => $mistake->review_status,
                'review_count' => $mistake->review_count,
                'reviewed_at' => $mistake->reviewed_at?->toISOString(),
                'next_review_at' => $mistake->next_review_at?->toISOString(),
                'mastery_level' => $mistake->mastery_level,
                'message' => '复习状态更新成功',
            ];

        } catch (\Throwable $e) {
            Log::error('更新复习状态失败', [
                'mistake_id' => $mistakeId,
                'action' => $action,
                'error' => $e->getMessage(),
            ]);

            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * 获取复习状态
     */
    public function getReviewStatus(string $mistakeId): array
    {
        try {
            $mistake = MistakeRecord::find($mistakeId);
            if (!$mistake) {
                return [
                    'success' => false,
                    'error' => '错题记录不存在',
                ];
            }

            return [
                'success' => true,
                'mistake_id' => $mistakeId,
                'review_status' => $mistake->review_status,
                'review_count' => $mistake->review_count,
                'reviewed_at' => $mistake->reviewed_at?->toISOString(),
                'next_review_at' => $mistake->next_review_at?->toISOString(),
                'mastery_level' => $mistake->mastery_level,
                'force_review' => $mistake->force_review,
            ];

        } catch (\Throwable $e) {
            Log::error('获取复习状态失败', [
                'mistake_id' => $mistakeId,
                'error' => $e->getMessage(),
            ]);

            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * 增加复习次数
     */
    public function incrementReviewCount(string $mistakeId, bool $forceReview = false): array
    {
        return $this->updateReviewStatus($mistakeId, 'increment', $forceReview);
    }

    /**
     * 重置为强制复习状态
     */
    public function resetReviewStatus(string $mistakeId): array
    {
        return $this->updateReviewStatus($mistakeId, 'reset');
    }

    /**
     * 添加到重练清单
     */
    public function addToRetryList(string $mistakeId): bool
    {
        try {
            $mistake = MistakeRecord::find($mistakeId);
            if (!$mistake) {
                return false;
            }

            $mistake->addToRetryList();

            // 清除缓存
            $this->clearCache($mistake->student_id);

            return true;

        } catch (\Throwable $e) {
            Log::error('加入重练清单失败', [
                'mistake_id' => $mistakeId,
                'error' => $e->getMessage(),
            ]);

            return false;
        }
    }

    /**
     * 批量操作错题
     */
    public function batchOperation(array $mistakeIds, string $operation, array $params = []): array
    {
        if (empty($mistakeIds)) {
            return [
                'success' => false,
                'error' => '请选择要操作的错题',
            ];
        }

        try {
            $mistakes = MistakeRecord::whereIn('id', $mistakeIds)->get();
            $successCount = 0;
            $errors = [];

            foreach ($mistakes as $mistake) {
                try {
                    match ($operation) {
                        'favorite' => $mistake->toggleFavorite(),
                        'reviewed' => $mistake->markAsReviewed(),
                        'mastered' => $mistake->markAsMastered(),
                        'retry_list' => $mistake->addToRetryList(),
                        'remove_retry_list' => $mistake->removeFromRetryList(),
                        'set_error_type' => $mistake->update(['error_type' => $params['error_type'] ?? null]),
                        'set_importance' => $mistake->update(['importance' => $params['importance'] ?? 5]),
                        default => throw new \InvalidArgumentException('不支持的操作'),
                    };

                    $successCount++;
                } catch (\Throwable $e) {
                    $errors[] = [
                        'mistake_id' => $mistake->id,
                        'error' => $e->getMessage(),
                    ];
                }
            }

            // 清除缓存
            if ($successCount > 0) {
                $studentIds = $mistakes->pluck('student_id')->unique();
                foreach ($studentIds as $studentId) {
                    $this->clearCache($studentId);
                }
            }

            return [
                'success' => true,
                'total' => count($mistakeIds),
                'success_count' => $successCount,
                'error_count' => count($errors),
                'errors' => $errors,
            ];

        } catch (\Throwable $e) {
            Log::error('批量操作失败', [
                'operation' => $operation,
                'mistake_ids' => $mistakeIds,
                'error' => $e->getMessage(),
            ]);

            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    /**
     * 基于错题推荐练习题（本地实现）
     */
    public function recommendPractice(string $studentId, array $kpIds = [], array $skillIds = []): array
    {
        try {
            // 获取学生未掌握的知识点
            $weakKnowledgePoints = MistakeRecord::forStudent($studentId)
                ->where('review_status', '!=', MistakeRecord::REVIEW_STATUS_MASTERED)
                ->pluck('knowledge_point')
                ->filter()
                ->unique()
                ->values()
                ->toArray();

            // 合并传入的知识点
            $allKpIds = array_unique(array_merge($kpIds, $weakKnowledgePoints));

            // TODO: 这里应该调用本地题库服务
            // 目前返回模拟数据
            $recommendations = [];
            foreach (array_slice($allKpIds, 0, 5) as $kpId) {
                $recommendations[] = [
                    'id' => "rec_{$kpId}_{$studentId}",
                    'kp_code' => $kpId,
                    'question_text' => "针对知识点 {$kpId} 的练习题",
                    'difficulty' => 0.5,
                    'source' => 'recommendation',
                ];
            }

            return ['data' => $recommendations];

        } catch (\Throwable $e) {
            Log::error('推荐练习题失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage(),
            ]);

            return ['data' => []];
        }
    }

    /**
     * 获取仪表板快照数据
     */
    public function getPanelSnapshot(string $studentId, int $limit = 5): array
    {
        try {
            $recentMistakes = MistakeRecord::forStudent($studentId)
                ->orderByDesc('created_at')
                ->limit($limit)
                ->get()
                ->map(fn($m) => $this->transformMistakeRecord($m))
                ->toArray();

            $patterns = $this->getMistakePatterns($studentId);
            $summary = $this->summarize($studentId);

            return [
                'recent' => $recentMistakes,
                'weak_skills' => array_slice($patterns['error_types'] ?? [], 0, 5, true),
                'weak_kps' => array_slice($patterns['knowledge_points'] ?? [], 0, 5, true),
                'error_types' => $patterns['error_types'] ?? [],
                'stats' => $summary,
            ];

        } catch (\Throwable $e) {
            Log::error('获取快照数据失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage(),
            ]);

            return [
                'recent' => [],
                'weak_skills' => [],
                'weak_kps' => [],
                'error_types' => [],
                'stats' => [
                    'total' => 0,
                    'pending' => 0,
                    'this_week' => 0,
                ],
            ];
        }
    }

    /**
     * 应用筛选条件
     */
    private function applyFilters($query, array $params): void
    {
        // 知识点筛选
        if (!empty($params['kp_ids'])) {
            $kpIds = is_array($params['kp_ids']) ? $params['kp_ids'] : explode(',', $params['kp_ids']);
            $query->byKnowledgePoint($kpIds);
        }

        // 技能筛选
        if (!empty($params['skill_ids'])) {
            $skillIds = is_array($params['skill_ids']) ? $params['skill_ids'] : explode(',', $params['skill_ids']);
            $query->where(function ($q) use ($skillIds) {
                foreach ($skillIds as $skillId) {
                    $q->orWhereJsonContains('skill_ids', $skillId);
                }
            });
        }

        // 错误类型筛选
        if (!empty($params['error_types'])) {
            $errorTypes = is_array($params['error_types']) ? $params['error_types'] : explode(',', $params['error_types']);
            $query->whereIn('error_type', $errorTypes);
        }

        // 时间范围筛选
        if (!empty($params['time_range'])) {
            match ($params['time_range']) {
                'last_7' => $query->where('created_at', '>=', now()->subDays(7)),
                'last_30' => $query->where('created_at', '>=', now()->subDays(30)),
                'last_90' => $query->where('created_at', '>=', now()->subDays(90)),
                default => null,
            };
        }

        // 自定义时间范围
        if (!empty($params['start_date'])) {
            $query->whereDate('created_at', '>=', $params['start_date']);
        }
        if (!empty($params['end_date'])) {
            $query->whereDate('created_at', '<=', $params['end_date']);
        }

        // 复习状态筛选
        if (!empty($params['unreviewed_only'])) {
            $query->pending();
        }
        if (!empty($params['favorite_only'])) {
            $query->favorites();
        }
        if (!empty($params['in_retry_list_only'])) {
            $query->inRetryList();
        }

        // 排序
        $sortBy = $params['sort_by'] ?? 'created_at_desc';
        match ($sortBy) {
            'created_at_asc' => $query->orderBy('created_at'),
            'created_at_desc' => $query->orderByDesc('created_at'),
            'review_status_asc' => $query->orderBy('review_status'),
            'difficulty_desc' => $query->orderByDesc('difficulty'),
            default => null,
        };
    }

    /**
     * 转换错题记录格式
     */
    private function transformMistakeRecord(MistakeRecord $mistake, bool $detailed = false): array
    {
        // 【新增】通过 question_id 关联获取题目详情
        $questionDetails = $this->getQuestionDetails($mistake->question_id);

        // 【新增】通过 kp_ids 获取知识点信息
        $knowledgePoints = $this->getKnowledgePoints($mistake->kp_ids);

        $data = [
            'id' => $mistake->id,
            'student_id' => $mistake->student_id,
            'question_id' => $mistake->question_id,
            'paper_id' => $mistake->paper_id,
            'question_text' => $mistake->question_text,
            'student_answer' => $mistake->student_answer,
            // 【优先】questions 表的答案，其次才是错题本自带的
            'correct_answer' => $questionDetails['answer'] ?? $mistake->correct_answer,
            'created_at' => $mistake->created_at?->toISOString(),
            'review_status' => $mistake->review_status,
            'review_status_label' => $mistake->review_status_label,
            'review_count' => $mistake->review_count,
            'is_favorite' => $mistake->is_favorite,
            'in_retry_list' => $mistake->in_retry_list,
            'reviewed_at' => $mistake->reviewed_at?->toISOString(),
            'next_review_at' => $mistake->next_review_at?->toISOString(),
            'error_type' => $mistake->error_type,
            'error_type_label' => $mistake->error_type_label,
            // 【移除】kp_ids、source、source_label、knowledge_point 字段
            // 'kp_ids' => $mistake->kp_ids,
            // 'source' => $mistake->source,
            // 'source_label' => $mistake->source_label,
            // 'knowledge_point' => $mistake->knowledge_point,
            'explanation' => $mistake->explanation,
            'skill_ids' => $mistake->skill_ids,
            'difficulty' => $mistake->difficulty,
            'difficulty_level' => $mistake->difficulty_level,
            'importance' => $mistake->importance,
            'mastery_level' => $mistake->mastery_level,
            // 【新增】知识点信息
            'knowledge_points' => $knowledgePoints,
            // 【保留】options、question_type 字段（从 questions 表查询的）
            'options' => $questionDetails['options'] ?? null,
            'question_type' => $questionDetails['question_type'] ?? null,
            // 【移除】answer、solution 字段（从 questions 表查询的）
            // 'answer' => $questionDetails['answer'] ?? null,
            // 'solution' => $questionDetails['solution'] ?? null,
        ];

        if ($detailed) {
            $data['student'] = [
                'id' => $mistake->student?->student_id,
                'name' => $mistake->student?->name,
                'grade' => $mistake->student?->grade,
                'class_name' => $mistake->student?->class_name,
            ];
        }

        return $data;
    }

    /**
     * 构建缓存键
     */
    private function buildCacheKey(string $type, array $params): string
    {
        $key = "mistake_book:{$type}:" . md5(serialize($params));
        return $key;
    }

    /**
     * 清除缓存
     */
    private function clearCache(string|int $studentId): void
    {
        try {
            $patterns = [
                "mistake_book:list:{$studentId}",
                "mistake_book:summary:{$studentId}",
                "mistake_book:patterns:{$studentId}",
            ];

            foreach ($patterns as $key) {
                Cache::forget($key);
            }
        } catch (\Exception $e) {
            // 缓存清除失败不影响主流程
            Log::debug('缓存清除失败（可忽略）', ['error' => $e->getMessage()]);
        }
    }

    /**
     * 【新增】通过 question_id 获取题目详情
     */
    private function getQuestionDetails(?string $questionId): ?array
    {
        if (!$questionId) {
            return null;
        }

        try {
            $question = \DB::connection('mysql')
                ->table('questions')
                ->where('id', $questionId)
                ->first();

            if (!$question) {
                return null;
            }

            return [
                'stem' => $question->stem ?? null,
                'options' => $question->options ?? null,
                'answer' => $question->answer ?? null,
                'solution' => $question->solution ?? null,
                'difficulty' => $question->difficulty ?? null,
                'question_type' => $question->question_type ?? null,
            ];
        } catch (\Exception $e) {
            Log::warning('获取题目详情失败', [
                'question_id' => $questionId,
                'error' => $e->getMessage()
            ]);
            return null;
        }
    }

    /**
     * 【新增】通过 kp_ids 获取知识点信息
     */
    private function getKnowledgePoints(?array $kpIds): array
    {
        if (empty($kpIds)) {
            return [];
        }

        try {
            $knowledgePoints = \DB::connection('mysql')
                ->table('knowledge_points')
                ->whereIn('kp_code', $kpIds)
                ->select(['kp_code', 'name', 'parent_kp_code'])
                ->get()
                ->toArray();

            return array_map(function ($kp) {
                return [
                    'kp_code' => $kp->kp_code,
                    'name' => $kp->name ?? $kp->kp_code,
                    'parent_kp_code' => $kp->parent_kp_code,
                ];
            }, $knowledgePoints);
        } catch (\Exception $e) {
            Log::warning('获取知识点信息失败', [
                'kp_ids' => $kpIds,
                'error' => $e->getMessage()
            ]);
            return [];
        }
    }
}
