from __future__ import annotations

from typing import Any, Literal
from pydantic import BaseModel, Field, ConfigDict, AliasPath

from ._constants import BASE_URL, USER_AGENT


HttpVersion = Literal["v1", "v2", "v2tls", "v2_prior_knowledge", "v3"]


class ClientConfig(BaseModel):
    """Client configuration for API connections.

    Stores default parameters such as base URL, timeout, headers,
    HTTP version, and optional authentication token.
    """

    model_config = ConfigDict(extra="ignore")

    base_url: str = BASE_URL
    timeout: float = 30.0
    user_agent: str = USER_AGENT
    default_headers: dict[str, str] = Field(default_factory=dict)
    http_version: HttpVersion = "v2"
    token: str | None = None


class Status(BaseModel):
    """Response status metadata returned by the API."""

    model_config = ConfigDict(extra="ignore")

    code: int | None = None
    msg: str = ""
    request_id: str | None = None


class APIEnvelope(BaseModel):
    """Generic API response wrapper.

    Most endpoints return a JSON object with a `status` and an optional `data`
    field. This model represents that structure.
    """

    status: Status
    data: Any = None


class LoginData(BaseModel):
    """Information returned after a successful login.

    Attributes:
        id: Account ID.
        email: User email.
        name: Display name.
        token: Authentication token for subsequent requests.

    Notes:
        Other fields are included for compatibility with the upstream API
        response. Unrecognized fields are ignored (`extra="ignore"`).
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    id: str = Field(validation_alias=AliasPath("account", "id"))
    email: str | None = Field(
        default=None, validation_alias=AliasPath("account", "email")
    )
    head: str | None = Field(
        default=None, validation_alias=AliasPath("account", "head")
    )
    avatar_frame: str | None = Field(
        default=None, validation_alias=AliasPath("account", "avatar_frame")
    )
    create_at: int | None = Field(
        default=None, validation_alias=AliasPath("account", "create_at")
    )
    name: str | None = Field(
        default=None, validation_alias=AliasPath("account", "name")
    )
    status: int | None = Field(
        default=None, validation_alias=AliasPath("account", "status")
    )
    emp_status: int | None = Field(
        default=None, validation_alias=AliasPath("account", "emp_status")
    )
    guide_status: int | None = Field(
        default=None, validation_alias=AliasPath("account", "guide_status")
    )
    device_code: str | None = Field(
        default=None, validation_alias=AliasPath("account", "device_code")
    )
    is_europe: bool | None = Field(
        default=None, validation_alias=AliasPath("account", "is_europe")
    )
    adv_platforms: list[str] | None = Field(
        default=None, validation_alias=AliasPath("account", "adv_platforms")
    )
    lang: str | None = Field(
        default=None, validation_alias=AliasPath("account", "lang")
    )
    lang_code: str | None = Field(
        default=None, validation_alias=AliasPath("account", "lang_code")
    )

    token: str


class Badge(BaseModel):
    """User badge/award metadata.

    Immutable model with basic identity, display texts and media URIs.
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    id: str
    name_key: str | None = None
    intro_key: str | None = None
    uri: str | None = None
    uri_big: str | None = None
    status: int | None = None
    type: int | None = None
    name: str | None = None
    intro: str | None = None
    create_at: int | None = None
    start_at: int | None = None
    expire_at: int | None = None
    display_order: int | None = None


class AccountSettings(BaseModel):
    """Per-account feature toggles and UI preferences.

    Holds user-facing settings like localization, NSFW flags, auto-publish, etc.
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    is_variant_operation: bool
    is_auto_pub_community: bool
    is_off_localization: bool
    bg_cover: str | None = None
    green_mode: int | None = None
    lang_code: str | None = None
    nsfw_plus: int | None = None
    insight: int | None = None
    ai_video_auto_play: int | None = None
    task_flow_version: str | None = None
    task_image_prompt_switch: int | None = None
    use_model_preset_meta_mode: int | None = None
    character_push: int | None = None
    show_sexy_content: int | None = None
    show_eyes: int | None = None
    auto_save_artwork: int | None = None
    enable_no_download: int | None = None


class CharacterSetting(BaseModel):
    """Assistant/character runtime settings.

    Includes model choices, chat/streaming flags, UI mode and workflow bindings.
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    gpt_model: str | None = None
    functionality_gpt_model: str | None = None
    auto_tts: int | None = None
    enable_memory: int | None = None
    enable_five_memory: int | None = None
    style: str | None = None
    full_screen: int | None = None
    h5_full_screen: int | None = None
    h5_style: str | None = None
    hide_bg: int | None = None
    h5_hide_bg: int | None = None
    h5_hide_continue: int | None = None
    enable_stream_chat: int | None = None
    default_card: str | None = None
    gender: str | None = None
    is_set_companion_model: int | None = None
    is_set_functionality_model: int | None = None
    is_set_workflow: int | None = None
    on_line_search: int | None = None
    workflow_no: str | None = None
    initiative_chat: int | None = None
    immerse_switch: int | None = None
    recommend_reply: int | None = None
    confirm_guide_msg_id: str | None = None
    free_model_guide_msg_id: str | None = None
    auto_play_tts: int | None = None
    apply_list_img: str | None = None


