import time
from dataclasses import dataclass
from typing import List, Optional, Tuple
from models import Cell, Maze
from strategies import PathFindingStrategy


@dataclass
class SearchStats:
    """Статистика поиска"""
    time_ms: float
    visited_cells: int
    path_length: int
    path_found: bool = True
    
    def __str__(self) -> str:
        if not self.path_found:
            return f"Путь не найден (время: {self.time_ms:.2f} мс)"
        return (f"Время: {self.time_ms:.2f} мс, "
                f"Посещено клеток: {self.visited_cells}, "
                f"Длина пути: {self.path_length}")


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) -> Tuple[List[Cell], SearchStats]:
        """Выполняет поиск пути с текущей стратегией"""
        if self._strategy is None:
            raise ValueError("Стратегия не установлена")
        
        start_time = time.perf_counter()
        path = self._strategy.find_path(self.maze, self.maze.start, self.maze.exit)
        end_time = time.perf_counter()
        
        time_ms = (end_time - start_time) * 1000
        
        stats = SearchStats(
            time_ms=time_ms,
            visited_cells=len(path) if path else 0,
            path_length=len(path) if path else 0,
            path_found=bool(path)
        )
        
        return path, stats