from __future__ import annotations

import json
import os
from datetime import datetime
from typing import Any, Optional

from diona.project.storage.storage import ProjectStorage


class MiddlewareStorage:
    _instance: Any = None

    def __new__(cls) -> MiddlewareStorage:
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance

    def __init__(self):
        if self._initialized:
            return

        self._storage = ProjectStorage()
        self._module_name = "agent"
        self._relative_path = "middleware"
        self._ensure_directory()
        self._initialized = True

    def _ensure_directory(self):
        path = self._get_full_path()
        os.makedirs(path, exist_ok=True)

    def _get_full_path(self) -> str:
        return self._storage.get_path(self._module_name, self._relative_path, "user")

    def save(self, context: Any) -> str:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
        filename = f"{timestamp}.json"

        data = context.to_storage_json()
        content = json.dumps(data, ensure_ascii=False, indent=2)

        full_path = os.path.join(self._get_full_path(), filename)

        try:
            with open(full_path, 'w', encoding='utf-8') as f:
                f.write(content)
        except Exception as e:
            print(f"Error saving log: {e}")

        return filename

    def list_logs(self) -> list[str]:
        path = self._get_full_path()
        if not os.path.exists(path):
            return []

        files = [f for f in os.listdir(path) if f.endswith('.json')]
        files.sort(reverse=True)
        return files

    def read_log(self, filename: str) -> dict | None:
        full_path = os.path.join(self._get_full_path(), filename)
        try:
            with open(full_path, 'r', encoding='utf-8') as f:
                content = f.read()
                return json.loads(content)
        except Exception:
            return None

    def save_with_metadata(self, metadata: dict) -> str:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
        filename = f"{timestamp}_gk.json"

        data = {
            "type": "global_knowledge",
            "timestamp": timestamp,
            **metadata
        }
        content = json.dumps(data, ensure_ascii=False, indent=2)

        full_path = os.path.join(self._get_full_path(), filename)

        try:
            with open(full_path, 'w', encoding='utf-8') as f:
                f.write(content)
        except Exception as e:
            print(f"Error saving log: {e}")

        return filename


_storage: Optional[MiddlewareStorage] = None


def get_middleware_storage() -> MiddlewareStorage:
    global _storage
    if _storage is None:
        _storage = MiddlewareStorage()
    return _storage
