# generated by datamodel-codegen:
#   filename:  media_buy/get_media_buy_delivery_response.json
#   timestamp: 2026-01-08T19:25:24+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 context as context_1
from ..core import error
from ..core import ext as ext_1
from ..core.delivery_metrics import DeliveryMetrics
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
    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)
    ]
    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',
    )
    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)]
    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 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 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 ByPackageItem(DeliveryMetrics):
    buyer_ref: Annotated[
        str | None, Field(description="Buyer's reference identifier for this package")
    ] = 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 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')]
    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
    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.'),
    ]
    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
