"""连接管理工具."""
from __future__ import annotations

from typing import Optional

from .. import client as es_client
from ..config import (
    get_cached_es_version,
    load_connections,
    load_profile,
    load_safety,
    update_profile_connection_version,
    update_profile_last_connection,
)
from ..models import (
    ConnectionConfig,
    ConnectionItem,
    EsVersionInfo,
    SafetyConfig,
    SessionState,
)

# 全局会话状态
_session_state: SessionState = SessionState()


def get_session_state() -> SessionState:
    """获取会话状态."""
    return _session_state


def get_current_connection_config() -> ConnectionConfig:
    """获取当前连接配置."""
    if not _session_state.current_connection:
        raise ValueError("当前没有选中的连接，请先调用 select_connection")

    connections = load_connections()
    for conn in connections:
        if conn.name == _session_state.current_connection:
            return conn

    raise ValueError(f"未找到连接: {_session_state.current_connection}")


def list_connections() -> list[ConnectionItem]:
    """列出所有配置的连接."""
    connections = load_connections()
    return [
        ConnectionItem(
            name=conn.name,
            env=conn.env,
            description=conn.description,
        )
        for conn in connections
    ]


def get_current_connection() -> Optional[str]:
    """获取当前连接名."""
    return _session_state.current_connection


def select_connection(name: str) -> dict:
    """
    选择连接并获取版本信息.
    返回连接信息和版本
    """
    global _session_state

    # 查找连接配置
    connections = load_connections()
    conn_config = None
    for conn in connections:
        if conn.name == name:
            conn_config = conn
            break

    if not conn_config:
        available = [c.name for c in connections]
        raise ValueError(f"未找到连接: {name}，可用: {', '.join(available)}")

    # 创建 ES 客户端
    es_client_conn = es_client.create_client(conn_config)

    # 检查是否有缓存版本
    cached_version = get_cached_es_version(name)

    if cached_version:
        es_version_info = cached_version
    else:
        # 连接并获取版本
        es_version_info = es_client.get_es_version(es_client_conn)
        # 缓存版本
        update_profile_connection_version(name, es_version_info)

    # 加载 safety 配置
    safety = load_safety(conn_config.env)

    # 更新会话状态
    _session_state = SessionState(
        current_connection=name,
        env=conn_config.env,
        es_version=es_version_info.version,
        es_version_info=es_version_info,
        safety=safety,
    )

    # 保存最后使用的连接
    update_profile_last_connection(name)

    return {
        "name": name,
        "env": conn_config.env,
        "description": conn_config.description,
        "es_version": es_version_info.version,
        "es_version_info": f"{es_version_info.major}.{es_version_info.minor}.{es_version_info.patch}",
        "safety": {
            "read_only": safety.read_only,
            "max_search_size": safety.max_search_size,
            "confirm_delete": safety.confirm_delete,
            "allow_delete_index": safety.allow_delete_index,
            "allow_create_index": safety.allow_create_index,
            "risk_check": safety.risk_check,
        },
    }


def get_es_client() -> es_client.Elasticsearch:
    """获取当前 ES 客户端."""
    config = get_current_connection_config()
    es_version = get_es_version()
    return es_client.create_client(config, es_version=es_version)


def get_es_version() -> int:
    """获取当前 ES 版本."""
    if not _session_state.es_version:
        raise ValueError("当前没有选中的连接")
    return _session_state.es_version


def get_safety() -> SafetyConfig:
    """获取当前安全配置."""
    if not _session_state.safety:
        raise ValueError("当前没有选中的连接")
    return _session_state.safety


def auto_select_connection() -> Optional[dict]:
    """
    自动选择上次使用的连接.
    用于启动时恢复会话.
    如果上次连接为空或不在列表中，使用第一个连接.
    """
    profile = load_profile()
    connections = load_connections()

    # 确定要连接的名称
    target_name = profile.last_connection

    # 如果上次连接为空或不在列表中，使用第一个连接
    if not target_name or target_name not in [c.name for c in connections]:
        if connections:
            target_name = connections[0].name
        else:
            return None

    try:
        return select_connection(target_name)
    except Exception:
        # 如果选中的连接失败，尝试第一个
        if connections and target_name != connections[0].name:
            try:
                return select_connection(connections[0].name)
            except Exception:
                pass
        return None
