"""ErrorCollector — message hook error aggregation for Textual apps."""

import time

from textual.app import App
from textual.message import Message
from textual.worker import Worker, WorkerState


class ErrorCollector:
    """Collects errors from Textual message hooks and app exceptions.

    Designed to be used as a message hook callback via on_message().
    Tracks worker errors (Worker.StateChanged with ERROR state) and
    app-level exceptions.
    """

    def __init__(self) -> None:
        self.errors: list[dict] = []
        self.messages_seen: int = 0

    def on_message(self, message: Message) -> None:
        """Process a Textual message, capturing worker errors.

        Args:
            message: Any Textual message. Worker.StateChanged messages
                with ERROR state are recorded.
        """
        self.messages_seen += 1
        if isinstance(message, Worker.StateChanged):
            if message.state == WorkerState.ERROR:
                self.errors.append(
                    {
                        "type": "worker_error",
                        "worker_name": message.worker.name,
                        "error": str(message.worker.error),
                        "timestamp": time.time(),
                    }
                )

    def check_app_exception(self, app: App) -> dict | None:
        """Check if the app has an unhandled exception.

        Args:
            app: The Textual App instance to inspect.

        Returns:
            A dict with 'type' and 'message' keys if an exception exists,
            or None if the app is healthy.
        """
        if app._exception is not None:
            return {
                "type": type(app._exception).__name__,
                "message": str(app._exception),
            }
        return None

    def drain(self) -> list[dict]:
        """Return all collected errors and clear the internal buffer.

        Returns:
            A list of error dicts. Subsequent calls return an empty list
            until new errors are collected.
        """
        errors = self.errors.copy()
        self.errors.clear()
        return errors
