<?php

declare(strict_types=1);

namespace Kylin\Education\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Kylin\Education\Enums\StudentStatus;
use Kylin\Education\Traits\Encryptable;

/**
 * 学生模型
 *
 * 在线教育平台学生信息，关联用户账号和班级。
 *
 * 依据《个人信息保护法》第二十八条和《未成年人保护法》第七十二条，
 * 未成年学员的身份证号、监护人姓名、监护人手机号属于敏感个人信息，
 * 需 AES-256 加密存储。
 */
class Student extends Model
{
    use Encryptable;

    protected $table = 'students';

    protected $fillable = [
        'user_id',
        'student_no',
        'birthday',
        'gender',
        'id_card_encrypted',
        'guardian_name',
        'guardian_phone',
        'guardian_relation',
        'guardian_consent',
        'consent_document',
        'status',
        'source',
        'tags',
    ];

    /**
     * 需要加密存储的敏感字段
     *
     * 依据《个人信息保护法》第二十八条：
     * 不满十四周岁未成年人的个人信息属于敏感个人信息。
     * 依据《个人信息保护法》第五十一条：采取加密等安全技术措施。
     */
    protected array $encryptable = [
        'id_card_encrypted',
        'guardian_name',
        'guardian_phone',
    ];

    protected $casts = [
        'birthday' => 'date',
        'guardian_consent' => 'boolean',
        'status' => StudentStatus::class,
        'tags' => 'array',
    ];

    /**
     * 关联用户
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(config('auth.providers.users.model', \App\Models\User::class), 'user_id');
    }

    /**
     * 关联报名
     */
    public function enrollments(): HasMany
    {
        return $this->hasMany(Enrollment::class, 'student_id');
    }

    /**
     * 关联班级
     */
    public function classes()
    {
        return $this->belongsToMany(StudentClass::class, 'student_class_pivot', 'student_id', 'class_id');
    }

    /**
     * 是否为未成年人（<14岁）
     */
    public function isMinor(): bool
    {
        return $this->birthday->age < config('kylin-education.student.minor_age_threshold', 14);
    }
}
