"""
Session management for the AKShare CLI harness.

Tracks state across commands in REPL mode: last result, history, preferences.
"""

import json
import os
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional

import pandas as pd


class Session:
    """Manages CLI session state including result history and preferences."""

    def __init__(self, session_dir: Optional[str] = None):
        self._history: List[Dict[str, Any]] = []
        self._last_result: Optional[pd.DataFrame] = None
        self._last_function: Optional[str] = None
        self._preferences: Dict[str, Any] = {
            "output_format": "table",
            "max_rows": 50,
            "show_index": False,
        }
        self._session_dir = session_dir or os.path.join(
            os.path.expanduser("~"), ".akshare-cli"
        )
        self._start_time = datetime.now()

    @property
    def last_result(self) -> Optional[pd.DataFrame]:
        """Get the last query result."""
        return self._last_result

    @property
    def last_function(self) -> Optional[str]:
        """Get the name of the last function called."""
        return self._last_function

    @property
    def history(self) -> List[Dict[str, Any]]:
        """Get command history."""
        return list(self._history)

    @property
    def preferences(self) -> Dict[str, Any]:
        """Get current session preferences."""
        return dict(self._preferences)

    def record_call(self, func_name: str, kwargs: Dict, result: Any) -> None:
        """Record a function call in the session history."""
        entry = {
            "timestamp": datetime.now().isoformat(),
            "function": func_name,
            "kwargs": kwargs,
            "rows": len(result) if isinstance(result, pd.DataFrame) else None,
            "columns": list(result.columns) if isinstance(result, pd.DataFrame) else None,
        }
        self._history.append(entry)

        if isinstance(result, pd.DataFrame):
            self._last_result = result
        self._last_function = func_name

    def set_preference(self, key: str, value: Any) -> None:
        """Set a session preference."""
        self._preferences[key] = value

    def get_preference(self, key: str, default: Any = None) -> Any:
        """Get a session preference."""
        return self._preferences.get(key, default)

    def save_history(self, filepath: Optional[str] = None) -> str:
        """Save session history to a JSON file."""
        if filepath is None:
            os.makedirs(self._session_dir, exist_ok=True)
            filepath = os.path.join(
                self._session_dir,
                f"session_{self._start_time.strftime('%Y%m%d_%H%M%S')}.json",
            )

        data = {
            "start_time": self._start_time.isoformat(),
            "end_time": datetime.now().isoformat(),
            "preferences": self._preferences,
            "history": self._history,
        }

        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False, default=str)

        return filepath

    def clear(self) -> None:
        """Clear session state."""
        self._history.clear()
        self._last_result = None
        self._last_function = None

    def summary(self) -> Dict[str, Any]:
        """Get a summary of the current session."""
        return {
            "start_time": self._start_time.isoformat(),
            "total_calls": len(self._history),
            "last_function": self._last_function,
            "last_result_shape": (
                f"{self._last_result.shape[0]}x{self._last_result.shape[1]}"
                if self._last_result is not None
                else None
            ),
            "preferences": self._preferences,
        }
