"""CanonicalProductRegulatoryProfile — the single semantic product profile.

Convergence layer (spec 2026-06-26): instead of letting the Go `gap.ProductProfile`
and the Python reasoning `ProductProfile` drift, ONE canonical type is the source
of truth. The Go gap engine LEADS (it carries real engine logic), so the canonical
mirrors gap's field names and adds the Navigator gaps the audit found missing
(economic-operator role, radio module, generates_usage_data, lifecycle phase,
structured BOM, safety-vs-security split, machine-vs-component) plus a
forward-looking Environmental-Impact domain.

No regulation logic lives here — types only. Mappers live in sibling modules.
Python 3.9 compatible (no `|` unions).
"""

from __future__ import annotations

from enum import Enum
from typing import List, Optional

from pydantic import BaseModel, Field


class CanonicalProductType(str, Enum):  # mirrors gap.ProductType
    SOFTWARE = "software"
    HARDWARE = "hardware"
    IOT = "iot"
    SAAS = "saas"
    EXCHANGE = "exchange"
    MEDICAL_DEVICE = "medical_device"
    MACHINERY = "machinery"
    OTHER = "other"


class EconomicOperatorRole(str, Enum):  # CE/CRA role — gap.ProductProfile has none
    MANUFACTURER = "manufacturer"
    IMPORTER = "importer"
    DISTRIBUTOR = "distributor"
    INTEGRATOR = "integrator"
    OPERATOR = "operator"
    SERVICE_PROVIDER = "service_provider"


class CanonicalLifecyclePhase(str, Enum):
    DEVELOPMENT = "development"
    PLACING_ON_MARKET = "placing_on_market"
    OPERATION = "operation"
    MAINTENANCE = "maintenance"
    UPDATE = "update"
    END_OF_LIFE = "end_of_life"


class ComponentKind(str, Enum):
    MOTOR = "motor"
    PUMP = "pump"
    HEATING = "heating"
    COOLING = "cooling"
    CONTROLLER = "controller"
    PLC = "plc"
    HMI = "hmi"
    SENSOR = "sensor"
    ACTUATOR = "actuator"
    CAMERA = "camera"
    NETWORK_INTERFACE = "network_interface"
    RADIO_MODULE = "radio_module"
    CHEMICAL_DOSING = "chemical_dosing"
    WATER_INLET = "water_inlet"
    WASTEWATER_OUTLET = "wastewater_outlet"
    BATTERY = "battery"
    OTHER = "other"


class ProductComponent(BaseModel):
    """One structured BOM node — these nodes are what later trigger domains."""

    name: str
    kind: ComponentKind = ComponentKind.OTHER
    notes: Optional[str] = None


class EnvironmentalImpact(BaseModel):
    """Forward-looking Umweltmedien-Trigger (own Navigator domain).

    No regulation logic consumes these yet — profile fields only, so the model
    is not blind to wastewater/air/chemicals/waste questions when that domain
    is wired later (AbwV/WRRL/REACH/CLP/IED/BImSchG ...).
    """

    discharges_to_wastewater: Optional[bool] = None
    uses_cleaning_chemicals: Optional[bool] = None
    supplies_chemicals: Optional[bool] = None
    emits_to_air: Optional[bool] = None
    uses_solvents: Optional[bool] = None
    creates_waste: Optional[bool] = None
    contains_restricted_substances: Optional[bool] = None
    consumes_energy_or_water: Optional[bool] = None
    has_cooling_or_spraying_water: Optional[bool] = None


class CanonicalProductRegulatoryProfile(BaseModel):
    # --- identity ---
    name: str = ""
    description: str = ""
    product_type: Optional[CanonicalProductType] = None
    product_profile_id: Optional[str] = None
    tenant_id: Optional[str] = None
    iace_project_id: Optional[str] = None

    # --- gap-native lists ---
    technologies: List[str] = Field(default_factory=list)
    data_processing: List[str] = Field(default_factory=list)
    markets: List[str] = Field(default_factory=list)  # real list — never hardcoded ['EU']
    existing_certifications: List[str] = Field(default_factory=list)
    applied_norms: List[str] = Field(default_factory=list)

    # --- gap-native product / IST-state booleans (tri-state: None = unknown) ---
    connected_to_internet: Optional[bool] = None
    has_software_updates: Optional[bool] = None
    uses_ai: Optional[bool] = None
    processes_personal_data: Optional[bool] = None
    is_critical_infra_supplier: Optional[bool] = None
    has_risk_assessment: Optional[bool] = None
    has_technical_file: Optional[bool] = None
    has_operating_manual: Optional[bool] = None
    has_sbom: Optional[bool] = None
    has_vuln_management: Optional[bool] = None
    has_update_mechanism: Optional[bool] = None
    has_incident_response: Optional[bool] = None
    has_supply_chain_mgmt: Optional[bool] = None
    ce_marking_since: Optional[str] = None
    product_age: Optional[str] = None

    # --- NEW Navigator-gap fields (audit 2026-06-26) ---
    economic_operator_role: Optional[EconomicOperatorRole] = None
    has_radio_module: Optional[bool] = None
    generates_usage_data: Optional[bool] = None
    lifecycle_phase: Optional[CanonicalLifecyclePhase] = None
    components: List[ProductComponent] = Field(default_factory=list)
    has_safety_function: Optional[bool] = None
    safety_function_description: Optional[str] = None
    has_security_function: Optional[bool] = None  # safety vs security split
    has_remote_access: Optional[bool] = None
    has_embedded_software: Optional[bool] = None
    is_machine: Optional[bool] = None
    is_component: Optional[bool] = None
    is_spare_part: Optional[bool] = None

    # --- company / market context (NIS2 + scope; from company-profile) ---
    b2b_or_b2c: Optional[str] = None
    sector_industry: Optional[str] = None
    company_size: Optional[str] = None
    primary_jurisdiction: Optional[str] = None

    # --- AI context (classification stays delegated to ai-act/ucca) ---
    ai_integration_type: List[str] = Field(default_factory=list)
    human_oversight_level: Optional[str] = None

    # --- forward-looking environmental domain ---
    environmental: EnvironmentalImpact = Field(default_factory=EnvironmentalImpact)
