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

from __future__ import annotations

from typing import Annotated

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

from ..core import account_ref
from ..core import context as context_1
from ..core import duration
from ..core import ext as ext_1
from ..enums import attribution_model
from ..enums import geo_level as geo_level_1
from ..enums import media_buy_status, metro_system, postal_system, sort_metric


class AttributionWindow(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    model: Annotated[
        attribution_model.AttributionModel | None,
        Field(
            description='Attribution model to use. When omitted, the seller applies their default model.'
        ),
    ] = None
    post_click: Annotated[
        duration.Duration | None, Field(description='Post-click attribution window to apply.')
    ] = None
    post_view: Annotated[
        duration.Duration | None, Field(description='Post-view attribution window to apply.')
    ] = None


class Audience(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    limit: Annotated[
        int | None, Field(description='Maximum number of entries to return. Defaults to 25.', ge=1)
    ] = 25
    sort_by: Annotated[
        sort_metric.SortMetric | None,
        Field(
            description="Metric to sort breakdown rows by (descending). Falls back to 'spend' if the seller does not report the requested metric."
        ),
    ] = sort_metric.SortMetric.spend


class DevicePlatform(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    limit: Annotated[
        int | None,
        Field(
            description='Maximum number of entries to return. When omitted, all entries are returned (the enum is small and bounded).',
            ge=1,
        ),
    ] = None
    sort_by: Annotated[
        sort_metric.SortMetric | None,
        Field(
            description="Metric to sort breakdown rows by (descending). Falls back to 'spend' if the seller does not report the requested metric."
        ),
    ] = sort_metric.SortMetric.spend


class DeviceType(DevicePlatform):
    pass


class Geo(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    geo_level: Annotated[
        geo_level_1.GeographicTargetingLevel,
        Field(description='Geographic granularity level for the breakdown'),
    ]
    limit: Annotated[
        int | None,
        Field(
            description='Maximum number of geo entries to return. Defaults to 25. When truncated, by_geo_truncated is true in the response.',
            ge=1,
        ),
    ] = 25
    sort_by: Annotated[
        sort_metric.SortMetric | None,
        Field(
            description="Metric to sort breakdown rows by (descending). Falls back to 'spend' if the seller does not report the requested metric."
        ),
    ] = sort_metric.SortMetric.spend
    system: Annotated[
        metro_system.MetroAreaSystem | postal_system.PostalCodeSystem | None,
        Field(
            description="Classification system for metro or postal_area levels (e.g., 'nielsen_dma', 'us_zip'). Required when geo_level is 'metro' or 'postal_area'."
        ),
    ] = None


class Placement(Audience):
    pass


class ReportingDimensions(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    audience: Annotated[
        Audience | None, Field(description='Request audience segment breakdown.')
    ] = None
    device_platform: Annotated[
        DevicePlatform | None, Field(description='Request device platform breakdown.')
    ] = None
    device_type: Annotated[
        DeviceType | None, Field(description='Request device type breakdown.')
    ] = None
    geo: Annotated[
        Geo | None,
        Field(
            description='Request geographic breakdown. Check reporting_capabilities.supports_geo_breakdown for available levels and systems.'
        ),
    ] = None
    placement: Annotated[Placement | None, Field(description='Request placement breakdown.')] = None


class StatusFilter(RootModel[list[media_buy_status.MediaBuyStatus]]):
    root: Annotated[
        list[media_buy_status.MediaBuyStatus],
        Field(
            description='Filter by status. Can be a single status or array of statuses',
            min_length=1,
        ),
    ]


class GetMediaBuyDeliveryRequest(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Filter delivery data to a specific account. When omitted, returns data across all accessible accounts.'
        ),
    ] = None
    attribution_window: Annotated[
        AttributionWindow | None,
        Field(
            description='Attribution window to apply for conversion metrics. When provided, the seller returns conversion data using the requested lookback windows instead of their platform default. The seller echoes the applied window in the response. Sellers that do not support configurable windows ignore this field and return their default. Check get_adcp_capabilities conversion_tracking.attribution_windows for available options.'
        ),
    ] = None
    buyer_refs: Annotated[
        list[str] | None,
        Field(description='Array of buyer reference IDs to get delivery data for', min_length=1),
    ] = None
    context: context_1.ContextObject | None = None
    end_date: Annotated[
        str | None,
        Field(
            description="End date for reporting period (YYYY-MM-DD). When omitted along with start_date, returns campaign lifetime data. Only accepted when the product's reporting_capabilities.date_range_support is 'date_range'.",
            pattern='^\\d{4}-\\d{2}-\\d{2}$',
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None
    include_package_daily_breakdown: Annotated[
        bool | None,
        Field(
            description='When true, include daily_breakdown arrays within each package in by_package. Useful for per-package pacing analysis and line-item monitoring. Omit or set false to reduce response size — package daily data can be large for multi-package buys over long flights.'
        ),
    ] = False
    media_buy_ids: Annotated[
        list[str] | None,
        Field(
            description='Array of publisher media buy IDs to get delivery data for', min_length=1
        ),
    ] = None
    reporting_dimensions: Annotated[
        ReportingDimensions | None,
        Field(
            description='Request dimensional breakdowns in delivery reporting. Each key enables a specific breakdown dimension within by_package — include as an empty object (e.g., "device_type": {}) to activate with defaults. Omit entirely for no breakdowns (backward compatible). Unsupported dimensions are silently omitted from the response. Note: keyword, catalog_item, and creative breakdowns are returned automatically when the seller supports them and are not controlled by this object.'
        ),
    ] = None
    start_date: Annotated[
        str | None,
        Field(
            description="Start date for reporting period (YYYY-MM-DD). When omitted along with end_date, returns campaign lifetime data. Only accepted when the product's reporting_capabilities.date_range_support is 'date_range'.",
            pattern='^\\d{4}-\\d{2}-\\d{2}$',
        ),
    ] = None
    status_filter: Annotated[
        media_buy_status.MediaBuyStatus | StatusFilter | None,
        Field(description='Filter by status. Can be a single status or array of statuses'),
    ] = None
