# -*- coding: utf-8 -*-
# hub/ticket/state/repository.py

"""Файловый репозиторий Ticket для хранения задач."""

from __future__ import annotations

import json
from datetime import datetime
from pathlib import Path
from typing import Any

from error_logger import log_exception

from domain.task import TicketTask
from .paths import ensure_storage_directories


class TicketStateRepository:
    """Канонический файловый репозиторий состояния Ticket."""

    def __init__(self, tasks_file: Path):
        self._tasks_file = tasks_file
        ensure_storage_directories()
        self._tasks_file.parent.mkdir(parents=True, exist_ok=True)

    def load_tasks(self) -> list[TicketTask]:
        """Загрузить все задачи из хранилища."""
        try:
            if not self._tasks_file.exists():
                return []
            with open(self._tasks_file, "r", encoding="utf-8") as handle:
                raw_tasks = json.load(handle)
        except Exception as exc:
            log_exception(__name__, "TicketStateRepository.load_tasks", exc)
            return []

        if not isinstance(raw_tasks, list):
            return []

        tasks: list[TicketTask] = []
        for raw_task in raw_tasks:
            if not isinstance(raw_task, dict):
                continue
            task = TicketTask.from_record(raw_task)
            if task is not None:
                tasks.append(task)
        return tasks

    def save_tasks(self, tasks: list[TicketTask]) -> bool:
        """Сохранить все задачи в каноническое JSON-хранилище."""
        try:
            payload = [task.to_record() for task in tasks]
            with open(self._tasks_file, "w", encoding="utf-8") as handle:
                json.dump(
                    payload,
                    handle,
                    indent=2,
                    ensure_ascii=False,
                    default=self._json_serializer,
                )
        except Exception as exc:
            log_exception(__name__, "TicketStateRepository.save_tasks", exc)
            return False
        return True

    @staticmethod
    def _json_serializer(value: Any) -> str:
        """Сериализовать datetime и родственные значения для JSON."""
        if isinstance(value, datetime):
            return value.isoformat()
        raise TypeError(f"Object of type {type(value)} is not JSON serializable")
