"""All publish_* methods for the results stream."""
from __future__ import annotations

import json
import logging
from datetime import datetime, timezone
from typing import Any, Dict, Optional

logger = logging.getLogger(__name__)


class ResultPublisher:
    """Writes structured messages to the agent results stream."""

    def __init__(self, conn, instance_id: str, results_stream: str) -> None:
        self._conn = conn          # RedisConnection
        self._instance_id = instance_id
        self._results_stream = results_stream

    # -- helpers ---------------------------------------------------------

    def _now(self) -> str:
        return datetime.now(timezone.utc).isoformat()

    def _xadd(self, fields: Dict[str, Any]) -> None:
        self._conn.client.xadd(self._results_stream, fields)

    # -- public ----------------------------------------------------------

    def publish_result(self, task_id: str, result: Dict[str, Any]) -> None:
        self._xadd({
            "type": "task_result",
            "task_id": task_id,
            "instance_id": self._instance_id,
            "status": "success",
            "result": json.dumps(result),
            "timestamp": self._now(),
        })
        logger.info("Published task result task_id=%s", task_id)

    def publish_error(self, task_id: str, error: str) -> None:
        self._xadd({
            "type": "task_result",
            "task_id": task_id,
            "instance_id": self._instance_id,
            "status": "error",
            "error": error,
            "timestamp": self._now(),
        })
        logger.warning("Published task error task_id=%s error=%s", task_id, error)

    def publish_heartbeat(self, status: str, components: Dict[str, Any]) -> None:
        self._xadd({
            "type": "heartbeat",
            "instance_id": self._instance_id,
            "status": status,
            "components": json.dumps(components),
            "timestamp": self._now(),
        })
        logger.debug("Published heartbeat status=%s", status)

    def publish_report(self, report_type: str, data: Dict[str, Any]) -> None:
        self._xadd({
            "type": report_type,
            "instance_id": self._instance_id,
            "data": json.dumps(data),
            "timestamp": self._now(),
        })
        logger.debug("Published report type=%s", report_type)

    def publish_config_request(self) -> None:
        self._xadd({
            "type": "config_request",
            "instance_id": self._instance_id,
            "timestamp": self._now(),
        })
        logger.info("Published config_request for instance_id=%s", self._instance_id)

    def publish_config_applied(self, version: Optional[int]) -> None:
        # Deprecated: config_applied should be published via telemetry stream.
        self._xadd({
            "type": "config_applied",
            "instance_id": self._instance_id,
            "config_version": version if version is not None else "",
            "timestamp": self._now(),
        })
        logger.info("Published config_applied version=%s", version)

    def publish_instance_registration(
        self,
        instance_name: Optional[str],
        version: str,
        metadata: Dict[str, Any],
    ) -> None:
        self._xadd({
            "type": "instance_register",
            "instance_id": self._instance_id,
            "instance_name": instance_name or "",
            "version": version or "",
            "metadata": json.dumps(metadata),
            "timestamp": self._now(),
        })
        logger.info(
            "Published instance_register instance_id=%s",
            self._instance_id,
        )

    def publish_backlog_report(self, data: Dict[str, Any]) -> None:
        try:
            self._xadd({
                "type": "backlog_report",
                "instance_id": self._instance_id,
                "data": json.dumps(data),
                "timestamp": self._now(),
            })
        except Exception as exc:
            logger.error("Failed to publish backlog report: %s", exc)
