"""Value objects for the customer cleanup transaction."""

from __future__ import annotations

from collections.abc import Mapping
from dataclasses import dataclass
from pathlib import Path
from types import MappingProxyType


class CleanupError(ValueError):
    """Base error for customer cleanup."""


class CleanupIntegrityError(CleanupError):
    """A cleanup source, journal, or archive failed integrity validation."""


class CleanupBlockedError(CleanupError):
    """Live or ambiguous authority prevents destructive cleanup."""


@dataclass(frozen=True, slots=True)
class CleanupReceipt:
    customer_key: str
    operation_id: str
    phase: str
    archive_root: Path
    manifest_path: Path
    journal_path: Path
    archive_verified: bool


@dataclass(frozen=True, slots=True)
class AuthorityInventory:
    customer_key: str
    disabled: bool
    nonconsenting: bool
    categories: Mapping[str, int]
    active_count: int
    pending_count: int
    unknown_count: int
    orphan_count: int
    archive_verified: bool
    journal_committed: bool
    terminal: bool

    @classmethod
    def build(
        cls,
        *,
        customer_key: str,
        disabled: bool,
        nonconsenting: bool,
        categories: dict[str, int],
        active_count: int,
        pending_count: int,
        unknown_count: int,
        orphan_count: int,
        archive_verified: bool,
        journal_committed: bool,
    ) -> AuthorityInventory:
        terminal = all((
            disabled,
            nonconsenting,
            active_count == 0,
            pending_count == 0,
            unknown_count == 0,
            orphan_count == 0,
            archive_verified,
            journal_committed,
        ))
        return cls(
            customer_key=customer_key,
            disabled=disabled,
            nonconsenting=nonconsenting,
            categories=MappingProxyType(dict(categories)),
            active_count=active_count,
            pending_count=pending_count,
            unknown_count=unknown_count,
            orphan_count=orphan_count,
            archive_verified=archive_verified,
            journal_committed=journal_committed,
            terminal=terminal,
        )
