<?php

namespace App\Filament\Pages;

use App\Filament\Traits\HandlesMindmapDetails;
use App\Filament\Traits\HasUserRole;
use App\Models\Student;
use App\Models\Teacher;
use App\Services\KnowledgeMasteryService;
use App\Services\LearningAnalyticsService;
use App\Services\MasteryCalculator;
use BackedEnum;
use Filament\Pages\Page;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use UnitEnum;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\On;
use Livewire\Attributes\Computed;
use App\Models\Student as StudentModel;
use App\Services\MistakeBookService;

class StudentDashboard extends Page
{
    use HasUserRole, HandlesMindmapDetails, \Filament\Pages\Concerns\InteractsWithFormActions;

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-chart-bar';

    protected static string|UnitEnum|null $navigationGroup = '学生管理';

    protected static ?string $navigationLabel = '学生仪表板';

    protected static ?int $navigationSort = 2;

    protected ?string $heading = '学生仪表板';

    protected string $view = 'filament.pages.student-dashboard';

    public string $studentId = '';
    public string $teacherId = '';
    public array $dashboardData = [];
    public bool $isLoading = false;
    public string $errorMessage = '';
    public array $mindmapMasteryData = [];
    public bool $mindmapDrawerOpen = false;
    public array $mindmapNodeDetails = [];
    public ?string $mindmapSelectedNode = null;
    // teachers 和 students 现在是 Computed 属性，不再需要声明
    public array $mistakePanel = [];

    public function mount(Request $request): void
    {
        // 初始化用户角色检查
        $this->initializeUserRole();

        // 如果是老师，自动选择当前老师
        if ($this->isTeacher) {
            $teacherId = $this->getCurrentTeacherId();
            if ($teacherId) {
                $this->teacherId = $teacherId;
            }
        } else {
            // 从请求中获取老师ID
            $this->teacherId = (string) ($request->input('teacher_id') ?? '');
        }

        // 从请求中获取学生ID
        $this->studentId = (string) ($request->input('student_id') ?? '');

        if ($this->studentId && empty($this->teacherId)) {
            $student = StudentModel::find($this->studentId);
            if ($student && $student->teacher_id) {
                $this->teacherId = (string) $student->teacher_id;
            }
        }

        // 若已通过 URL 传入学生，自动加载仪表盘数据，减少手动刷新
        if ($this->studentId && $this->teacherId) {
            $this->loadDashboardData();
        }
    }

    #[Computed]
    public function teachers(): array
    {
        try {
            $query = Teacher::query()
                ->leftJoin('users as u', 'teachers.teacher_id', '=', 'u.user_id')
                ->select(
                    'teachers.teacher_id',
                    'teachers.name',
                    'teachers.subject',
                    'u.username',
                    'u.email'
                );

            // 如果是老师，只返回自己
            if ($this->isTeacher) {
                $teacherId = $this->getCurrentTeacherId();
                if ($teacherId) {
                    $query->where('teachers.teacher_id', $teacherId);
                }
            }

            $teachers = $query->orderBy('teachers.name')->get();

            // 检查是否有学生没有对应的老师记录
            $teacherIds = $teachers->pluck('teacher_id')->toArray();
            $missingTeacherIds = Student::query()
                ->distinct()
                ->whereNotIn('teacher_id', $teacherIds)
                ->pluck('teacher_id')
                ->toArray();

            $teachersArray = $teachers->all();

            if (!empty($missingTeacherIds)) {
                foreach ($missingTeacherIds as $missingId) {
                    $teachersArray[] = (object) [
                        'teacher_id' => $missingId,
                        'name' => '未知老师 (' . $missingId . ')',
                        'subject' => '未知',
                        'username' => null,
                        'email' => null
                    ];
                }

                usort($teachersArray, function($a, $b) {
                    return strcmp($a->name, $b->name);
                });
            }

            return $teachersArray;
        } catch (\Exception $e) {
            Log::error('加载老师列表失败', [
                'error' => $e->getMessage()
            ]);
            return [];
        }
    }

    #[Computed]
    public function students(): array
    {
        if (empty($this->teacherId)) {
            return [];
        }

        try {
            return Student::query()
                ->leftJoin('users as u', 'students.student_id', '=', 'u.user_id')
                ->where('students.teacher_id', $this->teacherId)
                ->select(
                    'students.student_id',
                    'students.name',
                    'students.grade',
                    'students.class_name',
                    'u.username',
                    'u.email'
                )
                ->orderBy('students.grade')
                ->orderBy('students.class_name')
                ->orderBy('students.name')
                ->get()
                ->all();
        } catch (\Exception $e) {
            Log::error('加载学生列表失败', [
                'teacher_id' => $this->teacherId,
                'error' => $e->getMessage()
            ]);
            return [];
        }
    }

