"""
SessionService - сервис управления сессией
"""
from datetime import datetime
from pathlib import Path
from typing import Optional, Callable
from models.astro_object import AstroObject
from models.session import Session
from services.file_service import FileService


class SessionService:
    """Сервис для управления сессией наблюдения"""

    def __init__(self):
        self._current_session: Optional[Session] = None
        self._file_service = FileService()

    def start_session(self, watch_folder: Path, object_name: str, camera: str, optics: str) -> Session:
        """Начинает новую сессию"""
        start_time = datetime.now()
        self._current_session = Session(
            camera=camera,
            optics=optics,
            start_time=start_time
        )

        session_folder = watch_folder / self._current_session.get_session_name()
        session_folder.mkdir(parents=True, exist_ok=True)
        self._current_session.session_folder = session_folder

        self._log_session_event(f"Session started at {start_time}")
        self._log_session_event(f"Camera: {camera}")
        self._log_session_event(f"Optics: {optics}")

        self.create_new_object(object_name)
        return self._current_session

    def create_new_object(self, object_name: str) -> AstroObject:
        """Создаёт новый объект съёмки"""
        if not self._current_session:
            raise ValueError("Session not started")

        if self._current_session.get_current_object():
            current_obj = self._current_session.get_current_object()
            self._log_session_event(f"Object finished: {current_obj.name}, photos: {current_obj.photo_count}")

        object_folder = self._current_session.session_folder / object_name
        object_folder.mkdir(parents=True, exist_ok=True)

        astro_object = AstroObject(
            name=object_name,
            folder=object_folder,
            photo_count=0
        )

        self._current_session.add_object(astro_object)
        self._log_session_event(f"New object: {object_name}")
        return astro_object

    def handle_file(self, file_path: Path) -> bool:
        """Обрабатывает новый файл: перемещает в папку текущего объекта с переименованием"""
        if not self._current_session:
            return False

        current_object = self._current_session.get_current_object()
        if not current_object:
            return False

        # Передаём имя объекта для переименования файла
        success = self._file_service.move_file(
            file_path,
            current_object.folder,
            self._current_session.camera,
            self._current_session.optics,
            current_object.name  # Добавляем имя объекта для переименования
        )

        if success:
            current_object.increment_photo_count()

        return success

    def move_remaining_files(self, watch_folder: Path, on_file_moved: Optional[Callable] = None) -> int:
        """Перемещает все существующие файлы из папки наблюдения"""
        if not self._current_session:
            return 0

        current_object = self._current_session.get_current_object()
        if not current_object:
            return 0

        count = 0
        if watch_folder.exists():
            for file_path in watch_folder.iterdir():
                if file_path.is_file() and self._file_service.is_photo(file_path):
                    success = self._file_service.move_file(
                        file_path,
                        current_object.folder,
                        self._current_session.camera,
                        self._current_session.optics,
                        current_object.name  # Добавляем имя объекта для переименования
                    )
                    if success:
                        current_object.increment_photo_count()
                        count += 1
                        if on_file_moved:
                            on_file_moved(file_path)
        return count

    def finish_session(self) -> Session:
        """Завершает сессию"""
        if not self._current_session:
            raise ValueError("No active session")

        self._current_session.finish()

        self._log_session_event(f"Session finished at {self._current_session.end_time}")
        self._log_session_event("=== SESSION SUMMARY ===")
        for obj in self._current_session.objects:
            self._log_session_event(f"Object: {obj.name}, Photos: {obj.photo_count}")

        return self._current_session

    def get_current_session(self) -> Optional[Session]:
        return self._current_session

    def get_current_object(self) -> Optional[AstroObject]:
        if self._current_session:
            return self._current_session.get_current_object()
        return None

    def get_current_object_folder(self) -> Optional[Path]:
        current_obj = self.get_current_object()
        return current_obj.folder if current_obj else None

    def change_camera(self, camera: str):
        if self._current_session:
            self._current_session.camera = camera
            self._log_session_event(f"Camera changed to: {camera}")

    def change_optics(self, optics: str):
        if self._current_session:
            self._current_session.optics = optics
            self._log_session_event(f"Optics changed to: {optics}")

    def _log_session_event(self, message: str):
        if self._current_session and self._current_session.session_folder:
            log_file = self._current_session.session_folder / "SessionLog.txt"
            timestamp = datetime.now()
            line = f"{timestamp} - {message}\n"
            try:
                with open(log_file, 'a', encoding='utf-8') as f:
                    f.write(line)
            except Exception as e:
                print(f"Ошибка записи лога: {e}")

    def is_active(self) -> bool:
        return self._current_session is not None and self._current_session.is_active()