from __future__ import annotations

"""Mac sync-agent — 条件推送 + 触发器。"""

from typing import Any

from niannian.storage.local import LocalMemoryStore
from niannian.storage.types import FlushResult, PullResult, SyncStatus


class SyncAgent:
    """非 heavy daemon；由 app 启动 / CLI / Console 触发。"""

    def __init__(
        self,
        store: LocalMemoryStore,
        *,
        config: dict[str, Any] | None = None,
    ) -> None:
        self._store = store
        self._config = config or {}
        self._sync_cfg = self._config.get("sync") or {}

    def status(self, *, probe_tier: bool = False) -> SyncStatus:
        return self._store.sync_status(probe_tier=probe_tier)

    def should_push(self, *, force: bool = False) -> tuple[bool, list[str]]:
        return self._store.evaluate_push(force=force)

    def push(self, *, force: bool = False) -> FlushResult:
        return self._store.flush_to_cloud(force=force)

    def pull(self) -> PullResult:
        return self._store.pull_from_cloud()

    def on_trigger(self, trigger: str) -> FlushResult | None:
        """app_launch / threshold / pre_sleep / user_manual / max_interval。"""
        triggers = self._sync_cfg.get("triggers") or [
            "app_launch",
            "threshold",
            "pre_sleep",
            "user_manual",
        ]
        if trigger not in triggers and trigger != "user_manual":
            return None

        if trigger == "user_manual":
            return self.push(force=True)

        if trigger in ("app_launch", "pre_sleep", "max_interval"):
            allowed, _ = self.should_push(force=False)
            if allowed:
                return self.push(force=False)
            return None

        if trigger == "threshold":
            allowed, _ = self.should_push(force=False)
            if allowed:
                return self.push(force=False)
        return None

    def on_app_launch(self) -> FlushResult | None:
        self.pull()
        allowed, _ = self.should_push(force=False)
        if allowed:
            return self.push(force=False)
        return None
