from __future__ import annotations

import asyncio
import logging
import time

from fastapi import APIRouter

from woc_bridge.config import _state, _require_xdotool, _require_db_reader
from woc_bridge.db.coordinator import with_db_retry, _resolve_db_state
from woc_bridge.models import StatusResponse
from woc_bridge.version import BRIDGE_VERSION, BRIDGE_CAPABILITIES, MEDIA_SUPPORTED

logger = logging.getLogger("woc-bridge")
router = APIRouter()


@router.get("/api/status", response_model=StatusResponse)
@with_db_retry
async def get_status() -> StatusResponse:
    """聚合返回 bridge 运行状态。

    一次请求内完成 4 类检测：进程运行、窗口存在、登录态、DB 可达性，
    并返回当前账号信息与客户端轮询建议参数。所有调用方（channels 适配器、
    面板健康检查、诊断 autofix）都应优先调本接口判断前置条件。

    Returns:
        StatusResponse：含 bridge_version / wechat_running / wechat_window_found
        / login_state / db_accessible / current_wxid / current_nickname
        / uptime_seconds / display / max_batch_size / poll_interval_ms

    Notes:
        - 不抛业务错误：即使微信未运行 / DB 加密，也返回 200 + 对应 false 字段，
          让调用方按字段判定下一步动作（而非按 HTTP 状态码）
        - login_state 内联判定（不调 detect_login_state），避免重复 pgrep/xdotool
        - DB 加密时细分：有 key 且验证过 → encrypted_key_ok + db_accessible=true；
          无 key 且自动提取未启用 → encrypted_no_key；
          自动提取已尝试但失败 → key_extract_failed；
          二者 db_accessible 均为 false
        - current_wxid/nickname 仅在 db_accessible=true 且 login_state=logged_in
          时才尝试读 DB，失败静默为空字符串
    """
    xdotool = _require_xdotool()
    db_reader = _require_db_reader()

    # 一次 status 请求内复用 pgrep/xdotool 结果，避免重复调用
    wechat_running = await xdotool.is_wechat_running()
    window_id = await xdotool.find_wechat_window() if wechat_running else None
    wechat_window_found = window_id is not None
    # 登录态内联判定，避免 detect_login_state 内部再次 pgrep/xdotool search
    if not wechat_running:
        login_state = "not_running"
    elif not wechat_window_found:
        login_state = "not_logged_in"
    else:
        login_state = "logged_in"

    # DB 状态：统一走 _resolve_db_state（不触发自动提取，仅解析）
    db_state = await _resolve_db_state()
    db_accessible = db_state.db_accessible
    db_error_code = db_state.db_error_code
    init_in_progress = _state.init_state.state == "running"
    init_progress_pct = _state.init_state.progress_pct
    init_message = _state.init_state.message

    # current_wxid / current_nickname：从 DB 读，失败为空
    current_wxid = ""
    current_nickname = ""
    if db_accessible and login_state == "logged_in":
        try:
            self_info = await asyncio.to_thread(db_reader.get_self_info)
            current_wxid = self_info.get("wxid", "")
            current_nickname = self_info.get("nickname", "")
        except Exception:
            current_wxid = ""
            current_nickname = ""

    uptime_seconds = time.monotonic() - _state.start_time

    return StatusResponse(
        bridge_version=BRIDGE_VERSION,
        wechat_running=wechat_running,
        wechat_window_found=wechat_window_found,
        login_state=login_state,
        db_accessible=db_accessible,
        db_error_code=db_error_code,
        init_in_progress=init_in_progress,
        init_progress_pct=init_progress_pct,
        init_message=init_message,
        current_wxid=current_wxid,
        current_nickname=current_nickname,
        uptime_seconds=uptime_seconds,
        display=_state.config.display,
        max_batch_size=_state.config.max_batch_size,
        poll_interval_ms=_state.config.poll_interval_ms,
        send_queue_pending=_state.send_queue.pending_count() if _state.send_queue else 0,
        media_supported=MEDIA_SUPPORTED,
        bridge_capabilities=list(BRIDGE_CAPABILITIES),
    )
