from analogai.foundation.modules.user.user_repository import UserRepository
from analogai.foundation.core.observables.user_observable_service import UserObservableService
from analogai.foundation.modules.user.user import User
from typeguard import typechecked
from typing import Optional
from analogai.foundation.common.logging.app_logger import app_logger

class UserService(UserObservableService):
    def __init__(self, user_repository: UserRepository):
        super().__init__()
        self.user_repository = user_repository

    @typechecked
    def find(self, id: str) -> Optional[User]:
        user = self.user_repository.find_by_id(id)
        if user:
            app_logger.success(f"Found User: {user}")
        else:
            app_logger.warning(f"User not found: id={id}")
        return user

    @typechecked
    def create(self, id: str, name: str, email: str, timezone: Optional[str] = None) -> User:
        existing_user = self.user_repository.find_by_email(email)
        if existing_user:
            raise ValueError(f"User with email '{email}' already exists")
        
        user = User(id=id, name=name, email=email, timezone=timezone)
        result = self.user_repository.create(user)
        self.notify_user_created(result)
        app_logger.debug(f"Created User: {result}")
        return result

    @typechecked
    def delete(self, id: str) -> bool:
        return self.user_repository.delete(id)

    @typechecked
    def find_by_email(self, email: str) -> Optional[User]:
        user = self.user_repository.find_by_email(email)
        if user:
            app_logger.debug(f"Found User: {user}")
        else:
            app_logger.warning(f"User not found: email='{email}'")
        return user

    @typechecked
    def update(self, user: User) -> User:
        existing_user = self.user_repository.find_by_id(user.id)
        if not existing_user:
            raise ValueError(f"User with ID {user.id} not found")
        
        updated_user = self.user_repository.update(user)
        app_logger.debug(f"Updated User: {updated_user}")
        return updated_user