"""Frozen dataclasses for cross-domain data transfer.

These are the *only* shapes that cross domain boundaries.  Consumers never
see ORM model instances from another domain — only these DTOs.
"""
from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from decimal import Decimal


# ---------------------------------------------------------------------------
# Blog domain
# ---------------------------------------------------------------------------

@dataclass(frozen=True, slots=True)
class PostDTO:
    id: int
    slug: str
    title: str
    status: str
    visibility: str
    is_page: bool = False
    feature_image: str | None = None
    html: str | None = None
    excerpt: str | None = None
    custom_excerpt: str | None = None
    published_at: datetime | None = None


# ---------------------------------------------------------------------------
# Calendar / Events domain
# ---------------------------------------------------------------------------

@dataclass(frozen=True, slots=True)
class CalendarDTO:
    id: int
    container_type: str
    container_id: int
    name: str
    slug: str
    description: str | None = None


@dataclass(frozen=True, slots=True)
class TicketDTO:
    id: int
    code: str
    state: str
    entry_name: str
    entry_start_at: datetime
    entry_end_at: datetime | None = None
    ticket_type_name: str | None = None
    calendar_name: str | None = None
    created_at: datetime | None = None
    checked_in_at: datetime | None = None
    entry_id: int | None = None
    ticket_type_id: int | None = None
    price: Decimal | None = None
    order_id: int | None = None
    calendar_container_id: int | None = None


@dataclass(frozen=True, slots=True)
class CalendarEntryDTO:
    id: int
    calendar_id: int
    name: str
    start_at: datetime
    state: str
    cost: Decimal
    end_at: datetime | None = None
    user_id: int | None = None
    session_id: str | None = None
    order_id: int | None = None
    slot_id: int | None = None
    ticket_price: Decimal | None = None
    ticket_count: int | None = None
    calendar_name: str | None = None
    calendar_slug: str | None = None
    calendar_container_id: int | None = None
    calendar_container_type: str | None = None


# ---------------------------------------------------------------------------
# Market domain
# ---------------------------------------------------------------------------

@dataclass(frozen=True, slots=True)
class MarketPlaceDTO:
    id: int
    container_type: str
    container_id: int
    name: str
    slug: str
    description: str | None = None


@dataclass(frozen=True, slots=True)
class ProductDTO:
    id: int
    slug: str
    title: str | None = None
    image: str | None = None
    description_short: str | None = None
    rrp: Decimal | None = None
    regular_price: Decimal | None = None
    special_price: Decimal | None = None


# ---------------------------------------------------------------------------
# Cart domain
# ---------------------------------------------------------------------------

@dataclass(frozen=True, slots=True)
class CartItemDTO:
    id: int
    product_id: int
    quantity: int
    product_title: str | None = None
    product_slug: str | None = None
    product_image: str | None = None
    unit_price: Decimal | None = None
    market_place_id: int | None = None


@dataclass(frozen=True, slots=True)
class CartSummaryDTO:
    count: int = 0
    total: Decimal = Decimal("0")
    calendar_count: int = 0
    calendar_total: Decimal = Decimal("0")
    items: list[CartItemDTO] = field(default_factory=list)
    ticket_count: int = 0
    ticket_total: Decimal = Decimal("0")


# ---------------------------------------------------------------------------
# Federation / ActivityPub domain
# ---------------------------------------------------------------------------

@dataclass(frozen=True, slots=True)
class ActorProfileDTO:
    id: int
    user_id: int
    preferred_username: str
    public_key_pem: str
    display_name: str | None = None
    summary: str | None = None
    inbox_url: str | None = None
    outbox_url: str | None = None
    created_at: datetime | None = None


@dataclass(frozen=True, slots=True)
class APActivityDTO:
    id: int
    activity_id: str
    activity_type: str
    actor_profile_id: int
    object_type: str | None = None
    object_data: dict | None = None
    published: datetime | None = None
    is_local: bool = True
    source_type: str | None = None
    source_id: int | None = None
    ipfs_cid: str | None = None


@dataclass(frozen=True, slots=True)
class APFollowerDTO:
    id: int
    actor_profile_id: int
    follower_acct: str
    follower_inbox: str
    follower_actor_url: str
    created_at: datetime | None = None


@dataclass(frozen=True, slots=True)
class APAnchorDTO:
    id: int
    merkle_root: str
    activity_count: int = 0
    tree_ipfs_cid: str | None = None
    ots_proof_cid: str | None = None
    confirmed_at: datetime | None = None
    bitcoin_txid: str | None = None
