# generated by datamodel-codegen:
#   filename:  core/creative_brief.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 ConfigDict, Field, RootModel

from ..enums import disclosure_position
from . import reference_asset


class Jurisdiction(RootModel[str]):
    root: Annotated[str, Field(pattern='^[A-Z]{2}(-[A-Z0-9]{1,3})?$')]


class Messaging(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    cta: Annotated[str | None, Field(description='Call-to-action text')] = None
    headline: Annotated[str | None, Field(description='Primary headline')] = None
    key_messages: Annotated[
        list[str] | None, Field(description='Key messages to communicate in priority order')
    ] = None
    tagline: Annotated[str | None, Field(description='Supporting tagline or sub-headline')] = None


class Objective(Enum):
    awareness = 'awareness'
    consideration = 'consideration'
    conversion = 'conversion'
    retention = 'retention'
    engagement = 'engagement'


class RequiredDisclosure(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    jurisdictions: Annotated[
        list[Jurisdiction] | None,
        Field(
            description="Jurisdictions where this disclosure is required. ISO 3166-1 alpha-2 country codes or ISO 3166-2 subdivision codes (e.g., 'US', 'GB', 'US-NJ', 'CA-QC'). If omitted, the disclosure applies to all jurisdictions in the campaign.",
            min_length=1,
        ),
    ] = None
    language: Annotated[
        str | None,
        Field(
            description="Language of the disclosure text as a BCP 47 language tag (e.g., 'en', 'fr-CA', 'es'). When omitted, the disclosure is assumed to match the creative's language."
        ),
    ] = None
    min_duration_ms: Annotated[
        int | None,
        Field(
            description='Minimum display duration in milliseconds. For video/audio disclosures, how long the disclosure must be visible or audible. For static formats, how long the disclosure must remain on screen before any auto-advance.',
            ge=1,
        ),
    ] = None
    position: Annotated[
        disclosure_position.DisclosurePosition | None,
        Field(
            description='Where the disclosure should appear within the creative. prominent: clearly visible in the main creative area; footer: at the bottom of visual creatives; audio: spoken in audio/video creatives; subtitle: displayed in the subtitle or closed-caption track; overlay: superimposed on video content; end_card: displayed on video end card; pre_roll: spoken or displayed before main content; companion: in companion ad unit alongside primary creative'
        ),
    ] = None
    regulation: Annotated[
        str | None,
        Field(
            description="The regulation or legal authority requiring this disclosure (e.g., 'SEC Rule 156', 'FCA COBS 4.5', 'FDA 21 CFR 202')"
        ),
    ] = None
    text: Annotated[str, Field(description='The disclosure text that must appear in the creative')]


class Compliance(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    prohibited_claims: Annotated[
        list[str] | None,
        Field(
            description='Claims that must not appear in creatives for this campaign. Creative agents should ensure generated content avoids these claims.',
            min_length=1,
        ),
    ] = None
    required_disclosures: Annotated[
        list[RequiredDisclosure] | None,
        Field(
            description='Disclosures that must appear in creatives for this campaign. Each disclosure specifies the text, where it should appear, and which jurisdictions require it.',
            min_length=1,
        ),
    ] = None


class CreativeBrief(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    audience: Annotated[
        str | None, Field(description='Target audience description for this campaign')
    ] = None
    compliance: Annotated[
        Compliance | None,
        Field(
            description='Regulatory and legal compliance requirements for this campaign. Campaign-specific, regional, and product-based — distinct from brand-level disclaimers in brand.json.'
        ),
    ] = None
    messaging: Annotated[
        Messaging | None, Field(description='Messaging framework for the campaign')
    ] = None
    name: Annotated[str, Field(description='Campaign or flight name for identification')]
    objective: Annotated[
        Objective | None,
        Field(
            description='Campaign objective that guides creative tone and call-to-action strategy'
        ),
    ] = None
    reference_assets: Annotated[
        list[reference_asset.ReferenceAsset] | None,
        Field(
            description='Visual and strategic reference materials such as mood boards, product shots, example creatives, and strategy documents'
        ),
    ] = None
    territory: Annotated[
        str | None,
        Field(description='Creative territory or positioning the campaign should occupy'),
    ] = None
    tone: Annotated[
        str | None,
        Field(
            description="Desired tone for this campaign, modulating the brand's base tone (e.g., 'playful and festive', 'premium and aspirational')"
        ),
    ] = None
