<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;

class MistakeRecord extends Model
{
    use HasFactory;

    protected $table = 'mistake_records';

    protected $fillable = [
        'student_id',
        'question_id',
        'paper_id',
        'source',
        'question_text',
        'student_answer',
        'correct_answer',
        'knowledge_point',
        'explanation',
        'is_corrected',
        'review_status',
        'review_count',
        'force_review',
        'is_favorite',
        'in_retry_list',
        'reviewed_at',
        'next_review_at',
        'error_type',
        'kp_ids',
        'skill_ids',
        'difficulty',
        'importance',
        'mastery_level',
        'remark',
    ];

    protected $casts = [
        'is_corrected' => 'boolean',
        'force_review' => 'boolean',
        'is_favorite' => 'boolean',
        'in_retry_list' => 'boolean',
        'reviewed_at' => 'datetime',
        'next_review_at' => 'datetime',
        'kp_ids' => 'array',
        'skill_ids' => 'array',
        'difficulty' => 'decimal:2',
        'mastery_level' => 'decimal:2',
    ];

    // 复习状态常量
    const REVIEW_STATUS_PENDING = 'pending';
    const REVIEW_STATUS_REVIEWED = 'reviewed';
    const REVIEW_STATUS_MASTERED = 'mastered';
    const REVIEW_STATUS_IGNORED = 'ignored';

    // 错误类型常量
    const ERROR_TYPE_CONCEPT = 'concept';
    const ERROR_TYPE_CALCULATION = 'calculation';
    const ERROR_TYPE_CARELESS = 'careless';
    const ERROR_TYPE_LOGIC = 'logic';
    const ERROR_TYPE_OTHER = 'other';

    // 来源常量
    const SOURCE_EXAM = 'exam';
    const SOURCE_PRACTICE = 'practice';
    const SOURCE_HOMEWORK = 'homework';
    const SOURCE_TEST = 'test';

    /**
     * 关联学生
     */
    public function student(): BelongsTo
    {
        return $this->belongsTo(Student::class, 'student_id', 'student_id');
    }

    /**
     * 获取复习状态标签
     */
    public function getReviewStatusLabelAttribute(): string
    {
        return match ($this->review_status) {
            self::REVIEW_STATUS_PENDING => '待复习',
            self::REVIEW_STATUS_REVIEWED => '已复习',
            self::REVIEW_STATUS_MASTERED => '已掌握',
            self::REVIEW_STATUS_IGNORED => '已忽略',
            default => '未知',
        };
    }

    /**
     * 获取错误类型标签
     */
    public function getErrorTypeLabelAttribute(): string
    {
        return match ($this->error_type) {
            self::ERROR_TYPE_CONCEPT => '概念错误',
            self::ERROR_TYPE_CALCULATION => '计算错误',
            self::ERROR_TYPE_CARELESS => '粗心错误',
            self::ERROR_TYPE_LOGIC => '逻辑错误',
            self::ERROR_TYPE_OTHER => '其他',
            default => '未知',
        };
    }

    /**
     * 获取来源标签
     */
    public function getSourceLabelAttribute(): string
    {
        return match ($this->source) {
            self::SOURCE_EXAM => '考试',
            self::SOURCE_PRACTICE => '练习',
            self::SOURCE_HOMEWORK => '作业',
            self::SOURCE_TEST => '测试',
            default => '未知',
        };
    }

    /**
     * 获取难度等级
     */
    public function getDifficultyLevelAttribute(): string
    {
        if (!$this->difficulty) {
            return '未知';
        }

        return match (true) {
            $this->difficulty < 0.3 => '简单',
            $this->difficulty < 0.7 => '中等',
            default => '困难',
        };
    }

    /**
     * 标记为已复习
     */
    public function markAsReviewed(): self
    {
        // 先递增 review_count
        $this->increment('review_count');
        // 然后更新其他字段
        $this->update([
            'review_status' => self::REVIEW_STATUS_REVIEWED,
            'reviewed_at' => now(),
        ]);

        // ⚠️ 重要：重新加载模型数据
        $this->refresh();

        // 根据复习次数计算下次复习时间
        $this->calculateNextReviewDate();

        return $this;
    }

    /**
     * 标记为已掌握
     */
    public function markAsMastered(): self
    {
        $this->update([
            'review_status' => self::REVIEW_STATUS_MASTERED,
            'mastery_level' => 1.0,
        ]);

        return $this;
    }

    /**
     * 切换收藏状态
     */
    public function toggleFavorite(): self
    {
        $this->update([
            'is_favorite' => !$this->is_favorite,
        ]);

        return $this;
    }

    /**
     * 加入重练清单
     */
    public function addToRetryList(): self
    {
        $this->update([
            'in_retry_list' => true,
            'force_review' => true,
        ]);

        return $this;
    }

    /**
     * 从重练清单移除
     */
    public function removeFromRetryList(): self
    {
        $this->update([
            'in_retry_list' => false,
        ]);

        return $this;
    }