    /**
     * 老师改变时重新加载学生列表
     */
    public function updatedTeacherId(): void
    {
        // 清空之前选中的学生ID
        $this->studentId = '';
    }

    /**
     * 学生改变时重新加载数据
     */
    public function updatedStudentId(): void
    {
        if (!empty($this->studentId)) {
            $this->loadDashboardData();
        } else {
            $this->mindmapMasteryData = [];
            $this->dispatch('mastery-updated', data: []);
            $this->mistakePanel = [];
        }
    }

    public function loadDashboardData(): void
    {
        // 检查是否选择了学生
        if (empty($this->studentId)) {
            $this->errorMessage = '请先选择学生';
            $this->isLoading = false;
            return;
        }

        $this->isLoading = true;
        $this->errorMessage = '';

        try {
            $service = app(LearningAnalyticsService::class);

            // 检查服务健康状态
            if (!$service->checkHealth()) {
                $this->errorMessage = '学习分析系统当前不可用，请稍后重试';
                $this->isLoading = false;
                return;
            }

            Log::info('开始加载仪表板数据', ['student_id' => $this->studentId]);

            // 获取各项数据
            $masteryOverview = $service->getStudentMasteryOverview($this->studentId);
            $skillProficiency = $service->getStudentSkillProficiency($this->studentId);
            $skillSummary = $service->getStudentSkillSummary($this->studentId);
            $predictions = $service->getStudentPredictions($this->studentId, 5);
            $learningPaths = $service->getStudentLearningPaths($this->studentId, 3);
            $predictionAnalytics = $service->getPredictionAnalytics($this->studentId);
            $pathAnalytics = $service->getLearningPathAnalytics($this->studentId);
            $quickPrediction = $service->quickScorePrediction($this->studentId);

            Log::info('快速预测结果', [
                'student_id' => $this->studentId,
                'quick_prediction' => $quickPrediction
            ]);

            $recommendations = $service->recommendLearningPaths($this->studentId, 3);

            // 组合数据
            $masteryList = $service->getStudentMasteryList($this->studentId);

            // 如果没有掌握度数据，从错题记录中生成基于错题的掌握度
            if (empty($masteryList['data'] ?? [])) {
                Log::info('未找到掌握度数据，从错题记录生成', ['student_id' => $this->studentId]);
                $masteryList = $this->generateMasteryFromMistakes($this->studentId);
            }

            $this->dashboardData = [
                'mastery' => [
                    'overview' => $masteryOverview,
                    'list' => $masteryList,
                ],
                'skill' => [
                    'proficiency' => $skillProficiency,
                    'summary' => $skillSummary,
                ],
                'prediction' => [
                    'list' => $predictions,
                    'analytics' => $predictionAnalytics,
                    'quick' => $quickPrediction,
                ],
                'learning_path' => [
                    'list' => $learningPaths,
                    'analytics' => $pathAnalytics,
                    'recommendations' => $recommendations,
                ],
            ];

            $this->mindmapMasteryData = $this->buildMasteryMap(
                $this->dashboardData['mastery']['list'] ?? []
            );
            $this->dispatch('mastery-updated', data: $this->mindmapMasteryData);

            Log::info('仪表板数据加载完成', [
                'student_id' => $this->studentId,
                'dashboard_data_keys' => array_keys($this->dashboardData)
            ]);

            try {
                $mistakeService = app(MistakeBookService::class);
                $this->mistakePanel = $mistakeService->getPanelSnapshot($this->studentId, 5);
            } catch (\Exception $e) {
                Log::warning('加载错题本面板数据失败', [
                    'student_id' => $this->studentId,
                    'error' => $e->getMessage()
                ]);
                $this->mistakePanel = [];
            }

        } catch (\Exception $e) {
            $this->errorMessage = '加载数据时发生错误：' . $e->getMessage();
            Log::error('学生仪表板数据加载失败', [
                'student_id' => $this->studentId,
                'error' => $e->getMessage()
            ]);
            $this->mindmapMasteryData = [];
            $this->dispatch('mastery-updated', data: []);
            $this->mistakePanel = [];
        } finally {
            $this->isLoading = false;
        }
    }

