# generated by datamodel-codegen:
#   filename:  media_buy/get_media_buy_delivery_response.json
#   timestamp: 2026-02-22T00:26:42+00:00

from __future__ import annotations

from enum import Enum
from typing import Annotated, Any

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

from ..core import attribution_window as attribution_window_1
from ..core import context as context_1
from ..core import error
from ..core import ext as ext_1
from ..core.delivery_metrics import DeliveryMetrics
from ..enums import content_id_type as content_id_type_1
from ..enums import pricing_model as pricing_model_1


class AggregatedTotals(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    clicks: Annotated[
        float | None,
        Field(description='Total clicks across all media buys (if applicable)', ge=0.0),
    ] = None
    conversion_value: Annotated[
        float | None,
        Field(description='Total conversion value across all media buys (if applicable)', ge=0.0),
    ] = None
    conversions: Annotated[
        float | None,
        Field(description='Total conversions across all media buys (if applicable)', ge=0.0),
    ] = None
    cost_per_acquisition: Annotated[
        float | None,
        Field(
            description='Aggregate cost per conversion across all media buys (total spend / total conversions)',
            ge=0.0,
        ),
    ] = None
    impressions: Annotated[
        float, Field(description='Total impressions delivered across all media buys', ge=0.0)
    ]
    media_buy_count: Annotated[
        int, Field(description='Number of media buys included in the response', ge=0)
    ]
    new_to_brand_rate: Annotated[
        float | None,
        Field(
            description='Fraction of total conversions across all media buys from first-time brand buyers (weighted by conversion volume, not a simple average of per-buy rates)',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    roas: Annotated[
        float | None,
        Field(
            description='Aggregate return on ad spend across all media buys (total conversion_value / total spend)',
            ge=0.0,
        ),
    ] = None
    spend: Annotated[float, Field(description='Total amount spent across all media buys', ge=0.0)]
    video_completions: Annotated[
        float | None,
        Field(description='Total video completions across all media buys (if applicable)', ge=0.0),
    ] = None


class DeliveryStatus(Enum):
    delivering = 'delivering'
    completed = 'completed'
    budget_exhausted = 'budget_exhausted'
    flight_ended = 'flight_ended'
    goal_met = 'goal_met'


class DailyBreakdownItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    conversion_value: Annotated[
        float | None, Field(description='Daily conversion value', ge=0.0)
    ] = None
    conversions: Annotated[float | None, Field(description='Daily conversions', ge=0.0)] = None
    date: Annotated[str, Field(description='Date (YYYY-MM-DD)', pattern='^\\d{4}-\\d{2}-\\d{2}$')]
    impressions: Annotated[float, Field(description='Daily impressions', ge=0.0)]
    new_to_brand_rate: Annotated[
        float | None,
        Field(
            description='Daily fraction of conversions from first-time brand buyers (0 = none, 1 = all)',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    roas: Annotated[
        float | None,
        Field(description='Daily return on ad spend (conversion_value / spend)', ge=0.0),
    ] = None
    spend: Annotated[float, Field(description='Daily spend', ge=0.0)]


class Status(Enum):
    pending = 'pending'
    active = 'active'
    paused = 'paused'
    completed = 'completed'
    failed = 'failed'
    reporting_delayed = 'reporting_delayed'


class NotificationType(Enum):
    scheduled = 'scheduled'
    final = 'final'
    delayed = 'delayed'
    adjusted = 'adjusted'


class ReportingPeriod(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    end: Annotated[
        AwareDatetime,
        Field(description='ISO 8601 end timestamp in UTC (e.g., 2024-02-05T23:59:59Z)'),
    ]
    start: Annotated[
        AwareDatetime,
        Field(description='ISO 8601 start timestamp in UTC (e.g., 2024-02-05T00:00:00Z)'),
    ]


class ByCatalogItemItem(DeliveryMetrics):
    content_id: Annotated[
        str, Field(description='Catalog item identifier (e.g., SKU, GTIN, job_id, offering_id)')
    ]
    content_id_type: Annotated[
        content_id_type_1.ContentIdType | None,
        Field(description='Identifier type for this content_id'),
    ] = None
    impressions: Any
    spend: Any


class ByCreativeItem(DeliveryMetrics):
    creative_id: Annotated[
        str, Field(description='Creative identifier matching the creative assignment')
    ]
    weight: Annotated[
        float | None,
        Field(
            description='Observed delivery share for this creative within the package during the reporting period, expressed as a percentage (0-100). Reflects actual delivery distribution, not a configured setting.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    impressions: Any
    spend: Any


class ByPackageItem(DeliveryMetrics):
    buyer_ref: Annotated[
        str | None, Field(description="Buyer's reference identifier for this package")
    ] = None
    by_catalog_item: Annotated[
        list[ByCatalogItemItem] | None,
        Field(
            description='Delivery by catalog item within this package. Available for catalog-driven packages when the seller supports item-level reporting.'
        ),
    ] = None
    by_creative: Annotated[
        list[ByCreativeItem] | None,
        Field(
            description='Metrics broken down by creative within this package. Available when the seller supports creative-level reporting.'
        ),
    ] = None
    currency: Annotated[
        str,
        Field(
            description="ISO 4217 currency code (e.g., USD, EUR, GBP) for this package's pricing. Indicates the currency in which the rate and spend values are denominated. Different packages can use different currencies when supported by the publisher.",
            pattern='^[A-Z]{3}$',
        ),
    ]
    delivery_status: Annotated[
        DeliveryStatus | None,
        Field(
            description='System-reported operational state of this package. Reflects actual delivery state independent of buyer pause control.'
        ),
    ] = None
    pacing_index: Annotated[
        float | None,
        Field(description='Delivery pace (1.0 = on track, <1.0 = behind, >1.0 = ahead)', ge=0.0),
    ] = None
    package_id: Annotated[str, Field(description="Publisher's package identifier")]
    paused: Annotated[
        bool | None, Field(description='Whether this package is currently paused by the buyer')
    ] = None
    pricing_model: Annotated[
        pricing_model_1.PricingModel,
        Field(
            description='The pricing model used for this package (e.g., cpm, cpcv, cpp). Indicates how the package is billed and which metrics are most relevant for optimization.'
        ),
    ]
    rate: Annotated[
        float,
        Field(
            description='The pricing rate for this package in the specified currency. For fixed-rate pricing, this is the agreed rate (e.g., CPM rate of 12.50 means $12.50 per 1,000 impressions). For auction-based pricing, this represents the effective rate based on actual delivery.',
            ge=0.0,
        ),
    ]
    spend: Any


class Totals(DeliveryMetrics):
    effective_rate: Annotated[
        float | None,
        Field(
            description="Effective rate paid per unit based on pricing_model (e.g., actual CPM for 'cpm', actual cost per completed view for 'cpcv', actual cost per point for 'cpp')",
            ge=0.0,
        ),
    ] = None
    spend: Any


class MediaBuyDelivery(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    buyer_ref: Annotated[
        str | None, Field(description="Buyer's reference identifier for this media buy")
    ] = None
    by_package: Annotated[list[ByPackageItem], Field(description='Metrics broken down by package')]
    campaign_ref: Annotated[
        str | None,
        Field(
            description="Buyer's campaign reference label. Groups related operations under a single campaign for CRM and ad server correlation."
        ),
    ] = None
    daily_breakdown: Annotated[
        list[DailyBreakdownItem] | None, Field(description='Day-by-day delivery')
    ] = None
    expected_availability: Annotated[
        AwareDatetime | None,
        Field(
            description='When delayed data is expected to be available (only present when status is reporting_delayed)'
        ),
    ] = None
    is_adjusted: Annotated[
        bool | None,
        Field(
            description='Indicates this delivery contains updated data for a previously reported period. Buyer should replace previous period data with these totals.'
        ),
    ] = None
    media_buy_id: Annotated[str, Field(description="Publisher's media buy identifier")]
    pricing_model: Annotated[
        pricing_model_1.PricingModel | None,
        Field(description='Pricing model used for this media buy'),
    ] = None
    status: Annotated[
        Status,
        Field(
            description='Current media buy status. In webhook context, reporting_delayed indicates data temporarily unavailable.'
        ),
    ]
    totals: Totals


class GetMediaBuyDeliveryResponse(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    aggregated_totals: Annotated[
        AggregatedTotals | None,
        Field(
            description='Combined metrics across all returned media buys. Only included in API responses (get_media_buy_delivery), not in webhook notifications.'
        ),
    ] = None
    attribution_window: Annotated[
        attribution_window_1.AttributionWindow | None,
        Field(
            description='Attribution methodology and lookback windows used for conversion metrics in this response. All media buys from a single seller share the same attribution methodology. Enables cross-platform comparison (e.g., Amazon 14-day click vs. Criteo 30-day click).'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')]
    errors: Annotated[
        list[error.Error] | None,
        Field(
            description='Task-specific errors and warnings (e.g., missing delivery data, reporting platform issues)'
        ),
    ] = None
    ext: ext_1.ExtensionObject | None = None
    media_buy_deliveries: Annotated[
        list[MediaBuyDelivery],
        Field(
            description='Array of delivery data for media buys. When used in webhook notifications, may contain multiple media buys aggregated by publisher. When used in get_media_buy_delivery API responses, typically contains requested media buys.'
        ),
    ]
    next_expected_at: Annotated[
        AwareDatetime | None,
        Field(
            description="ISO 8601 timestamp for next expected notification (only present in webhook deliveries when notification_type is not 'final')"
        ),
    ] = None
    notification_type: Annotated[
        NotificationType | None,
        Field(
            description='Type of webhook notification (only present in webhook deliveries): scheduled = regular periodic update, final = campaign completed, delayed = data not yet available, adjusted = resending period with updated data'
        ),
    ] = None
    partial_data: Annotated[
        bool | None,
        Field(
            description='Indicates if any media buys in this webhook have missing/delayed data (only present in webhook deliveries)'
        ),
    ] = None
    reporting_period: Annotated[
        ReportingPeriod,
        Field(description='Date range for the report. All periods use UTC timezone.'),
    ]
    sandbox: Annotated[
        bool | None,
        Field(description='When true, this response contains simulated data from sandbox mode.'),
    ] = None
    sequence_number: Annotated[
        int | None,
        Field(
            description='Sequential notification number (only present in webhook deliveries, starts at 1)',
            ge=1,
        ),
    ] = None
    unavailable_count: Annotated[
        int | None,
        Field(
            description='Number of media buys with reporting_delayed or failed status (only present in webhook deliveries when partial_data is true)',
            ge=0,
        ),
    ] = None
