# generated by datamodel-codegen:
#   filename:  core/product.json
#   timestamp: 2025-11-22T19:54:03+00:00

from __future__ import annotations

from typing import Annotated, Any

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

from ..enums import delivery_type as delivery_type_1
from ..pricing_options import (
    cpc_option,
    cpcv_option,
    cpm_auction_option,
    cpm_fixed_option,
    cpp_option,
    cpv_option,
    flat_rate_option,
    vcpm_auction_option,
    vcpm_fixed_option,
)
from . import creative_policy as creative_policy_1
from . import ext as ext_1
from . import format_id as format_id_1
from . import measurement as measurement_1
from . import placement, publisher_property_selector
from . import reporting_capabilities as reporting_capabilities_1


class DeliveryMeasurement(AdCPBaseModel):
    notes: Annotated[
        str | None,
        Field(
            description="Additional details about measurement methodology in plain language (e.g., 'MRC-accredited viewability. 50% in-view for 1s display / 2s video', 'Panel-based demographic measurement updated monthly')"
        ),
    ] = None
    provider: Annotated[
        str,
        Field(
            description="Measurement provider(s) used for this product (e.g., 'Google Ad Manager with IAS viewability', 'Nielsen DAR', 'Geopath for DOOH impressions')"
        ),
    ]


class ProductCard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    format_id: Annotated[
        format_id_1.FormatId,
        Field(
            description='Creative format defining the card layout (typically product_card_standard)'
        ),
    ]
    manifest: Annotated[
        dict[str, Any],
        Field(description='Asset manifest for rendering the card, structure defined by the format'),
    ]


class ProductCardDetailed(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    format_id: Annotated[
        format_id_1.FormatId,
        Field(
            description='Creative format defining the detailed card layout (typically product_card_detailed)'
        ),
    ]
    manifest: Annotated[
        dict[str, Any],
        Field(
            description='Asset manifest for rendering the detailed card, structure defined by the format'
        ),
    ]


class Product(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    brief_relevance: Annotated[
        str | None,
        Field(
            description='Explanation of why this product matches the brief (only included when brief is provided)'
        ),
    ] = None
    creative_policy: creative_policy_1.CreativePolicy | None = None
    delivery_measurement: Annotated[
        DeliveryMeasurement,
        Field(
            description='Measurement provider and methodology for delivery metrics. The buyer accepts the declared provider as the source of truth for the buy. REQUIRED for all products.'
        ),
    ]
    delivery_type: delivery_type_1.DeliveryType
    description: Annotated[
        str, Field(description='Detailed description of the product and its inventory')
    ]
    estimated_exposures: Annotated[
        int | None,
        Field(description='Estimated exposures/impressions for guaranteed products', ge=0),
    ] = None
    expires_at: Annotated[
        AwareDatetime | None, Field(description='Expiration timestamp for custom products')
    ] = None
    ext: ext_1.ExtensionObject | None = None
    format_ids: Annotated[
        list[format_id_1.FormatId],
        Field(
            description='Array of supported creative format IDs - structured format_id objects with agent_url and id'
        ),
    ]
    is_custom: Annotated[bool | None, Field(description='Whether this is a custom product')] = None
    measurement: measurement_1.Measurement | None = None
    name: Annotated[str, Field(description='Human-readable product name')]
    placements: Annotated[
        list[placement.Placement] | None,
        Field(
            description='Optional array of specific placements within this product. When provided, buyers can target specific placements when assigning creatives.',
            min_length=1,
        ),
    ] = None
    pricing_options: Annotated[
        list[
            cpm_fixed_option.CpmFixedRatePricingOption
            | cpm_auction_option.CpmAuctionPricingOption
            | vcpm_fixed_option.VcpmFixedRatePricingOption
            | vcpm_auction_option.VcpmAuctionPricingOption
            | cpc_option.CpcPricingOption
            | cpcv_option.CpcvPricingOption
            | cpv_option.CpvPricingOption
            | cpp_option.CppPricingOption
            | flat_rate_option.FlatRatePricingOption
        ],
        Field(description='Available pricing models for this product', min_length=1),
    ]
    product_card: Annotated[
        ProductCard | None,
        Field(
            description='Optional standard visual card (300x400px) for displaying this product in user interfaces. Can be rendered via preview_creative or pre-generated.'
        ),
    ] = None
    product_card_detailed: Annotated[
        ProductCardDetailed | None,
        Field(
            description='Optional detailed card with carousel and full specifications. Provides rich product presentation similar to media kit pages.'
        ),
    ] = None
    product_id: Annotated[str, Field(description='Unique identifier for the product')]
    publisher_properties: Annotated[
        list[
            publisher_property_selector.PublisherPropertySelector1
            | publisher_property_selector.PublisherPropertySelector2
            | publisher_property_selector.PublisherPropertySelector3
        ],
        Field(
            description="Publisher properties covered by this product. Buyers fetch actual property definitions from each publisher's adagents.json and validate agent authorization. Selection patterns mirror the authorization patterns in adagents.json for consistency.",
            min_length=1,
        ),
    ]
    reporting_capabilities: reporting_capabilities_1.ReportingCapabilities | None = None
