from typing import ClassVar, Protocol, TypeVar
from humps import camelize
from enum import Enum
from pydantic import UUID4, BaseModel, ConfigDict

T = TypeVar("T", bound=BaseModel)

class SearchType(Enum):
    fuzzy = "fuzzy"
    tokenized = "tokenized"

class FuwareModel(BaseModel):
  _searchable_properties: ClassVar[list[str]] = []
  """
    Searchable properties for the search API.
    The first property will be used for sorting (order_by)
    """
  model_config = ConfigDict(alias_generator=camelize, populate_by_name=True)

  def cast(self, cls: type[T], **kwargs) -> T:
    """
    Cast the current model to another with additional arguments. Useful for
    transforming DTOs into models that are saved to a database
    """
    create_data = {field: getattr(self, field) for field in self.__fields__ if field in cls.__fields__}
    create_data.update(kwargs or {})
    return cls(**create_data)