    public function recalculateMastery(string $kpCode): void
    {
        try {
            // 使用本地MasteryCalculator替代LearningAnalyticsService
            $masteryCalculator = app(MasteryCalculator::class);
            $result = $masteryCalculator->calculateMasteryLevel($this->studentId, $kpCode);

            if (!empty($result)) {
                $this->dispatch('notify', message: '掌握度重新计算完成', type: 'success');
                $this->loadDashboardData(); // 刷新数据
            } else {
                $this->dispatch('notify', message: '掌握度重新计算失败', type: 'danger');
            }
        } catch (\Exception $e) {
            Log::error('重新计算掌握度失败', [
                'student_id' => $this->studentId,
                'kp_code' => $kpCode,
                'error' => $e->getMessage()
            ]);
            $this->dispatch('notify', message: '操作失败：' . $e->getMessage(), type: 'danger');
        }
    }

    public function batchUpdateSkills(): void
    {
        try {
            // 使用本地MasteryCalculator替代LearningAnalyticsService
            $masteryCalculator = app(MasteryCalculator::class);
            // TODO: 需要实现本地的batchUpdateSkillProficiency功能
            \Log::warning('跳过LearningAnalytics的batchUpdateSkillProficiency调用', [
                'student_id' => $this->studentId,
                'reason' => '功能已迁移到本地KnowledgeMasteryService，但batchUpdateSkillProficiency尚未实现'
            ]);

            $this->dispatch('notify', message: '技能熟练度更新完成', type: 'success');
            $this->loadDashboardData(); // 刷新数据
        } catch (\Exception $e) {
            Log::error('批量更新技能熟练度失败', [
                'student_id' => $this->studentId,
                'error' => $e->getMessage()
            ]);
            $this->dispatch('notify', message: '操作失败：' . $e->getMessage(), type: 'danger');
        }
    }

    public function generateQuickPrediction(): void
    {
        try {
            // 使用本地MasteryCalculator替代LearningAnalyticsService
            $masteryCalculator = app(MasteryCalculator::class);
            // TODO: 需要实现本地的quickScorePrediction功能
            \Log::warning('跳过LearningAnalytics的quickScorePrediction调用', [
                'student_id' => $this->studentId,
                'reason' => '功能已迁移到本地KnowledgeMasteryService，但quickScorePrediction尚未实现'
            ]);

            $this->dispatch('notify', message: '快速预测生成完成', type: 'success');
            $this->loadDashboardData(); // 刷新数据
        } catch (\Exception $e) {
            Log::error('生成快速预测失败', [
                'student_id' => $this->studentId,
                'error' => $e->getMessage()
            ]);
            $this->dispatch('notify', message: '操作失败：' . $e->getMessage(), type: 'danger');
        }
    }

    protected function buildMasteryMap(array $list): array
    {
        $map = [];
        $items = $list['data'] ?? $list['masteries'] ?? $list;

        if (!is_array($items)) {
            return $map;
        }

        foreach ($items as $item) {
            if (!is_array($item)) {
                continue;
            }

            $code = $item['kp_code'] ?? $item['code'] ?? null;
            if (!$code) {
                continue;
            }

            $map[$code] = $item;
        }

        return $map;
    }

    public function openMindmapDrawer(string $nodeId): void
    {
        $this->mindmapSelectedNode = $nodeId;
        $this->mindmapNodeDetails = $this->getNodeDetails($nodeId, $this->mindmapMasteryData);
        $this->mindmapDrawerOpen = true;
    }

    public function closeMindmapDrawer(): void
    {
        $this->mindmapDrawerOpen = false;
        $this->mindmapSelectedNode = null;
        $this->mindmapNodeDetails = [];
    }


    /**
     * 监听TeacherStudentSelector组件的老师变化事件
     */
    #[On('teacherChanged')]
    public function onTeacherChanged(string $teacherId): void
    {
        $this->teacherId = $teacherId;
        $this->loadStudentsByTeacher();
        $this->studentId = $this->getDefaultStudentId();
    }

    /**
     * 监听TeacherStudentSelector组件的学生变化事件
     */
    #[On('studentChanged')]
    public function onStudentChanged(string $teacherId, string $studentId): void
    {
        $this->teacherId = $teacherId;
        $this->studentId = $studentId;
        $this->loadDashboardData();
    }

