<?php

namespace Kylin\User\Models;

use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Kylin\Rbac\Traits\HasRoles;
use Kylin\User\Enums\UserStatus;
use Laravel\Sanctum\HasApiTokens;

/**
 * 用户模型
 *
 * 核心用户实体，支持 RBAC 权限、API Token 认证。
 *
 * @property string $name               用户名
 * @property string $email              邮箱
 * @property string $phone              手机号
 * @property string $password           密码
 * @property string $avatar             头像
 * @property int    $status             状态（0-禁用 1-正常 2-锁定）
 * @property string $login_ip           最后登录IP
 * @property string $login_at           最后登录时间
 * @property string $age_group          年龄段
 */
class User extends Authenticatable
{
    use HasApiTokens, HasRoles, Notifiable;

    protected $fillable = [
        'name', 'email', 'phone', 'password', 'avatar',
        'status', 'login_ip', 'login_at', 'password_changed_at', 'age_group',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
        'login_at' => 'datetime',
        'password_changed_at' => 'datetime',
        'status' => UserStatus::class,
    ];

    protected $appends = ['age_group', 'is_adult', 'is_real_name_verified'];

    /**
     * 动态计算年龄分组
     * 优先使用数据库存储值，为空或 unknown 时从 UserProfile.birthday 动态计算
     */
    public function getAgeGroupAttribute(): string
    {
        $dbValue = $this->getRawOriginal('age_group');
        if ($dbValue && $dbValue !== 'unknown') {
            return $dbValue;
        }

        $profile = $this->getRelationValue('profile');
        if ($profile && $profile->birthday) {
            return self::calculateAgeGroup($profile->birthday->age);
        }

        return $dbValue ?? 'unknown';
    }

    /**
     * 动态计算是否成年
     */
    public function getIsAdultAttribute(): bool
    {
        return $this->age_group === 'adult';
    }

    /**
     * 动态计算是否已实名认证
     */
    public function getIsRealNameVerifiedAttribute(): bool
    {
        $profile = $this->getRelationValue('profile');
        return $profile !== null
            && !empty($profile->real_name)
            && !empty($profile->id_card);
    }

    /**
     * 根据年龄计算年龄分组（与 AgeGroup::fromAge 逻辑一致，避免反向依赖）
     */
    public static function calculateAgeGroup(int $age): string
    {
        return match (true) {
            $age < 8 => 'child',
            $age >= 8 && $age <= 15 => 'junior_minor',
            $age >= 16 && $age <= 17 => 'senior_minor',
            $age >= 18 => 'adult',
            default => 'unknown',
        };
    }

    public function profile(): HasOne
    {
        return $this->hasOne(UserProfile::class);
    }

    public function isActive(): bool
    {
        return $this->status === UserStatus::Active;
    }

    public function isLocked(): bool
    {
        return $this->status === UserStatus::Locked;
    }
}
