<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

/**
 * User model — maps to table {{%user}} → lms_user
 *
 * @property int    $id
 * @property string $first_name
 * @property string $last_name
 * @property string $username
 * @property string $email
 * @property string $password
 * @property int    $level        0=admin, 1=staff
 * @property int    $user_group_id
 * @property string $is_active    Y|N
 * @property string $last_login
 * @property string $created_at
 * @property string $updated_at
 */
class User extends ActiveRecord implements IdentityInterface
{
    const LEVEL_ADMIN = 0;
    const LEVEL_STAFF = 1;

    public $password_new; // virtual field for forms

    public static function tableName(): string
    {
        return '{{%user}}';
    }

    // ----------------------------------------------------------------
    // IdentityInterface
    // ----------------------------------------------------------------
    public static function findIdentity($id): ?self
    {
        return static::findOne(['id' => $id, 'is_active' => 'Y']);
    }

    public static function findIdentityByAccessToken($token, $type = null): ?self
    {
        return null;
    }

    public static function findByUsername(string $username): ?self
    {
        return static::findOne(['username' => strtolower($username), 'is_active' => 'Y'])
            ?? static::find()->where(['LOWER(username)' => strtolower($username), 'is_active' => 'Y'])->one();
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function getAuthKey(): string
    {
        return md5($this->password . $this->id);
    }

    public function validateAuthKey($authKey): bool
    {
        return $this->getAuthKey() === $authKey;
    }

    public function validatePassword(string $password): bool
    {
        return Yii::$app->security->validatePassword($password, $this->password);
    }

    public static function hashPassword(string $password): string
    {
        return Yii::$app->security->generatePasswordHash($password);
    }

    // ----------------------------------------------------------------
    // ActiveRecord
    // ----------------------------------------------------------------
    public function rules(): array
    {
        return [
            [['first_name', 'username', 'is_active'], 'required'],
            [['level', 'user_group_id'], 'integer'],
            [['username'], 'unique'],
            [['username', 'email'], 'string', 'max' => 100],
            [['first_name', 'last_name'], 'string', 'max' => 100],
            [['password'], 'string', 'max' => 255],
            [['is_active'], 'in', 'range' => ['Y', 'N']],
        ];
    }

    public function attributeLabels(): array
    {
        return [
            'id'            => 'ID',
            'first_name'    => 'First Name',
            'last_name'     => 'Last Name',
            'username'      => 'Username',
            'email'         => 'Email',
            'password'      => 'Password',
            'level'         => 'Role',
            'user_group_id' => 'User Group',
            'is_active'     => 'Status',
            'last_login'    => 'Last Login',
        ];
    }

    public function getFullName(): string
    {
        return trim($this->first_name . ' ' . $this->last_name);
    }

    public function isAdmin(): bool
    {
        return (int)$this->level === self::LEVEL_ADMIN;
    }

    public function getUserGroup(): \yii\db\ActiveQuery
    {
        return $this->hasOne(MasUserGroup::class, ['id' => 'user_group_id']);
    }
}
