import time
from dataclasses import dataclass
from typing import List, Optional
from maze_model import Maze, Cell
from pathfinding_strategies import PathFindingStrategy


@dataclass
class SearchStats:
    time_ms: float
    visited_cells: int
    path_length: int
    path_found: bool
    strategy_name: str


class MazeSolver:
    def __init__(self, maze: Maze, strategy: Optional[PathFindingStrategy] = None):
        self.maze = maze
        self._strategy = strategy

    def set_strategy(self, strategy: PathFindingStrategy) -> None:
        self._strategy = strategy

    def solve(self) -> SearchStats:
        if self._strategy is None:
            raise ValueError("Стратегии нет!")

        if self.maze.start is None or self.maze.exit is None:
            raise ValueError("Лабиринт не содержит начала или конца")

        start_time = time.perf_counter()

        if hasattr(self._strategy, '_find_path_with_stats'):
            path, visited = self._strategy._find_path_with_stats(
                self.maze, self.maze.start, self.maze.exit
            )
        else:
            path = self._strategy.find_path(
                self.maze, self.maze.start, self.maze.exit
            )
            visited = 0

        end_time = time.perf_counter()

        return SearchStats(
            time_ms=(end_time - start_time) * 1000,
            visited_cells=visited,
            path_length=len(path) if path else 0,
            path_found=len(path) > 0,
            strategy_name=self._strategy.name
        )