    /**
     * 从错题记录生成掌握度数据
     */
    private function generateMasteryFromMistakes(string $studentId): array
    {
        try {
            // 获取学生的错题记录
            $mistakeRecords = \App\Models\MistakeRecord::forStudent($studentId)
                ->get(['kp_ids', 'knowledge_point', 'is_corrected', 'review_status']);

            // 统计每个知识点的错题数量
            $kpStats = [];
            foreach ($mistakeRecords as $record) {
                $kpIds = $record->kp_ids ?? [];
                if (is_string($kpIds)) {
                    $kpIds = json_decode($kpIds, true) ?? [];
                }

                foreach ($kpIds as $kpCode) {
                    if (empty($kpCode)) {
                        continue;
                    }

                    if (!isset($kpStats[$kpCode])) {
                        $kpStats[$kpCode] = [
                            'kp_code' => $kpCode,
                            'kp_name' => $record->knowledge_point ?? $kpCode,
                            'mistake_count' => 0,
                            'corrected_count' => 0,
                            'mastery_level' => 0.0,
                        ];
                    }

                    $kpStats[$kpCode]['mistake_count']++;
                    if ($record->is_corrected) {
                        $kpStats[$kpCode]['corrected_count']++;
                    }
                }
            }

            // 计算掌握度（基于错题数量和纠正情况）
            $masteryData = [];
            foreach ($kpStats as $kpCode => $stats) {
                $total = $stats['mistake_count'];
                $corrected = $stats['corrected_count'];

                // 掌握度计算：已纠正的题目比例 + 基础分数
                // 如果全部纠正，掌握度较高；如果有未纠正的，掌握度较低
                $masteryLevel = $total > 0
                    ? ($corrected / $total) * 0.7 + 0.1  // 基础分数0.1，最高0.8
                    : 0.5; // 默认中等掌握度

                // 确保掌握度在合理范围内
                $masteryLevel = max(0.1, min(0.9, $masteryLevel));

                $masteryData[] = [
                    'kp_code' => $kpCode,
                    'kp_name' => $stats['kp_name'],
                    'mastery_level' => round($masteryLevel, 2),
                    'total_attempts' => $total,
                    'correct_attempts' => $corrected,
                    'accuracy_rate' => $total > 0 ? round($corrected / $total, 2) : 0,
                    'trend' => $corrected >= ($total * 0.5) ? 'improving' : 'needs_attention',
                    'last_attempt' => now()->toISOString(),
                ];
            }

            Log::info('从错题记录生成掌握度数据', [
                'student_id' => $studentId,
                'kp_count' => count($masteryData),
                'mastery_data' => $masteryData
            ]);

            // 为生成的掌握度数据创建快照记录
            $this->createMasterySnapshots($studentId, $masteryData);

            return [
                'student_id' => $studentId,
                'total_count' => count($masteryData),
                'data' => $masteryData,
            ];

        } catch (\Exception $e) {
            Log::error('从错题记录生成掌握度失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage()
            ]);

            return [
                'student_id' => $studentId,
                'total_count' => 0,
                'data' => [],
            ];
        }
    }

    /**
     * 创建掌握度快照记录
     */
    private function createMasterySnapshots(string $studentId, array $masteryData): void
    {
        try {
            // 计算整体掌握度
            $totalPoints = count($masteryData);
            $averageMastery = $totalPoints > 0
                ? array_sum(array_column($masteryData, 'mastery_level')) / $totalPoints
                : 0;

            // 统计强弱知识点数量
            $weakCount = 0;
            $strongCount = 0;
            foreach ($masteryData as $data) {
                $level = floatval($data['mastery_level']);
                if ($level >= 0.7) {
                    $strongCount++;
                } elseif ($level < 0.5) {
                    $weakCount++;
                }
            }

            // 生成快照ID
            $snapshotId = 'auto_' . $studentId . '_' . time();

            // 创建快照记录
            DB::table('knowledge_point_mastery_snapshots')->insert([
                'snapshot_id' => $snapshotId,
                'student_id' => $studentId,
                'paper_id' => null, // 自动生成，没有关联试卷
                'answer_record_id' => null,
                'mastery_data' => json_encode($masteryData),
                'overall_mastery' => round($averageMastery, 4),
                'weak_knowledge_points_count' => $weakCount,
                'strong_knowledge_points_count' => $strongCount,
                'snapshot_time' => now(),
                'analysis_id' => null,
                'created_at' => now(),
                'updated_at' => now(),
            ]);

            Log::info('创建掌握度快照', [
                'student_id' => $studentId,
                'snapshot_id' => $snapshotId,
                'total_knowledge_points' => $totalPoints,
                'average_mastery' => $averageMastery,
                'weak_count' => $weakCount,
                'strong_count' => $strongCount,
            ]);

        } catch (\Exception $e) {
            Log::error('创建掌握度快照失败', [
                'student_id' => $studentId,
                'error' => $e->getMessage()
            ]);
        }
    }
}
