# -*- coding: utf-8 -*-
"""
用户 CRUD 数据访问层
封装所有用户相关的数据库操作，业务逻辑层只调用此模块，不直接写 SQL。
"""

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.security import hash_password, verify_password
from app.models.user import User
from app.schemas.user import UserCreate, UserUpdate


async def get_user_by_username(db: AsyncSession, username: str) -> User | None:
    """根据用户名查询用户"""
    stmt = select(User).where(User.username == username)
    result = await db.execute(stmt)
    return result.scalar_one_or_none()


async def authenticate_user(
    db: AsyncSession, username: str, password: str
) -> User | None:
    """验证用户名密码，返回用户对象或 None"""
    user = await get_user_by_username(db, username)
    if not user or not user.is_active:
        return None
    if not verify_password(password, user.password_hash):
        return None
    return user


async def create_user(db: AsyncSession, data: UserCreate) -> User:
    """创建新用户"""
    user = User(
        username=data.username,
        password_hash=hash_password(data.password),
        role=data.role,
        permissions=data.permissions,
    )
    db.add(user)
    await db.flush()   # flush 获取自增 ID，但不提交 (由 get_db 统一提交)
    await db.refresh(user)
    return user


async def update_user(db: AsyncSession, user: User, data: UserUpdate) -> User:
    """部分更新用户信息"""
    update_data = data.model_dump(exclude_unset=True)
    if "password" in update_data:
        update_data["password_hash"] = hash_password(update_data.pop("password"))
    for field, value in update_data.items():
        setattr(user, field, value)
    await db.flush()
    await db.refresh(user)
    return user


async def delete_user(db: AsyncSession, user: User) -> None:
    """删除用户"""
    await db.delete(user)
    await db.flush()