    /**
     * 计算下次复习时间（艾宾浩斯遗忘曲线）
     */
    public function calculateNextReviewDate(): self
    {
        $intervals = [1, 2, 4, 7, 15, 30, 60]; // 复习间隔天数
        $reviewCount = $this->review_count;

        // 如果复习次数超过间隔数组长度，使用最大间隔
        $days = $intervals[min($reviewCount - 1, count($intervals) - 1)] ?? 60;

        $this->update([
            'next_review_at' => now()->addDays($days),
        ]);

        // ⚠️ 重要：重新加载模型数据
        $this->refresh();

        return $this;
    }

    /**
     * 作用域：按学生筛选
     */
    public function scopeForStudent($query, int|string $studentId)
    {
        return $query->where('student_id', $studentId);
    }

    /**
     * 作用域：按复习状态筛选
     */
    public function scopeByReviewStatus($query, string $status)
    {
        return $query->where('review_status', $status);
    }

    /**
     * 作用域：待复习
     */
    public function scopePending($query)
    {
        return $query->where('review_status', self::REVIEW_STATUS_PENDING);
    }

    /**
     * 作用域：已收藏
     */
    public function scopeFavorites($query)
    {
        return $query->where('is_favorite', true);
    }

    /**
     * 作用域：在重练清单
     */
    public function scopeInRetryList($query)
    {
        return $query->where('in_retry_list', true);
    }

    /**
     * 作用域：本周新增
     */
    public function scopeThisWeek($query)
    {
        return $query->whereBetween('created_at', [
            now()->startOfWeek(),
            now()->endOfWeek(),
        ]);
    }

    /**
     * 作用域：按时间范围筛选
     */
    public function scopeInDateRange($query, Carbon $startDate, Carbon $endDate)
    {
        return $query->whereBetween('created_at', [$startDate, $endDate]);
    }

    /**
     * 作用域：按错误类型筛选
     */
    public function scopeByErrorType($query, string $errorType)
    {
        return $query->where('error_type', $errorType);
    }

    /**
     * 作用域：按知识点筛选
     */
    public function scopeByKnowledgePoint($query, string|array $kpIds)
    {
        if (is_array($kpIds)) {
            return $query->where(function ($q) use ($kpIds) {
                foreach ($kpIds as $kpId) {
                    $q->orWhereJsonContains('kp_ids', $kpId);
                }
            });
        }

        return $query->whereJsonContains('kp_ids', $kpIds);
    }

    /**
     * 获取统计摘要
     */
    public static function getSummary(int|string $studentId): array
    {
        $query = self::forStudent($studentId);

        return [
            'total' => (clone $query)->count(),
            'pending' => (clone $query)->pending()->count(),
            'reviewed' => (clone $query)->byReviewStatus(self::REVIEW_STATUS_REVIEWED)->count(),
            'mastered' => (clone $query)->byReviewStatus(self::REVIEW_STATUS_MASTERED)->count(),
            'favorites' => (clone $query)->favorites()->count(),
            'in_retry_list' => (clone $query)->inRetryList()->count(),
            'this_week' => (clone $query)->thisWeek()->count(),
            'mastery_rate' => self::calculateMasteryRate($studentId),
        ];
    }

    /**
     * 计算掌握率
     */
    public static function calculateMasteryRate(int|string $studentId): float
    {
        $total = self::forStudent($studentId)->count();
        if ($total === 0) {
            return 0.0;
        }

        $mastered = self::forStudent($studentId)
            ->byReviewStatus(self::REVIEW_STATUS_MASTERED)
            ->count();

        return round(($mastered / $total) * 100, 2);
    }

    /**
     * 获取错误模式分析
     */
    public static function getMistakePatterns(int|string $studentId): array
    {
        $query = self::forStudent($studentId);

        // 错误类型分布
        $errorTypes = (clone $query)
            ->selectRaw('error_type, COUNT(*) as count')
            ->groupBy('error_type')
            ->pluck('count', 'error_type')
            ->toArray();

        // 知识点分布
        $knowledgePoints = self::forStudent($studentId)
            ->selectRaw('knowledge_point, COUNT(*) as count')
            ->groupBy('knowledge_point')
            ->orderByDesc('count')
            ->limit(10)
            ->pluck('count', 'knowledge_point')
            ->toArray();

        // 来源分布
        $sources = (clone $query)
            ->selectRaw('source, COUNT(*) as count')
            ->groupBy('source')
            ->pluck('count', 'source')
            ->toArray();

        // 难度分布
        $difficultyStats = (clone $query)
            ->selectRaw('AVG(difficulty) as avg_difficulty, COUNT(*) as total')
            ->first();

        return [
            'error_types' => $errorTypes,
            'knowledge_points' => $knowledgePoints,
            'sources' => $sources,
            'difficulty_stats' => [
                'average' => round($difficultyStats->avg_difficulty ?? 0, 2),
                'total' => $difficultyStats->total ?? 0,
            ],
            'weak_kps' => array_keys(array_slice($knowledgePoints, 0, 5, true)),
            'top_error_types' => array_keys(array_slice($errorTypes, 0, 3, true)),
        ];
    }
}
