from enum import Enum
from logging import Logger
from typing import ClassVar, List, Optional, Set

from nostr_sdk import (
    Event,
    Metadata,
    ProductData,
    ShippingCost,
    ShippingMethod,
    StallData,
)
from pydantic import BaseModel, ConfigDict

class Namespace(str, Enum):
    """
    Represents a namespace.
    """

    MERCHANT = "com.synvya.merchant"
    GAMER = "com.synvya.gamer"
    OTHER = "com.synvya.other"

    """Configuration for Pydantic models to use enum values directly."""
    model_config = ConfigDict(use_enum_values=True)

class ProfileType(str, Enum):
    """
    Represents a profile type.
    """

    MERCHANT_RETAIL = "retail"
    MERCHANT_RESTAURANT = "restaurant"
    MERCHANT_SERVICE = "service"
    MERCHANT_BUSINESS = "business"
    MERCHANT_ENTERTAINMENT = "entertainment"
    MERCHANT_OTHER = "other"
    GAMER_DADJOKE = "dad-joke-game"
    OTHER_OTHER = "other"

    """Configuration for Pydantic models to use enum values directly."""
    model_config = ConfigDict(use_enum_values=True)

class ProfileFilter(BaseModel):
    """
    Represents a profile filter.
    """

    namespace: str
    type: ProfileType
    hashtags: List[str]

    def __init__(
        self,
        namespace: str,
        profile_type: ProfileType,
        hashtags: Optional[List[str]] = None,
    ) -> None: ...
    def to_json(self) -> str: ...
    @classmethod
    def from_json(cls, json_str: str) -> "ProfileFilter": ...

class Profile(BaseModel):
    """
    Nostr Profile class with public key only. Used to represent a third party profile.
    """

    PROFILE_URL_PREFIX: ClassVar[str]

    logger: ClassVar[Logger]
    about: str
    banner: str
    bot: bool
    display_name: str
    labels: List[str]
    locations: Set[str]
    name: str
    namespace: str
    nip_05: str
    picture: str
    profile_type: ProfileType
    profile_url: str
    public_key: str
    website: str

    def __init__(self, public_key: str) -> None: ...
    def add_hashtag(self, hashtag: str) -> None: ...
    def add_location(self, location: str) -> None: ...
    def get_about(self) -> str: ...
    def get_banner(self) -> str: ...
    def get_display_name(self) -> str: ...
    def get_hashtags(self) -> List[str]: ...
    def get_locations(self) -> Set[str]: ...
    def get_name(self) -> str: ...
    def get_namespace(self) -> str: ...
    def get_nip05(self) -> str: ...
    def get_picture(self) -> str: ...
    def get_profile_type(self) -> ProfileType: ...
    def get_profile_url(self) -> str: ...
    def get_public_key(self, encoding: str = "bech32") -> str: ...
    def get_website(self) -> str: ...
    def is_bot(self) -> bool: ...
    def is_nip05_validated(self) -> bool: ...
    def matches_filter(self, profile_filter: ProfileFilter) -> bool: ...
    def set_about(self, about: str) -> None: ...
    def set_banner(self, banner: str) -> None: ...
    def set_bot(self, bot: bool) -> None: ...
    def set_display_name(self, display_name: str) -> None: ...
    def set_name(self, name: str) -> None: ...
    def set_namespace(self, namespace: str) -> None: ...
    def set_nip05(self, nip05: str) -> None: ...
    def set_picture(self, picture: str) -> None: ...
    def set_profile_type(self, profile_type: ProfileType) -> None: ...
    def set_website(self, website: str) -> None: ...
    def to_dict(self) -> dict: ...
    def to_json(self) -> str: ...
    def __eq__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...
    def _fetch_nip05_metadata(self, nip05: str) -> dict: ...
    def _validate_profile_nip05(self) -> bool: ...
    def _validate_url(self, url: str) -> str: ...
    @classmethod
    async def from_metadata(cls, metadata: Metadata, public_key: str) -> "Profile": ...
    @classmethod
    async def from_event(cls, event: Event) -> "Profile": ...
    @classmethod
    def from_json(cls, json_str: str) -> "Profile": ...

class NostrKeys(BaseModel):
    public_key: str
    private_key: str

    def __init__(self, public_key: str, private_key: str) -> None: ...
    def get_public_key(self, encoding: str = "bech32") -> str: ...
    def get_private_key(self) -> str: ...
    def to_json(self) -> str: ...
    def __str__(self) -> str: ...
    @classmethod
    def from_private_key(cls, private_key: str) -> "NostrKeys": ...
    @classmethod
    def derive_public_key(cls, private_key: str, encoding: str = "bech32") -> str: ...

class ProductShippingCost(BaseModel):
    psc_id: str
    psc_cost: float

    def __init__(self, psc_id: str, psc_cost: float) -> None: ...
    def get_id(self) -> str: ...
    def get_cost(self) -> float: ...
    def set_id(self, psc_id: str) -> None: ...
    def set_cost(self, psc_cost: float) -> None: ...
    def to_dict(self) -> dict: ...
    def to_json(self) -> str: ...
    def __str__(self) -> str: ...

class StallShippingMethod(BaseModel):
    """
    Represents a shipping method for a stall.
    """

    ssm_id: str
    ssm_cost: float
    ssm_name: str
    ssm_regions: List[str]

    def __init__(
        self, ssm_id: str, ssm_cost: float, ssm_name: str, ssm_regions: List[str]
    ) -> None: ...
    def get_id(self) -> str: ...
    def get_cost(self) -> float: ...
    def get_name(self) -> str: ...
    def get_regions(self) -> List[str]: ...
    def set_id(self, ssm_id: str) -> None: ...
    def set_cost(self, ssm_cost: float) -> None: ...
    def set_name(self, ssm_name: str) -> None: ...
    def set_regions(self, ssm_regions: List[str]) -> None: ...
    def to_dict(self) -> dict: ...
    def to_json(self) -> str: ...
    def __str__(self) -> str: ...

class Product(BaseModel):
    id: str
    stall_id: str
    name: str
    description: str
    images: List[str]
    currency: str
    price: float
    quantity: int
    shipping: List[ShippingCost]
    categories: List[str]
    specs: List[List[str]]
    seller: str

    @classmethod
    def from_product_data(cls, product_data: ProductData) -> "Product": ...
    @classmethod
    def from_json(cls, json_str: str) -> "Product": ...
    def get_seller(self) -> str: ...
    def set_seller(self, seller: str) -> None: ...
    def to_product_data(self) -> ProductData: ...
    def to_dict(self) -> dict: ...
    def to_json(self) -> str: ...
    def __eq__(self, other: object) -> bool: ...

class Stall(BaseModel):
    id: str
    name: str
    description: str
    currency: str
    shipping: List[ShippingMethod]
    geohash: str

    # @classmethod
    # def from_stall_data(cls, stall_data: StallData) -> "MerchantStall": ...
    @classmethod
    def from_json(cls, stall_content: str) -> "Stall": ...
    def get_geohash(self) -> str: ...
    def set_geohash(self, geohash: str) -> None: ...
    def to_dict(self) -> dict: ...
    def to_json(self) -> str: ...
    def to_stall_data(self) -> StallData: ...
