from __future__ import annotations

from typing import Literal, NotRequired, TypedDict

PublicMethod = Literal[
    "messages.list", "marketing.funnel", "leads.list", "pipelines.list",
    "pipelines.get", "stages.list", "tasks.list", "tasks.get",
    "products.list", "products.search", "products.get", "products.brands",
    "products.categories", "shop.banners.list", "shop.frete.config",
    "shop.frete.calcular", "shop.desconto.validar", "shop.loja.config",
]


class MessagesListRequest(TypedDict):
    conversation_id: str
    limit: NotRequired[int]
    before: NotRequired[str]


class LeadsListRequest(TypedDict, total=False):
    status: Literal["new", "converted", "junk"]
    status_in: list[str] | str
    search: str
    assigned_to: str
    assigned_to_in: list[str] | str
    source_id_in: list[int] | str
    created_from: str
    created_to: str
    junked_from: str
    junked_to: str
    converted_from: str
    converted_to: str
    opportunity_min: float
    opportunity_max: float
    has_conversation: bool
    page: int
    limit: int
    order_by: Literal["created_at_desc", "created_at_asc", "opportunity_desc", "opportunity_asc", "name_asc"]


class PipelinesListRequest(TypedDict, total=False):
    pipeline_id: int


class PipelinesGetRequest(TypedDict):
    id: int


class StagesListRequest(TypedDict):
    pipeline_id: int


class TasksListRequest(TypedDict, total=False):
    owner_type: Literal["deal", "contact", "lead"]
    owner_id: int
    completed: bool
    responsible_id: str | None
    overdue: bool
    page: int
    limit: int


class TasksGetRequest(TypedDict):
    id: int


class ProductsQueryRequest(TypedDict, total=False):
    q: str
    marca: str
    categoria: str
    familia: str
    tag: str
    preco_min: float
    preco_max: float
    order: Literal["nome", "preco_asc", "preco_desc", "estoque"]
    offset: int
    limit: int


class ProductsGetRequest(TypedDict, total=False):
    codigo: str
    sku: str


class ShopItem(TypedDict, total=False):
    sku: str
    codigo: str
    qtd: int
    quantidade: int


class ShopBannersListRequest(TypedDict, total=False):
    slot: str


class ShopFreteCalcularRequest(TypedDict):
    cep: str
    itens: list[ShopItem] | str


class ShopCustomer(TypedDict, total=False):
    cpf: str
    cpf_cnpj: str
    email: str


class ShopDescontoValidarRequest(TypedDict):
    itens: list[ShopItem] | str
    codigo: NotRequired[str]
    frete_cents: NotRequired[int]
    cliente: NotRequired[ShopCustomer]


MarketingFunnelRequest = TypedDict(
    "MarketingFunnelRequest",
    {"from": str, "to": str, "pipeline_id": int},
)


class MessageRecord(TypedDict, total=False):
    id: str
    sender_type: str
    content: str | None
    message_type: str
    media_url: str | None
    delivery_status: str | None
    created_at: str | None
    delivered_at: str | None
    read_at: str | None


class MessagesListResult(TypedDict):
    total: int
    total_count: int
    messages: list[MessageRecord]
    hasMore: bool
    next_cursor: str | None


class LeadRecord(TypedDict, total=False):
    id: int
    name: str
    status: str
    opportunity: str | float | None
    phone: list[dict[str, object]]
    email: list[dict[str, object]]


class LeadsListResult(TypedDict):
    rows: list[LeadRecord]
    total: int
    by_status: dict[str, int]
    page: int
    limit: int


class StageRecord(TypedDict, total=False):
    id: int
    pipeline_id: int
    name: str
    slug: str
    type: str
    color: str
    sort_order: int
    deals_count: int
    open_count: int
    deals_value: float


class PipelineRecord(TypedDict, total=False):
    id: int
    name: str
    slug: str
    is_default: bool
    type: str
    color: str
    sort_order: int
    total_deals: int
    total_value: float
    stages: list[StageRecord]


class PipelinesListResult(TypedDict):
    total: int
    pipelines: list[PipelineRecord]


class PipelinesGetResult(TypedDict):
    found: bool
    pipeline: NotRequired[PipelineRecord | None]


class StagesListResult(TypedDict):
    total: int
    stages: list[StageRecord]


class TaskRecord(TypedDict, total=False):
    id: int
    owner_type: str
    owner_id: int
    type: str
    subject: str
    completed: bool
    responsible_id: str | None
    deadline: str | None
    responsible_name: str | None


class TasksListResult(TypedDict):
    total: int
    tasks: list[TaskRecord]


class TasksGetResult(TypedDict):
    found: bool
    task: NotRequired[TaskRecord | None]


class ProductRecord(TypedDict, total=False):
    id: str
    nome: str
    codigo: str
    idCatalogo: str | None
    marca: str | None
    categoria: str | None
    imagemThumb: str | None
    imagens: list[str]
    imagensCount: int
    specs: dict[str, object]
    preco_venda: float | None
    estoque: float | None
    reservado: float | None
    disponivel_qtd: float | None
    disponivel: bool
    motivo_indisponivel: str | None
    descricao: str | None


class ProductsListResult(TypedDict):
    items: list[ProductRecord]
    total: int
    next_cursor: str | None


class ProductsGetResult(TypedDict):
    product: ProductRecord | None


class ProductsBrandsResult(TypedDict):
    marcas: list[dict[str, object]]


class ProductsCategoriesResult(TypedDict):
    categorias: list[dict[str, object]]


class ShopBannersListResult(TypedDict, total=False):
    banners: list[dict[str, object]]
    carrossel: dict[str, object] | None


class ShopFreteConfigResult(TypedDict, total=False):
    retirada: dict[str, object] | None
    entrega_local: dict[str, object] | None
    datas_estimadas: bool
    origem: dict[str, object] | None


class ShopFreteCalcularResult(TypedDict, total=False):
    cep: str
    uf: str | None
    opcoes: list[dict[str, object]]
    retirada: dict[str, object] | None
    entrega_local: dict[str, object] | None
    motivo: str | None
    itens_sem_frete: list[object]
    peso_incompleto: bool


class ShopDescontoValidarResult(TypedDict, total=False):
    descontos: list[dict[str, object]]
    valor_cents: int
    frete_gratis: bool
    frete_desconto_cents: int
    valor: float
    recusa: str | None


class ShopLojaConfigResult(TypedDict, total=False):
    nome: str
    logo_url: str | None
    descricao: str | None
    cores: dict[str, object]
    contato: dict[str, object]
    completa: bool


MarketingFunnelResult = TypedDict(
    "MarketingFunnelResult",
    {
        "company_id": str,
        "from": str,
        "to": str,
        "generated_at": str,
        "days": list[dict[str, object]],
        "stalled": dict[str, object],
        "pipelines": list[dict[str, object]],
    },
    total=False,
)
