"""Base dataclasses for the connector catalog."""
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Optional


@dataclass(frozen=True)
class ConnectorChangelogEntry:
    version: str   # format: "01.00.00"
    date: str      # ISO date: "2026-04-26"
    notes: str


@dataclass(frozen=True)
class ConnectorFieldDef:
    """Presentation and validation metadata for one connection field."""

    key: str
    label: str
    description: Optional[str] = None
    placeholder: Optional[str] = None
    required: bool = False
    input_type: str = "text"
    default: Optional[str] = None


@dataclass(frozen=True)
class ConnectorActionDef:
    key: str
    slug: str
    name: str
    description: str
    input_schema: dict[str, Any] = field(default_factory=dict)
    output_schema: dict[str, Any] = field(default_factory=dict)
    execution_mode: str = "sync"
    required_scopes: tuple[str, ...] = ()
    # Authorization / entitlement requirements (e.g. integrations.execute).
    # Not the P2HS invoke verb — see ``implements``.
    required_capabilities: tuple[str, ...] = ()
    # Stable P2HS invoke capabilities this action implements (catalog-only; not persisted).
    # Distinct from Codegen default: implements is catalog truth; escape-hatch
    # demotion happens when the backed capability is status=implemented.
    implements: tuple[str, ...] = ()


@dataclass(frozen=True)
class ConnectorTriggerDef:
    key: str
    event_type: str
    name: str
    schema: dict[str, Any] = field(default_factory=dict)
    webhook_required: bool = True
    polling_supported: bool = False


@dataclass(frozen=True)
class ConnectorDef:
    key: str
    name: str
    category: str
    auth_type: str
    # Connector entries represent customer-configured integrations. P2HS-owned
    # infrastructure belongs to native platform ports, not this catalog. The
    # explicit fields keep that boundary machine-readable and leave room for a
    # vendor to exist independently in both planes later.
    ownership_mode: str = "customer_byok"
    execution_domain: str = "C"
    version: str = "01.00.00"
    status: str = "active"
    # client_side: connector injects a frontend script into the generated app.
    # Can be True alongside actions (dual-mode: e.g. Facebook Pixel + CAPI).
    client_side: bool = False
    icon: Optional[str] = None
    image_url: Optional[str] = None
    description: Optional[str] = None
    docs_url: Optional[str] = None
    config_fields: tuple[str, ...] = ()
    secret_fields: tuple[str, ...] = ()
    config_field_defs: tuple[ConnectorFieldDef, ...] = ()
    secret_field_defs: tuple[ConnectorFieldDef, ...] = ()
    actions: tuple[ConnectorActionDef, ...] = ()
    triggers: tuple[ConnectorTriggerDef, ...] = ()
    changelog: tuple[ConnectorChangelogEntry, ...] = ()
