"""
会话管理系统
实现 SessionInfo 数据结构和持久化管理器

消息持久化已移至 DefaultContext（JSONL 格式），
此模块仅管理会话元信息。
"""

from dataclasses import dataclass, field
from typing import Optional, List, Dict, Any
from datetime import datetime
from pathlib import Path
import uuid
import json

from .logger import log_event


# ============================================================================
# Session 数据结构
# ============================================================================

@dataclass
class SessionInfo:
    """会话信息"""
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    slug: str = ""
    project_id: str = ""
    directory: str = field(default_factory=lambda: str(Path.cwd()))
    parent_id: Optional[str] = None
    title: str = "New Session"
    version: str = "1.1.0"

    # 时间信息
    created_at: datetime = field(default_factory=datetime.now)
    updated_at: datetime = field(default_factory=datetime.now)
    compacting_at: Optional[datetime] = None
    archived_at: Optional[datetime] = None

    # 权限配置
    permission: Optional[List[Dict[str, Any]]] = None

    # 回滚信息
    revert: Optional[Dict[str, Any]] = None

    # 会话摘要
    summary: Optional[Dict[str, Any]] = None

    # 分享信息
    share: Optional[Dict[str, str]] = None

    def to_dict(self) -> Dict[str, Any]:
        return {
            "id": self.id,
            "slug": self.slug,
            "project_id": self.project_id,
            "directory": self.directory,
            "parent_id": self.parent_id,
            "title": self.title,
            "version": self.version,
            "created_at": self.created_at.isoformat(),
            "updated_at": self.updated_at.isoformat(),
            "compacting_at": self.compacting_at.isoformat() if self.compacting_at else None,
            "archived_at": self.archived_at.isoformat() if self.archived_at else None,
            "permission": self.permission,
            "revert": self.revert,
            "summary": self.summary,
            "share": self.share,
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "SessionInfo":
        if "created_at" in data and isinstance(data["created_at"], str):
            data["created_at"] = datetime.fromisoformat(data["created_at"])
        if "updated_at" in data and isinstance(data["updated_at"], str):
            data["updated_at"] = datetime.fromisoformat(data["updated_at"])
        if data.get("compacting_at"):
            data["compacting_at"] = datetime.fromisoformat(data["compacting_at"])
        if data.get("archived_at"):
            data["archived_at"] = datetime.fromisoformat(data["archived_at"])
        return cls(**data)


# ============================================================================
# 存储层
# ============================================================================

class SessionStorage:
    """会话存储"""

    def __init__(self, storage_dir: Optional[Path] = None):
        if storage_dir:
            self.storage_dir = storage_dir
        else:
            from .paths import get_path_manager
            self.storage_dir = get_path_manager().get_data_dir() / "sessions"
        self.storage_dir.mkdir(parents=True, exist_ok=True)

    def save_session(self, session: SessionInfo) -> None:
        session_dir = self.storage_dir / session.id
        session_dir.mkdir(parents=True, exist_ok=True)
        session_file = session_dir / f"{session.id}.json"
        with open(session_file, "w", encoding="utf-8") as f:
            json.dump(session.to_dict(), f, indent=2, ensure_ascii=False)

    def load_session(self, session_id: str) -> Optional[SessionInfo]:
        session_file = self.storage_dir / session_id / f"{session_id}.json"
        if not session_file.exists():
            return None
        with open(session_file, "r", encoding="utf-8") as f:
            data = json.load(f)
        return SessionInfo.from_dict(data)

    def list_sessions(self) -> List[SessionInfo]:
        sessions = []
        for session_dir in self.storage_dir.iterdir():
            if not session_dir.is_dir():
                continue
            session_file = session_dir / f"{session_dir.name}.json"
            if not session_file.exists():
                continue
            try:
                with open(session_file, "r", encoding="utf-8") as f:
                    data = json.load(f)
                sessions.append(SessionInfo.from_dict(data))
            except Exception as e:
                log_event("session_load_error", file=str(session_file), error=str(e))
                continue
        sessions.sort(key=lambda s: s.updated_at, reverse=True)
        return sessions

    def delete_session(self, session_id: str) -> bool:
        session_dir = self.storage_dir / session_id
        if session_dir.exists():
            import shutil
            shutil.rmtree(session_dir)
            return True
        return False


# ============================================================================
# 会话管理器（持久化）
# ============================================================================

class PersistentSessionManager:
    """会话管理器（仅管理会话元信息）"""

    def __init__(self):
        self.session_storage = SessionStorage()

    def create_session(
        self,
        title: str = "New Session",
        directory: Optional[str] = None,
        parent_id: Optional[str] = None,
        permission: Optional[List[Dict[str, Any]]] = None,
        session_id: Optional[str] = None,
    ) -> SessionInfo:
        session = SessionInfo(
            id=session_id if session_id else str(uuid.uuid4()),
            title=title,
            directory=directory or str(Path.cwd()),
            parent_id=parent_id,
            permission=permission,
        )
        session.slug = self._generate_slug(session.title)
        self.session_storage.save_session(session)
        return session

    def get_session(self, session_id: str) -> Optional[SessionInfo]:
        return self.session_storage.load_session(session_id)

    def update_session(self, session: SessionInfo) -> None:
        session.updated_at = datetime.now()
        self.session_storage.save_session(session)

    def list_sessions(self) -> List[SessionInfo]:
        return self.session_storage.list_sessions()

    def delete_session(self, session_id: str) -> bool:
        return self.session_storage.delete_session(session_id)

    def _generate_slug(self, title: str) -> str:
        import re
        slug = title.lower()
        slug = re.sub(r'[^\w\s-]', '', slug)
        slug = re.sub(r'[-\s]+', '-', slug)
        return slug[:50]


# ============================================================================
# 全局实例
# ============================================================================

_session_manager: Optional[PersistentSessionManager] = None


def get_session_manager() -> PersistentSessionManager:
    """获取全局会话管理器"""
    global _session_manager
    if _session_manager is None:
        _session_manager = PersistentSessionManager()
    return _session_manager
