"""
Auto-generated Pydantic models from AdCP JSON schemas.

DO NOT EDIT THIS FILE MANUALLY.
Generated from: https://adcontextprotocol.org/schemas/v1/
To regenerate:
  python scripts/sync_schemas.py
  python scripts/fix_schema_refs.py
  python scripts/generate_models_simple.py
"""

from __future__ import annotations

from typing import Any, Literal

from pydantic import BaseModel, Field

# Import all types from generated module
from adcp.types.generated import (
    BrandManifestRef,
    Channels,
    CreativeAsset,
    CreativeManifest,
    Error,
    Format,
    FormatId,
    PackageRequest,
    Product,
    PushNotificationConfig,
    StartTiming,
)


class ActivateSignalRequest(BaseModel):
    """Request parameters for activating a signal on a specific platform/account"""

    signal_agent_segment_id: str = Field(
        description="The universal identifier for the signal to activate"
    )
    platform: str = Field(description="The target platform for activation")
    account: str | None = Field(
        None, description="Account identifier (required for account-specific activation)"
    )


class BuildCreativeRequest(BaseModel):
    """Request to transform or generate a creative manifest. Takes a source manifest (which may be minimal for pure generation) and produces a target manifest in the specified format. The source manifest should include all assets required by the target format (e.g., promoted_offerings for generative formats)."""

    message: str | None = Field(
        None,
        description="Natural language instructions for the transformation or generation. For pure generation, this is the creative brief. For transformation, this provides guidance on how to adapt the creative.",
    )
    creative_manifest: CreativeManifest | None = Field(
        None,
        description="Creative manifest to transform or generate from. For pure generation, this should include the target format_id and any required input assets (e.g., promoted_offerings for generative formats). For transformation (e.g., resizing, reformatting), this is the complete creative to adapt.",
    )
    target_format_id: FormatId = Field(
        description="Format ID to generate. The format definition specifies required input assets and output structure."
    )


class CreateMediaBuyRequest(BaseModel):
    """Request parameters for creating a media buy"""

    buyer_ref: str = Field(description="Buyer's reference identifier for this media buy")
    packages: list[PackageRequest] = Field(description="Array of package configurations")
    brand_manifest: BrandManifestRef = Field(
        description="Brand information manifest serving as the namespace and identity for this media buy. Provides brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest. Can be cached and reused across multiple requests."
    )
    po_number: str | None = Field(None, description="Purchase order number for tracking")
    start_time: StartTiming
    end_time: str = Field(description="Campaign end date/time in ISO 8601 format")
    reporting_webhook: Any | None = None


class GetMediaBuyDeliveryRequest(BaseModel):
    """Request parameters for retrieving comprehensive delivery metrics"""

    media_buy_ids: list[str] | None = Field(
        None, description="Array of publisher media buy IDs to get delivery data for"
    )
    buyer_refs: list[str] | None = Field(
        None, description="Array of buyer reference IDs to get delivery data for"
    )
    status_filter: Any | None = Field(
        None, description="Filter by status. Can be a single status or array of statuses"
    )
    start_date: str | None = Field(None, description="Start date for reporting period (YYYY-MM-DD)")
    end_date: str | None = Field(None, description="End date for reporting period (YYYY-MM-DD)")


class GetProductsRequest(BaseModel):
    """Request parameters for discovering available advertising products"""

    brief: str | None = Field(
        None, description="Natural language description of campaign requirements"
    )
    brand_manifest: BrandManifestRef | None = Field(
        None,
        description="Brand information manifest providing brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest.",
    )
    filters: dict[str, Any] | None = Field(
        None, description="Structured filters for product discovery"
    )


class GetSignalsRequest(BaseModel):
    """Request parameters for discovering signals based on description"""

    signal_spec: str = Field(description="Natural language description of the desired signals")
    deliver_to: dict[str, Any] = Field(description="Where the signals need to be delivered")
    filters: dict[str, Any] | None = Field(None, description="Filters to refine results")
    max_results: int | None = Field(None, description="Maximum number of results to return")


class ListAuthorizedPropertiesRequest(BaseModel):
    """Request parameters for discovering which publishers this agent is authorized to represent"""

    publisher_domains: list[str] | None = Field(
        None,
        description="Filter to specific publisher domains (optional). If omitted, returns all publishers this agent represents.",
    )