class HomeSet(BaseModel):
    """Public profile/home page configuration.

    Contains bio/intro, media, NSFW level and basic audience preferences.
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    sex: int | None = None
    show_sex: int | None = None
    preference_gender: int | None = None
    intro: str | None = None
    notice: str | None = None
    notice_at: int | None = None
    background_img_nsfw_level: int | None = None
    background_img: str | None = None
    interest_tag: str | None = None
    interest_module: str | None = None
    skip: bool | None = None
    enable_no_download: int | None = None


class OverviewList(BaseModel):
    """Small visibility toggle for an overview section.

    `key` identifies the item, `is_show` controls visibility.
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    key: str | None = None
    obj_type: int | None = None
    is_show: bool | None = None


class AccountInfo(BaseModel):
    """Aggregated account profile and capabilities.

    Combines identity, badges, counters, feature flags and nested settings.

    Notes:
        Many fields mirror upstream API and may be optional or experimental.
        Use nested models (`AccountSettings`, `CharacterSetting`, `HomeSet`)
        where available; unknown fields are preserved but ignored on validation.
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    id: str
    email: str | None = None
    type: str | None = None
    name: str | None = None
    head: str | None = None
    avatar_frame: str | None = None
    owned_avatar_frame: str | None = None
    badges: list[Badge] | None = None
    verified_badges: list[str] | None = None
    create_at: int | None = None
    settings: AccountSettings | None = None
    character_setting: CharacterSetting | None = None
    guide_status: int | None = None
    newbie_guide_status: int | None = None
    colleted_cnt: int | None = None
    following_cnt: int | None = None
    follower_cnt: int | None = None
    num_of_total: int | None = None
    num_of_timbre: int | None = None
    view_cnt: int | None = None
    invite_user_code: str | None = None
    invite_user_num: int | None = None
    review: int | None = None  # idk
    c_home: str | None = None  # idk
    is_model_creator: bool | None = None
    enable_ai: bool | None = None
    enable_gf: bool | None = None
    enable_tavern: bool | None = None
    enable_portfolio: bool | None = None
    enable_video: bool | None = None
    enable_palette: bool | None = None
    is_active: bool | None = None
    enable_nsfw_plus: bool | None = None
    is_studio_beta: bool | None = None
    show_lab: bool | None = None
    payment_conf: str | None = None  # idk
    account_login_channel: int | None = None
    role: str | None = None
    emp_status: int | None = None
    managed_tags: list[str] | None = None  # idk
    collect_tags: list[str] | None = None  # idk
    collect_tag_item: list[str] | None = None  # idk
    post_white: bool | None = None
    apps_flyer_id: str | None = None  # idk
    apps_flyer_adid: str | None = None  # idk
    task_num: int | None = None
    guide_pop: bool | None = None
    character_pop: bool | None = None
    is_audit: int | None = None
    join_stimulate: int | None = None
    system_push: int | None = None
    comment_push: int | None = None
    like_favorite_push: int | None = None
    follow_push: int | None = None
    followed_content_push: int | None = None
    ai_video_auto_play: int | None = None
    enable_comfyui: bool | None = None
    bind_adyen: bool | None = None
    task_expire_day: int | None = None
    app_id: str | None = None
    home_set: HomeSet | None = None
    overview_list: list[OverviewList] | None = None
    can_push_surveys: bool | None = None
    num_of_active: int | None = None
    show_evaluation_guide: bool | None = None
    adv_platform: list[str] | None = None
    can_show_ad: bool | None = None
    login_app: int | None = None
    story_gray: bool | None = None
    is_questionnaire: bool | None = None
    current_country_code: str | None = None
    show_download: bool | None = None
    task_flow_gt: str | None = None
    h5_task_flow_gt: str | None = None
    show_task_v2_guide: bool | None = None
    show_task_v2_guide_for_h5: bool | None = None
    shot_task_v2_preset_meta_popup: bool | None = None
    is_digital_lang_flow: int | None = None
    trial_order_pay_popup: int | None = None
    earnings: int | None = None
    is_show_video_calculate: bool | None = None
    is_interior: bool | None = None
    show_sexy_button: bool | None = None
    show_nexus_button: bool | None = None
    is_pinterest_share_award: int | None = None
    time_zone: str | None = None
    disable_task_v1_switch: bool | None = None
    is_sdk: bool | None = None
    apply_cn_temp_guide_popup: bool | None = None
