from typing import TypeVar, Generic, Any, Awaitable, Protocol
from pydantic import BaseModel

# Return types
TResult = TypeVar("TResult")

class ICommand(BaseModel):
    """
    Marker cho tất cả các Command.
    Command biểu diễn một ý định làm thay đổi trạng thái của hệ thống.
    """
    pass

class IQuery(BaseModel, Generic[TResult]):
    """
    Marker cho tất cả các Query.
    Query chỉ trả về dữ liệu và KHÔNG ĐƯỢC PHÉP thay đổi trạng thái hệ thống.
    """
    pass

TCommand = TypeVar("TCommand", bound=ICommand)
TQuery = TypeVar("TQuery", bound=IQuery)

class ICommandHandler(Generic[TCommand, TResult]):
    """
    Giao diện chuẩn cho tất cả các Command Handler.
    """
    def handle(self, command: TCommand) -> TResult:
        raise NotImplementedError

class IQueryHandler(Generic[TQuery, TResult]):
    """
    Giao diện chuẩn cho tất cả các Query Handler.
    """
    def handle(self, query: TQuery) -> TResult:
        raise NotImplementedError