class ListCreativeFormatsRequest(BaseModel):
    """Request parameters for discovering creative formats provided by this creative agent"""

    format_ids: list[FormatId] | None = Field(
        None, description="Return only these specific format IDs"
    )
    type: Literal["audio", "video", "display", "dooh"] | None = Field(
        None, description="Filter by format type (technical categories with distinct requirements)"
    )
    asset_types: (
        list[Literal["image", "video", "audio", "text", "html", "javascript", "url"]] | None
    ) = Field(
        None,
        description="Filter to formats that include these asset types. For third-party tags, search for 'html' or 'javascript'. E.g., ['image', 'text'] returns formats with images and text, ['javascript'] returns formats accepting JavaScript tags.",
    )
    max_width: int | None = Field(
        None,
        description="Maximum width in pixels (inclusive). Returns formats with width <= this value. Omit for responsive/fluid formats.",
    )
    max_height: int | None = Field(
        None,
        description="Maximum height in pixels (inclusive). Returns formats with height <= this value. Omit for responsive/fluid formats.",
    )
    min_width: int | None = Field(
        None,
        description="Minimum width in pixels (inclusive). Returns formats with width >= this value.",
    )
    min_height: int | None = Field(
        None,
        description="Minimum height in pixels (inclusive). Returns formats with height >= this value.",
    )
    is_responsive: bool | None = Field(
        None,
        description="Filter for responsive formats that adapt to container size. When true, returns formats without fixed dimensions.",
    )
    name_search: str | None = Field(
        None, description="Search for formats by name (case-insensitive partial match)"
    )


class ListCreativesRequest(BaseModel):
    """Request parameters for querying creative assets from the centralized library with filtering, sorting, and pagination"""

    filters: dict[str, Any] | None = Field(
        None, description="Filter criteria for querying creatives"
    )
    sort: dict[str, Any] | None = Field(None, description="Sorting parameters")
    pagination: dict[str, Any] | None = Field(None, description="Pagination parameters")
    include_assignments: bool | None = Field(
        None, description="Include package assignment information in response"
    )
    include_performance: bool | None = Field(
        None, description="Include aggregated performance metrics in response"
    )
    include_sub_assets: bool | None = Field(
        None, description="Include sub-assets (for carousel/native formats) in response"
    )
    fields: (
        list[
            Literal[
                "creative_id",
                "name",
                "format",
                "status",
                "created_date",
                "updated_date",
                "tags",
                "assignments",
                "performance",
                "sub_assets",
            ]
        ]
        | None
    ) = Field(None, description="Specific fields to include in response (omit for all fields)")


class PreviewCreativeRequest(BaseModel):
    """Request to generate a preview of a creative manifest in a specific format. The creative_manifest should include all assets required by the format (e.g., promoted_offerings for generative formats)."""

    format_id: FormatId = Field(description="Format identifier for rendering the preview")
    creative_manifest: CreativeManifest = Field(
        description="Complete creative manifest with all required assets (including promoted_offerings if required by the format)"
    )
    inputs: list[dict[str, Any]] | None = Field(
        None,
        description="Array of input sets for generating multiple preview variants. Each input set defines macros and context values for one preview rendering. If not provided, creative agent will generate default previews.",
    )
    template_id: str | None = Field(
        None, description="Specific template ID for custom format rendering"
    )


class ProvidePerformanceFeedbackRequest(BaseModel):
    """Request payload for provide_performance_feedback task"""

    media_buy_id: str = Field(description="Publisher's media buy identifier")
    measurement_period: dict[str, Any] = Field(
        description="Time period for performance measurement"
    )
    performance_index: float = Field(
        description="Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)"
    )
    package_id: str | None = Field(
        None, description="Specific package within the media buy (if feedback is package-specific)"
    )
    creative_id: str | None = Field(
        None, description="Specific creative asset (if feedback is creative-specific)"
    )
    metric_type: (
        Literal[
            "overall_performance",
            "conversion_rate",
            "brand_lift",
            "click_through_rate",
            "completion_rate",
            "viewability",
            "brand_safety",
            "cost_efficiency",
        ]
        | None
    ) = Field(None, description="The business metric being measured")
    feedback_source: (
        Literal[
            "buyer_attribution",
            "third_party_measurement",
            "platform_analytics",
            "verification_partner",
        ]
        | None
    ) = Field(None, description="Source of the performance data")


class SyncCreativesRequest(BaseModel):
    """Request parameters for syncing creative assets with upsert semantics - supports bulk operations, patch updates, and assignment management"""

    creatives: list[CreativeAsset] = Field(
        description="Array of creative assets to sync (create or update)"
    )
    patch: bool | None = Field(
        None,
        description="When true, only provided fields are updated (partial update). When false, entire creative is replaced (full upsert).",
    )
    assignments: dict[str, Any] | None = Field(
        None, description="Optional bulk assignment of creatives to packages"
    )
    delete_missing: bool | None = Field(
        None,
        description="When true, creatives not included in this sync will be archived. Use with caution for full library replacement.",
    )
    dry_run: bool | None = Field(
        None,
        description="When true, preview changes without applying them. Returns what would be created/updated/deleted.",
    )
    validation_mode: Literal["strict", "lenient"] | None = Field(
        None,
        description="Validation strictness. 'strict' fails entire sync on any validation error. 'lenient' processes valid creatives and reports errors.",
    )
    push_notification_config: PushNotificationConfig | None = Field(
        None,
        description="Optional webhook configuration for async sync notifications. Publisher will send webhook when sync completes if operation takes longer than immediate response time (typically for large bulk operations or manual approval/HITL).",
    )


