from __future__ import annotations

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


@dataclass
class SyncStatus:
    version: int = 0
    pending_atoms: int = 0
    pending_bytes: int = 0
    last_sync: str | None = None
    last_cloud_sync: str | None = None
    last_archive_at: str | None = None
    last_dream_at: str | None = None
    realtime: str = "quark"
    backup: dict[str, Any] = field(default_factory=dict)
    tier: dict[str, Any] = field(default_factory=dict)
    archive: dict[str, Any] = field(default_factory=dict)
    node_id: str | None = None
    cloud_ready: bool = False
    push_allowed: bool = False
    push_blocked_reasons: list[str] = field(default_factory=list)
    backends: dict[str, str] = field(default_factory=dict)
    manifest_versions: dict[str, int | None] = field(default_factory=dict)
    primary_mode: str = "mirror"
    degraded: bool = False

    def to_dict(self) -> dict[str, Any]:
        data = asdict(self)
        if data.get("last_cloud_sync") is None:
            data["last_cloud_sync"] = data.get("last_sync")
        return data


@dataclass
class FlushResult:
    ok: bool
    version: int = 0
    files_uploaded: list[str] = field(default_factory=list)
    errors: list[str] = field(default_factory=list)
    skipped: bool = False
    blocked_reasons: list[str] = field(default_factory=list)

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)


@dataclass
class PullResult:
    ok: bool
    version: int = 0
    files_downloaded: list[str] = field(default_factory=list)
    errors: list[str] = field(default_factory=list)

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)


@dataclass
class ArchiveResult:
    ok: bool
    chunks_archived: int = 0
    bytes_archived: int = 0
    errors: list[str] = field(default_factory=list)
    skipped_reason: str | None = None
    eligible_at_7d: int = 0
    min_distilled_atoms: int = 50
    next_retry_after_days: int | None = None
    webdav_ok: bool | None = None

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)
