"""User service."""

from typing import Any

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

from apex.core.security import get_password_hash
from apex.domain.models.user import BaseUser


class UserService:
    """
    User service for managing user operations.

    This is a base implementation. Users should extend this to work with their
    specific User model.
    """

    def __init__(self, session: AsyncSession, user_model: type[BaseUser]):
        """
        Initialize user service.

        Args:
            session: Database session
            user_model: User model class
        """
        self.session = session
        self.user_model = user_model

    async def get_user_by_email(self, email: str) -> BaseUser | None:
        """
        Get user by email.

        Args:
            email: User email

        Returns:
            User instance or None if not found
        """
        result = await self.session.execute(
            select(self.user_model).where(self.user_model.email == email)
        )
        return result.scalar_one_or_none()

    async def get_user_by_id(self, user_id: str) -> BaseUser | None:
        """
        Get user by ID.

        Args:
            user_id: User UUID

        Returns:
            User instance or None if not found
        """
        from uuid import UUID

        result = await self.session.execute(
            select(self.user_model).where(self.user_model.id == UUID(user_id))
        )
        return result.scalar_one_or_none()

    async def create_user(self, **kwargs) -> BaseUser:
        """
        Create a new user.

        Args:
            **kwargs: User field values (password will be hashed automatically)

        Returns:
            Created user instance
        """
        # Hash password if provided
        if "password" in kwargs:
            kwargs["password_hash"] = get_password_hash(kwargs.pop("password"))

        # Ensure hashed_password is set
        if "password_hash" not in kwargs:
            raise ValueError("Password is required")

        user = self.user_model(**kwargs)
        self.session.add(user)
        await self.session.flush()
        await self.session.refresh(user)
        return user

    async def update_user(self, user: BaseUser, **kwargs) -> BaseUser:
        """
        Update user fields.

        Args:
            user: User instance to update
            **kwargs: Fields to update (password will be hashed automatically)

        Returns:
            Updated user instance
        """
        # Hash password if provided
        if "password" in kwargs:
            kwargs["password_hash"] = get_password_hash(kwargs.pop("password"))

        for key, value in kwargs.items():
            setattr(user, key, value)

        await self.session.flush()
        await self.session.refresh(user)
        return user

    async def change_password(self, user: BaseUser, old_password: str, new_password: str) -> bool:
        """
        Change user password.

        Args:
            user: User instance
            old_password: Current password
            new_password: New password

        Returns:
            True if password changed successfully, False if old password is incorrect
        """
        from apex.core.security import verify_password

        if not verify_password(old_password, user.password_hash):
            return False

        user.password_hash = get_password_hash(new_password)
        await self.session.flush()
        return True