class UpdateMediaBuyRequest(BaseModel):
    """Request parameters for updating campaign and package settings"""

    media_buy_id: str | None = Field(None, description="Publisher's ID of the media buy to update")
    buyer_ref: str | None = Field(None, description="Buyer's reference for the media buy to update")
    active: bool | None = Field(None, description="Pause/resume the entire media buy")
    start_time: StartTiming | None = None
    end_time: str | None = Field(None, description="New end date/time in ISO 8601 format")
    packages: list[dict[str, Any]] | None = Field(None, description="Package-specific updates")
    push_notification_config: PushNotificationConfig | None = Field(
        None,
        description="Optional webhook configuration for async update notifications. Publisher will send webhook when update completes if operation takes longer than immediate response time.",
    )


class ActivateSignalResponse(BaseModel):
    """Response payload for activate_signal task"""

    decisioning_platform_segment_id: str | None = Field(
        None, description="The platform-specific ID to use once activated"
    )
    estimated_activation_duration_minutes: float | None = Field(
        None, description="Estimated time to complete (optional)"
    )
    deployed_at: str | None = Field(
        None, description="Timestamp when activation completed (optional)"
    )
    errors: list[Error] | None = Field(
        None,
        description="Task-specific errors and warnings (e.g., activation failures, platform issues)",
    )


class BuildCreativeResponse(BaseModel):
    """Response containing the transformed or generated creative manifest, ready for use with preview_creative or sync_creatives"""

    creative_manifest: CreativeManifest = Field(
        description="The generated or transformed creative manifest"
    )
    errors: list[Error] | None = Field(None, description="Task-specific errors and warnings")


class CreateMediaBuyResponse(BaseModel):
    """Response payload for create_media_buy task"""

    media_buy_id: str | None = Field(
        None, description="Publisher's unique identifier for the created media buy"
    )
    buyer_ref: str = Field(description="Buyer's reference identifier for this media buy")
    creative_deadline: str | None = Field(
        None, description="ISO 8601 timestamp for creative upload deadline"
    )
    packages: list[dict[str, Any]] | None = Field(None, description="Array of created packages")
    errors: list[Error] | None = Field(
        None,
        description="Task-specific errors and warnings (e.g., partial package creation failures)",
    )


class GetMediaBuyDeliveryResponse(BaseModel):
    """Response payload for get_media_buy_delivery task"""

    notification_type: Literal["scheduled", "final", "delayed", "adjusted"] | None = Field(
        None,
        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",
    )
    partial_data: bool | None = Field(
        None,
        description="Indicates if any media buys in this webhook have missing/delayed data (only present in webhook deliveries)",
    )
    unavailable_count: int | None = Field(
        None,
        description="Number of media buys with reporting_delayed or failed status (only present in webhook deliveries when partial_data is true)",
    )
    sequence_number: int | None = Field(
        None,
        description="Sequential notification number (only present in webhook deliveries, starts at 1)",
    )
    next_expected_at: str | None = Field(
        None,
        description="ISO 8601 timestamp for next expected notification (only present in webhook deliveries when notification_type is not 'final')",
    )
    reporting_period: dict[str, Any] = Field(
        description="Date range for the report. All periods use UTC timezone."
    )
    currency: str = Field(description="ISO 4217 currency code")
    aggregated_totals: dict[str, Any] | None = Field(
        None,
        description="Combined metrics across all returned media buys. Only included in API responses (get_media_buy_delivery), not in webhook notifications.",
    )
    media_buy_deliveries: list[dict[str, Any]] = 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."
    )
    errors: list[Error] | None = Field(
        None,
        description="Task-specific errors and warnings (e.g., missing delivery data, reporting platform issues)",
    )


class GetProductsResponse(BaseModel):
    """Response payload for get_products task"""

    products: list[Product] = Field(description="Array of matching products")
    errors: list[Error] | None = Field(
        None, description="Task-specific errors and warnings (e.g., product filtering issues)"
    )


class GetSignalsResponse(BaseModel):
    """Response payload for get_signals task"""

    signals: list[dict[str, Any]] = Field(description="Array of matching signals")
    errors: list[Error] | None = Field(
        None,
        description="Task-specific errors and warnings (e.g., signal discovery or pricing issues)",
    )


