# generated by datamodel-codegen:
#   filename:  media_buy/create_media_buy_request.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 AnyUrl, AwareDatetime, ConfigDict, Field

from ..core import account_ref, brand_ref
from ..core import context as context_1
from ..core import ext as ext_1
from ..core import push_notification_config as push_notification_config_1
from ..core import reporting_webhook as reporting_webhook_1
from ..core import start_timing
from ..enums import auth_scheme
from . import package_request


class Authentication(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    credentials: Annotated[
        str,
        Field(
            description='Credentials for authentication. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.',
            min_length=32,
        ),
    ]
    schemes: Annotated[
        list[auth_scheme.AuthenticationScheme],
        Field(
            description="Array of authentication schemes. Supported: ['Bearer'] for simple token auth, ['HMAC-SHA256'] for signature verification (recommended for production)",
            max_length=1,
            min_length=1,
        ),
    ]


class BatchFrequency(Enum):
    hourly = 'hourly'
    daily = 'daily'


class DeliveryMode(Enum):
    realtime = 'realtime'
    batched = 'batched'


class ArtifactWebhook(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    authentication: Annotated[
        Authentication,
        Field(description='Authentication configuration for webhook delivery (A2A-compatible)'),
    ]
    batch_frequency: Annotated[
        BatchFrequency | None,
        Field(
            description="For batched delivery, how often to push artifacts. Required when delivery_mode is 'batched'."
        ),
    ] = None
    delivery_mode: Annotated[
        DeliveryMode,
        Field(
            description="How artifacts are delivered. 'realtime' pushes artifacts as impressions occur. 'batched' aggregates artifacts and pushes periodically (see batch_frequency)."
        ),
    ]
    sampling_rate: Annotated[
        float | None,
        Field(
            description='Fraction of impressions to include (0-1). 1.0 = all impressions, 0.1 = 10% sample. Default: 1.0',
            ge=0.0,
            le=1.0,
        ),
    ] = None
    token: Annotated[
        str | None,
        Field(
            description='Optional client-provided token for webhook validation. Echoed back in webhook payload to validate request authenticity.',
            min_length=16,
        ),
    ] = None
    url: Annotated[AnyUrl, Field(description='Webhook endpoint URL for artifact delivery')]


class TotalBudget(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    amount: Annotated[float, Field(description='Total budget amount', ge=0.0)]
    currency: Annotated[str, Field(description='ISO 4217 currency code')]


class CreateMediaBuyRequest(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    account: Annotated[
        account_ref.AccountReference,
        Field(
            description='Account to bill for this media buy. Pass an account_id from list_accounts (explicit model), or use a natural key (brand, operator) if the seller supports implicit_from_sync resolution.'
        ),
    ]
    artifact_webhook: Annotated[
        ArtifactWebhook | None,
        Field(
            description='Optional webhook configuration for content artifact delivery. Used by governance agents to validate content adjacency. Seller pushes artifacts to this endpoint; orchestrator forwards to governance agent for validation.'
        ),
    ] = None
    brand: Annotated[
        brand_ref.BrandReference,
        Field(
            description='Brand reference for this media buy. Resolved to full brand identity at execution time from brand.json or the registry.'
        ),
    ]
    buyer_campaign_ref: Annotated[
        str | None,
        Field(
            description="Buyer's campaign reference label. Groups related discovery and buy operations under a single campaign for CRM and ad server correlation (e.g., 'NovaDrink_Meals_Q2')."
        ),
    ] = None
    buyer_ref: Annotated[
        str,
        Field(
            description="Buyer's reference identifier for this media buy. Also serves as an idempotency key: sellers SHOULD deduplicate requests with the same buyer_ref and account, returning the existing media buy rather than creating a duplicate."
        ),
    ]
    context: context_1.ContextObject | None = None
    end_time: Annotated[
        AwareDatetime, Field(description='Campaign end date/time in ISO 8601 format')
    ]
    ext: ext_1.ExtensionObject | None = None
    packages: Annotated[
        list[package_request.PackageRequest] | None,
        Field(
            description="Array of package configurations. Required when not using proposal_id. When executing a proposal, this can be omitted and packages will be derived from the proposal's allocations.",
            min_length=1,
        ),
    ] = None
    po_number: Annotated[str | None, Field(description='Purchase order number for tracking')] = None
    proposal_id: Annotated[
        str | None,
        Field(
            description="ID of a proposal from get_products to execute. When provided with total_budget, the publisher converts the proposal's allocation percentages into packages automatically. Alternative to providing packages array."
        ),
    ] = None
    push_notification_config: Annotated[
        push_notification_config_1.PushNotificationConfig | None,
        Field(
            description='Optional webhook configuration for async task status notifications. Publisher will send webhooks when status changes (working, input-required, completed, failed). The client generates an operation_id and embeds it in the URL before sending — the publisher echoes it back in webhook payloads for correlation.'
        ),
    ] = None
    reporting_webhook: Annotated[
        reporting_webhook_1.ReportingWebhook | None,
        Field(description='Optional webhook configuration for automated reporting delivery'),
    ] = None
    start_time: start_timing.StartTiming
    total_budget: Annotated[
        TotalBudget | None,
        Field(
            description="Total budget for the media buy when executing a proposal. The publisher applies the proposal's allocation percentages to this amount to derive package budgets."
        ),
    ] = None
