"""Chat session persistence — auto-named by timestamp, JSON storage."""

from __future__ import annotations

import json
import logging
from dataclasses import asdict, dataclass, field
from datetime import UTC, datetime
from pathlib import Path

from redhat_oracle.core.config import OracleConfig, get_data_dir

logger = logging.getLogger(__name__)


@dataclass
class ChatMessage:
    """A single chat message."""

    role: str  # "user" or "assistant"
    content: str
    sources: list[dict[str, str]] = field(default_factory=list)
    timestamp: str = ""

    def __post_init__(self) -> None:
        if not self.timestamp:
            self.timestamp = datetime.now(UTC).isoformat()


@dataclass
class ChatSession:
    """A chat session with message history."""

    name: str
    messages: list[ChatMessage] = field(default_factory=list)
    created_at: str = ""

    def __post_init__(self) -> None:
        if not self.created_at:
            self.created_at = datetime.now(UTC).isoformat()

    def add_message(
        self,
        role: str,
        content: str,
        sources: list[dict[str, str]] | None = None,
    ) -> ChatMessage:
        """Add a message to the session."""
        msg = ChatMessage(role=role, content=content, sources=sources or [])
        self.messages.append(msg)
        return msg

    def get_history(self, max_messages: int | None = None) -> list[ChatMessage]:
        """Get message history, optionally limited to last N messages."""
        if max_messages is None:
            return list(self.messages)
        return list(self.messages[-max_messages:])


def _sessions_dir(config: OracleConfig) -> Path:
    """Return the sessions directory."""
    path = get_data_dir(config) / "sessions"
    path.mkdir(parents=True, exist_ok=True)
    return path


def save_session(session: ChatSession, config: OracleConfig) -> Path:
    """Save a session to JSON.

    Returns:
        Path to the saved session file.
    """
    sessions_dir = _sessions_dir(config)
    file_path = sessions_dir / f"{session.name}.json"

    data = {
        "name": session.name,
        "created_at": session.created_at,
        "messages": [asdict(msg) for msg in session.messages],
    }

    file_path.write_text(json.dumps(data, indent=2))
    logger.info("Session saved: %s", file_path)
    return file_path


def load_session(name: str, config: OracleConfig) -> ChatSession | None:
    """Load a session from JSON by name.

    Returns:
        ChatSession or None if not found.
    """
    sessions_dir = _sessions_dir(config)
    file_path = sessions_dir / f"{name}.json"

    if not file_path.exists():
        return None

    data = json.loads(file_path.read_text())
    session = ChatSession(
        name=data["name"],
        created_at=data.get("created_at", ""),
    )
    for msg_data in data.get("messages", []):
        session.messages.append(ChatMessage(**msg_data))

    return session


def load_latest_session(config: OracleConfig) -> ChatSession | None:
    """Load the most recent session.

    Returns:
        ChatSession or None if no sessions exist.
    """
    sessions_dir = _sessions_dir(config)
    files = sorted(sessions_dir.glob("*.json"), key=lambda p: p.stat().st_mtime, reverse=True)

    if not files:
        return None

    name = files[0].stem
    return load_session(name, config)


def new_session(config: OracleConfig) -> ChatSession:
    """Create a new session named by timestamp."""
    name = datetime.now(UTC).strftime("%Y%m%d_%H%M%S")
    return ChatSession(name=name)


def list_sessions(config: OracleConfig) -> list[str]:
    """List all session names."""
    sessions_dir = _sessions_dir(config)
    return sorted(
        [f.stem for f in sessions_dir.glob("*.json")],
        reverse=True,
    )
