from __future__ import annotations

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Any

from .models import Cell, Maze


@dataclass(frozen=True)
class Event:
    event_type: str
    payload: dict[str, Any] = field(default_factory=dict)


class Observer(ABC):
    @abstractmethod
    def update(self, event: Event) -> None:
        raise NotImplementedError


class ConsoleView(Observer):
    def update(self, event: Event) -> None:
        if event.event_type == "search_started":
            print(f"Search started: {event.payload['strategy']}")
        elif event.event_type in {"path_found", "path_not_found"}:
            stats = event.payload["stats"]
            print(
                f"{event.event_type}: strategy={stats.strategy_name}, "
                f"time={stats.time_ms:.3f} ms, visited={stats.visited_cells}, "
                f"path_length={stats.path_length}"
            )

    def render(
        self,
        maze: Maze,
        player_position: Cell | None = None,
        path: list[Cell] | None = None,
    ) -> str:
        return maze.to_text(path=path, player=player_position)
