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

from __future__ import annotations

from typing import Annotated

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

from ..enums import age_verification_method
from ..enums import device_platform as device_platform_1
from ..enums import metro_system, postal_system
from . import daypart_target
from . import frequency_cap as frequency_cap_1
from . import property_list_ref


class AgeRestriction(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    accepted_methods: Annotated[
        list[age_verification_method.AgeVerificationMethod] | None,
        Field(
            description='Accepted verification methods. If omitted, any method the platform supports is acceptable.',
            min_length=1,
        ),
    ] = None
    min: Annotated[int, Field(description='Minimum age required', ge=13, le=99)]
    verification_required: Annotated[
        bool | None,
        Field(description='Whether verified age (not inferred) is required for compliance'),
    ] = False


class GeoCountry(RootModel[str]):
    root: Annotated[str, Field(pattern='^[A-Z]{2}$')]


class GeoCountriesExcludeItem(GeoCountry):
    pass


class GeoMetro(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    system: Annotated[
        metro_system.MetroAreaSystem,
        Field(description="Metro area classification system (e.g., 'nielsen_dma', 'uk_itl2')"),
    ]
    values: Annotated[
        list[str],
        Field(
            description="Metro codes within the system (e.g., ['501', '602'] for Nielsen DMAs)",
            min_length=1,
        ),
    ]


class GeoMetrosExcludeItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    system: Annotated[
        metro_system.MetroAreaSystem,
        Field(description="Metro area classification system (e.g., 'nielsen_dma', 'uk_itl2')"),
    ]
    values: Annotated[
        list[str],
        Field(
            description="Metro codes to exclude within the system (e.g., ['501', '602'] for Nielsen DMAs)",
            min_length=1,
        ),
    ]


class GeoPostalArea(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    system: Annotated[
        postal_system.PostalCodeSystem,
        Field(
            description="Postal code system (e.g., 'us_zip', 'gb_outward'). System name encodes country and precision."
        ),
    ]
    values: Annotated[
        list[str],
        Field(
            description="Postal codes within the system (e.g., ['10001', '10002'] for us_zip)",
            min_length=1,
        ),
    ]


class GeoPostalAreasExcludeItem(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    system: Annotated[
        postal_system.PostalCodeSystem,
        Field(
            description="Postal code system (e.g., 'us_zip', 'gb_outward'). System name encodes country and precision."
        ),
    ]
    values: Annotated[
        list[str],
        Field(
            description="Postal codes to exclude within the system (e.g., ['10001', '10002'] for us_zip)",
            min_length=1,
        ),
    ]


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


class GeoRegionsExcludeItem(GeoRegion):
    pass


class LanguageItem(RootModel[str]):
    root: Annotated[str, Field(pattern='^[a-z]{2}$')]


class StoreCatchment(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    catalog_id: Annotated[
        str, Field(description='Synced store-type catalog ID from sync_catalogs.')
    ]
    catchment_ids: Annotated[
        list[str] | None,
        Field(
            description="Catchment zone IDs to target (e.g., 'walk', 'drive'). Omit to target all catchment zones.",
            min_length=1,
        ),
    ] = None
    store_ids: Annotated[
        list[str] | None,
        Field(
            description='Filter to specific stores within the catalog. Omit to target all stores.',
            min_length=1,
        ),
    ] = None


class TargetingOverlay(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    age_restriction: Annotated[
        AgeRestriction | None,
        Field(
            description='Age restriction for compliance. Use for legal requirements (alcohol, gambling), not audience targeting.'
        ),
    ] = None
    audience_exclude: Annotated[
        list[str] | None,
        Field(
            description='Suppress delivery to members of these first-party CRM audiences. Matched users are excluded regardless of other targeting. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    audience_include: Annotated[
        list[str] | None,
        Field(
            description='Restrict delivery to members of these first-party CRM audiences. Only users present in the uploaded lists are eligible. References audience_id values from sync_audiences on the same seller account — audience IDs are not portable across sellers. Not for lookalike expansion — express that intent in the campaign brief. Seller must declare support in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    axe_exclude_segment: Annotated[
        str | None, Field(description='AXE segment ID to exclude from targeting')
    ] = None
    axe_include_segment: Annotated[
        str | None, Field(description='AXE segment ID to include for targeting')
    ] = None
    daypart_targets: Annotated[
        list[daypart_target.DaypartTarget] | None,
        Field(
            description='Restrict delivery to specific time windows. Each entry specifies days of week and an hour range.',
            min_length=1,
        ),
    ] = None
    device_platform: Annotated[
        list[device_platform_1.DevicePlatform] | None,
        Field(
            description='Restrict to specific platforms. Use for technical compatibility (app only works on iOS). Values from Sec-CH-UA-Platform standard, extended for CTV.',
            min_length=1,
        ),
    ] = None
    frequency_cap: frequency_cap_1.FrequencyCap | None = None
    geo_countries: Annotated[
        list[GeoCountry] | None,
        Field(
            description="Restrict delivery to specific countries. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').",
            min_length=1,
        ),
    ] = None
    geo_countries_exclude: Annotated[
        list[GeoCountriesExcludeItem] | None,
        Field(
            description="Exclude specific countries from delivery. ISO 3166-1 alpha-2 codes (e.g., 'US', 'GB', 'DE').",
            min_length=1,
        ),
    ] = None
    geo_metros: Annotated[
        list[GeoMetro] | None,
        Field(
            description='Restrict delivery to specific metro areas. Each entry specifies the classification system and target values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_metros_exclude: Annotated[
        list[GeoMetrosExcludeItem] | None,
        Field(
            description='Exclude specific metro areas from delivery. Each entry specifies the classification system and excluded values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_postal_areas: Annotated[
        list[GeoPostalArea] | None,
        Field(
            description='Restrict delivery to specific postal areas. Each entry specifies the postal system and target values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_postal_areas_exclude: Annotated[
        list[GeoPostalAreasExcludeItem] | None,
        Field(
            description='Exclude specific postal areas from delivery. Each entry specifies the postal system and excluded values. Seller must declare supported systems in get_adcp_capabilities.',
            min_length=1,
        ),
    ] = None
    geo_regions: Annotated[
        list[GeoRegion] | None,
        Field(
            description="Restrict delivery to specific regions/states. ISO 3166-2 subdivision codes (e.g., 'US-CA', 'GB-SCT').",
            min_length=1,
        ),
    ] = None
    geo_regions_exclude: Annotated[
        list[GeoRegionsExcludeItem] | None,
        Field(
            description="Exclude specific regions/states from delivery. ISO 3166-2 subdivision codes (e.g., 'US-CA', 'GB-SCT').",
            min_length=1,
        ),
    ] = None
    language: Annotated[
        list[LanguageItem] | None,
        Field(
            description="Restrict to users with specific language preferences. ISO 639-1 codes (e.g., 'en', 'es', 'fr').",
            min_length=1,
        ),
    ] = None
    property_list: Annotated[
        property_list_ref.PropertyListReference | None,
        Field(
            description="Reference to a property list for targeting specific properties within this product. The package runs on the intersection of the product's publisher_properties and this list. Sellers SHOULD return a validation error if the product has property_targeting_allowed: false."
        ),
    ] = None
    store_catchments: Annotated[
        list[StoreCatchment] | None,
        Field(
            description='Target users within store catchment areas from a synced store catalog. Each entry references a store-type catalog and optionally narrows to specific stores or catchment zones.',
            min_length=1,
        ),
    ] = None
