# generated by datamodel-codegen:
#   filename:  media_buy/get_products_response.json
#   timestamp: 2026-02-28T17:39:50+00:00

from __future__ import annotations

from enum import Enum
from typing import Annotated

from adcp.types.base import AdCPBaseModel
from pydantic import ConfigDict, Field

from ..core import context as context_1
from ..core import error
from ..core import ext as ext_1
from ..core import pagination_response
from ..core import product as product_1
from ..core import proposal as proposal_1


class Scope(Enum):
    request = 'request'
    product = 'product'
    proposal = 'proposal'


class Status(Enum):
    applied = 'applied'
    partial = 'partial'
    unable = 'unable'


class RefinementAppliedItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    id: Annotated[
        str | None,
        Field(
            description='Echoes the id from the corresponding refine entry (for product and proposal scopes).'
        ),
    ] = None
    notes: Annotated[
        str | None,
        Field(
            description="Seller explanation of what was done, what couldn't be done, or why. Recommended when status is 'partial' or 'unable'."
        ),
    ] = None
    scope: Annotated[
        Scope | None,
        Field(
            description='Echoes the scope from the corresponding refine entry. Allows orchestrators to cross-validate alignment.'
        ),
    ] = None
    status: Annotated[
        Status,
        Field(
            description="'applied': the ask was fulfilled. 'partial': the ask was partially fulfilled — see notes for details. 'unable': the seller could not fulfill the ask — see notes for why."
        ),
    ]


class GetProductsResponse(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_applied: Annotated[
        bool | None,
        Field(
            description='Whether the seller filtered results based on the provided catalog. True if the seller matched catalog items against its inventory. Absent or false if no catalog was provided or the seller does not support catalog matching.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    errors: Annotated[
        list[error.Error] | None,
        Field(description='Task-specific errors and warnings (e.g., product filtering issues)'),
    ] = None
    ext: ext_1.ExtensionObject | None = None
    pagination: pagination_response.PaginationResponse | None = None
    products: Annotated[list[product_1.Product], Field(description='Array of matching products')]
    property_list_applied: Annotated[
        bool | None,
        Field(
            description='[AdCP 3.0] Indicates whether property_list filtering was applied. True if the agent filtered products based on the provided property_list. Absent or false if property_list was not provided or not supported by this agent.'
        ),
    ] = None
    proposals: Annotated[
        list[proposal_1.Proposal] | None,
        Field(
            description='Optional array of proposed media plans with budget allocations across products. Publishers include proposals when they can provide strategic guidance based on the brief. Proposals are actionable - buyers can refine them via follow-up get_products calls within the same session, or execute them directly via create_media_buy.'
        ),
    ] = None
    refinement_applied: Annotated[
        list[RefinementAppliedItem] | None,
        Field(
            description="Seller's response to each change request in the refine array, matched by position. Each entry acknowledges whether the corresponding ask was applied, partially applied, or unable to be fulfilled. MUST contain the same number of entries in the same order as the request's refine array. Only present when the request used buying_mode: 'refine'."
        ),
    ] = None
    sandbox: Annotated[
        bool | None,
        Field(description='When true, this response contains simulated data from sandbox mode.'),
    ] = None
