import bcrypt

from datetime import datetime
from typing import Optional

class UserModel:
    def __init__(self,
                 username: str,
                 email: Optional[str] = None,
                 phone: Optional[str] = None,
                 name: Optional[str] = None,
                 user_id: int = None,
                 last_login: datetime = None,
                 created_at: datetime = None,
                 create_by: Optional[str] = None,
                 update_by: Optional[str] = None,
                 updated_at: datetime = None,
                 delete_by: Optional[str] = None,
                 deleted_at: datetime = None):
        self.id = user_id
        self.username = username
        self.email = email
        self.phone = phone
        self.name = name
        self._password = None
        self.last_login = last_login
        self.created_at = created_at or datetime.now()
        self.create_by = create_by
        self.update_by = update_by
        self.updated_at = updated_at
        self.delete_by = delete_by
        self.deleted_at = deleted_at

    def set_password(self, password: str):
        self._password = password

    def get_password(self) -> str:
        return self._password

    @staticmethod
    def _hash_password(password: str) -> bytes:
        salt = bcrypt.gensalt()
        return bcrypt.hashpw(password.encode('utf-8'), salt)

    def set_password_hash(self, password: str):
        if not password:
            raise ValueError("密码不能为空")
        self._password = self._hash_password(password)

    def verify_password(self, password: str) -> bool:
        if not self._password:
            return False
        return bcrypt.checkpw(password.encode('utf-8'), self._password.encode('utf-8'))  # 确保 _password 为字节类型

    def update_last_login(self):
        self.last_login = datetime.now()

    def to_dict(self) -> dict:
        return {
            'id': self.id,
            'username': self.username,
            'name': self.name,
            'email': self.email,
            'phone': self.phone,
        }