from __future__ import annotations

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


# ---------------------------------------------------------------------------
# Request parameter types
# ---------------------------------------------------------------------------

@dataclass
class CreateAssetParams:
    """Parameters for creating a new asset.

    The ``config`` dict is stored as ``asset_config`` in the database and
    returned as both ``config`` and ``assetConfig`` in the API response.

    ``product_name`` is a convenience shorthand — when provided it is
    merged into ``config`` as ``{"product_name": ...}``.  Callers can
    pass arbitrary keys via ``config`` directly instead.
    """

    product_name: Optional[str] = None
    external_id: Optional[str] = None
    vertical: Optional[str] = None
    security_level: Optional[str] = None
    config: Optional[Dict[str, Any]] = None
    metadata: Optional[Dict[str, Any]] = None


@dataclass
class UpdateAssetParams:
    """Parameters for updating an existing asset."""

    product_name: Optional[str] = None
    external_id: Optional[str] = None
    vertical: Optional[str] = None
    config: Optional[Dict[str, Any]] = None
    metadata: Optional[Dict[str, Any]] = None


@dataclass
class RevokeAssetParams:
    """Parameters for revoking an asset."""

    reason: str


@dataclass
class ListAssetsParams:
    """Parameters for listing assets."""

    page: Optional[int] = None
    per_page: Optional[int] = None
    vertical: Optional[str] = None
    status: Optional[str] = None
    is_sandbox: Optional[bool] = None


@dataclass
class ListAuditParams:
    """Parameters for listing audit events."""

    page: Optional[int] = None
    limit: Optional[int] = None
    event_type: Optional[str] = None
    resource_id: Optional[str] = None
    from_date: Optional[str] = None
    to_date: Optional[str] = None


@dataclass
class ExportParams:
    """Parameters for exporting audit data."""

    from_date: Optional[str] = None
    to_date: Optional[str] = None
    limit: Optional[int] = None


@dataclass
class CreateWebhookParams:
    """Parameters for creating a webhook endpoint."""

    url: str
    events: Optional[List[str]] = None
    description: Optional[str] = None


@dataclass
class CreateKeyParams:
    """Parameters for creating an API key."""

    environment: str
    tenant_id: str
    label: Optional[str] = None
    permissions: Optional[List[str]] = None


# ---------------------------------------------------------------------------
# Response types
# ---------------------------------------------------------------------------

@dataclass
class AssetSeal:
    """Cryptographic seal attached to an asset."""

    signature: str
    public_key_hex: str
    key_id: str
    signed_at: str
    algorithm: str


@dataclass
class Asset:
    """Core asset representation."""

    id: str
    vertical: str
    status: str
    is_sandbox: bool
    created_at: str
    config: Optional[Dict[str, Any]] = None
    external_id: Optional[str] = None
    security_level: Optional[str] = None
    seal: Optional[AssetSeal] = None


@dataclass
class AssetDetail(Asset):
    """Extended asset representation with full detail."""

    metadata: Optional[Dict[str, Any]] = None
    updated_at: Optional[str] = None


@dataclass
class AuditEvent:
    """A single audit log event."""

    id: str
    tenant_id: str
    event_type: str
    actor: str
    created_at: str
    resource_id: Optional[str] = None
    resource_type: Optional[str] = None
    details: Optional[Dict[str, Any]] = None
    event_hash: Optional[str] = None
    chain_sequence: Optional[int] = None


@dataclass
class ChainVerifyResult:
    """Result of an audit chain verification."""

    tenant_id: str
    chain_valid: bool
    events_checked: int
    verified_at: str
    broken_at_sequence: Optional[int] = None


@dataclass
class MerkleRoot:
    """A Merkle tree root for a time period."""

    id: str
    root_hash: str
    event_count: int
    period_start: str
    period_end: str
    created_at: str


@dataclass
class MerkleProof:
    """Merkle inclusion proof for a single event."""

    event_id: str
    event_hash: str
    merkle_root: str
    proof: List[str]
    verified: bool
    period: str


@dataclass
class ExportResult:
    """Result of an audit export operation."""

    filename: str
    event_count: int
    csv: str
    signature: Optional[str] = None
    public_key_hex: Optional[str] = None
    key_id: Optional[str] = None
    algorithm: Optional[str] = None


@dataclass
class ComplianceConfig:
    """Compliance configuration for a tenant."""

    compliance_mode: str
    retention_policy: Dict[str, Any] = field(default_factory=dict)


@dataclass
class WebhookEndpoint:
    """A registered webhook endpoint."""

    id: str
    url: str
    events: List[str]
    is_active: bool
    created_at: str
    description: Optional[str] = None
    updated_at: Optional[str] = None


@dataclass
class WebhookDelivery:
    """Record of a single webhook delivery attempt."""

    id: str
    event_type: str
    status: str
    attempts: int
    created_at: str
    response_status: Optional[int] = None
    error_message: Optional[str] = None
    last_attempt_at: Optional[str] = None


@dataclass
class VerificationResult:
    """Structured verification result with forward-compatible offline fields."""

    signature_valid: bool
    revocation_status: str  # 'clear' | 'revoked' | 'unknown'
    filter_age_seconds: Optional[int]
    verified_at: str  # ISO 8601
    verification_mode: str  # 'online' | 'offline'
    freshness: Optional[str] = None  # 'current' | 'stale'


@dataclass
class FilterSyncResult:
    """Result of downloading a revocation filter."""

    filter: bytes
    salts: Dict[str, bytes]  # tenant_id → salt
    issued_at: Any  # datetime
    item_count: int


@dataclass
class ApiKeyMeta:
    """Metadata about an API key (never exposes the full secret)."""

    id: str
    key_prefix: str
    environment: str
    permissions: List[str]
    rate_limit_per_hour: int
    created_at: str
    is_active: bool
    label: Optional[str] = None
    last_used_at: Optional[str] = None


# ---------------------------------------------------------------------------
# Schema Registry types (v2.0)
# ---------------------------------------------------------------------------


@dataclass
class CreateSchemaParams:
    """Parameters for registering a vertical config schema."""

    vertical_id: str
    metadata_schema: Dict[str, Any]
    version: Optional[str] = None
    export_formats: Optional[List[str]] = None
    description: Optional[str] = None


@dataclass
class UpdateSchemaParams:
    """Parameters for updating an existing vertical schema."""

    version: Optional[str] = None
    metadata_schema: Optional[Dict[str, Any]] = None
    export_formats: Optional[List[str]] = None
    description: Optional[str] = None
    is_active: Optional[bool] = None


@dataclass
class ListSchemasParams:
    """Parameters for listing schemas."""

    page: Optional[int] = None
    per_page: Optional[int] = None
    include_inactive: Optional[bool] = None


@dataclass
class VerticalSchema:
    """A registered vertical config schema."""

    id: str
    tenantId: str
    verticalId: str
    version: str
    metadataSchema: Dict[str, Any]
    exportFormats: List[str]
    isActive: bool
    createdAt: str
    updatedAt: str
    description: Optional[str] = None


@dataclass
class SchemaValidationResult:
    """Result of pre-flight schema validation."""

    valid: bool
    errors: List[Dict[str, Any]] = field(default_factory=list)


@dataclass
class BatchCreateParams:
    """Parameters for batch asset creation."""

    keyset_id: str
    assets: List[CreateAssetParams]


@dataclass
class BatchCreateResult:
    """Result of batch asset creation."""

    created: int
    requested: int
    assets: List[Asset]
    errors: Optional[List[Dict[str, Any]]] = None