class ListAuthorizedPropertiesResponse(BaseModel):
    """Response payload for list_authorized_properties task. Lists publisher domains and authorization scope (property_ids or property_tags). Buyers fetch actual property definitions from each publisher's canonical adagents.json file."""

    publisher_domains: list[str] = Field(
        description="Publisher domains this agent is authorized to represent. Buyers should fetch each publisher's adagents.json to see property definitions and verify this agent is in their authorized_agents list with authorization scope."
    )
    primary_channels: list[Channels] | None = Field(
        None,
        description="Primary advertising channels represented in this property portfolio. Helps buying agents quickly filter relevance.",
    )
    primary_countries: list[str] | None = Field(
        None,
        description="Primary countries (ISO 3166-1 alpha-2 codes) where properties are concentrated. Helps buying agents quickly filter relevance.",
    )
    portfolio_description: str | None = Field(
        None,
        description="Markdown-formatted description of the property portfolio, including inventory types, audience characteristics, and special features.",
    )
    advertising_policies: str | None = Field(
        None,
        description="Publisher's advertising content policies, restrictions, and guidelines in natural language. May include prohibited categories, blocked advertisers, restricted tactics, brand safety requirements, or links to full policy documentation.",
    )
    last_updated: str | None = Field(
        None,
        description="ISO 8601 timestamp of when the agent's publisher authorization list was last updated. Buyers can use this to determine if their cached publisher adagents.json files might be stale.",
    )
    errors: list[Error] | None = Field(
        None, description="Task-specific errors and warnings (e.g., property availability issues)"
    )


class ListCreativeFormatsResponse(BaseModel):
    """Response payload for list_creative_formats task from creative agent - returns full format definitions"""

    formats: list[Format] = Field(
        description="Full format definitions for all formats this agent supports. Each format's authoritative source is indicated by its agent_url field."
    )
    creative_agents: list[dict[str, Any]] | None = Field(
        None,
        description="Optional: Creative agents that provide additional formats. Buyers can recursively query these agents to discover more formats. No authentication required for list_creative_formats.",
    )
    errors: list[Error] | None = Field(None, description="Task-specific errors and warnings")


class ListCreativesResponse(BaseModel):
    """Response from creative library query with filtered results, metadata, and optional enriched data"""

    query_summary: dict[str, Any] = Field(description="Summary of the query that was executed")
    pagination: dict[str, Any] = Field(description="Pagination information for navigating results")
    creatives: list[dict[str, Any]] = Field(
        description="Array of creative assets matching the query"
    )
    format_summary: dict[str, Any] | None = Field(
        None, description="Breakdown of creatives by format type"
    )
    status_summary: dict[str, Any] | None = Field(
        None, description="Breakdown of creatives by status"
    )


class PreviewCreativeResponse(BaseModel):
    """Response containing preview links for a creative. Each preview URL returns an HTML page that can be embedded in an iframe to display the rendered creative."""

    previews: list[dict[str, Any]] = Field(
        description="Array of preview variants. Each preview corresponds to an input set from the request. If no inputs were provided, returns a single default preview."
    )
    interactive_url: str | None = Field(
        None,
        description="Optional URL to an interactive testing page that shows all preview variants with controls to switch between them, modify macro values, and test different scenarios.",
    )
    expires_at: str = Field(description="ISO 8601 timestamp when preview links expire")


class ProvidePerformanceFeedbackResponse(BaseModel):
    """Response payload for provide_performance_feedback task"""

    success: bool = Field(description="Whether the performance feedback was successfully received")
    errors: list[Error] | None = Field(
        None,
        description="Task-specific errors and warnings (e.g., invalid measurement period, missing campaign data)",
    )


class SyncCreativesResponse(BaseModel):
    """Response from creative sync operation with results for each creative"""

    dry_run: bool | None = Field(
        None, description="Whether this was a dry run (no actual changes made)"
    )
    creatives: list[dict[str, Any]] = Field(description="Results for each creative processed")


class UpdateMediaBuyResponse(BaseModel):
    """Response payload for update_media_buy task"""

    media_buy_id: str = Field(description="Publisher's identifier for the media buy")
    buyer_ref: str = Field(description="Buyer's reference identifier for the media buy")
    implementation_date: Any | None = Field(
        None, description="ISO 8601 timestamp when changes take effect (null if pending approval)"
    )
    affected_packages: list[dict[str, Any]] | None = Field(
        None, description="Array of packages that were modified"
    )
    errors: list[Error] | None = Field(
        None, description="Task-specific errors and warnings (e.g., partial update failures)"
    )
