"""L6 Capability API：对外能力接口（SendResult + WeChatCapabilities）。

P1 阶段：WeChatCapabilities.send_text 委托给旧 xdotool_driver.send_text，
把返回的 local_send_id 包成 SendResult(success=True, verified=True)。
P3 阶段：替换为 FlowOrchestrator.send_text，统一走状态机 + DB 校验 + 幂等。
"""

from __future__ import annotations

import logging
from dataclasses import dataclass, field
from typing import Optional

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


@dataclass
class SendResult:
    """发送文本结果。

    所有字段带默认值，避免构造时必填字段顺序问题。
    diagnostics 用 field(default=None) + Optional 避免可变默认值陷阱。

    Attributes:
        success: 是否成功（含校验通过）
        local_id: 本地生成的消息 ID（如 local_<unix>_<rand>）
        verified: 是否经 DB 校验确认（P1 阶段默认 True，P3 接入真实校验）
        skipped: 是否因幂等命中而跳过实际发送
        error: 错误描述（成功时为空）
        error_code: 错误码（如 WINDOW_NOT_FOUND / SEND_TIMEOUT）
        retryable: 是否可安全重试
        diagnostics: 诊断信息字典（trace_id / image_confidence / duration_ms 等）
    """

    success: bool = False
    local_id: str = ""
    verified: bool = False
    skipped: bool = False
    error: str = ""
    error_code: str = ""
    retryable: bool = False
    diagnostics: Optional[dict] = field(default=None)


class WeChatCapabilities:
    """L6 对外能力 API：业务层（路由 / outbox）通过此类调用 UI 自动化。

    P1 阶段：xdotool_driver 非空、orchestrator 为 None，send_text 委托给
    旧 xdotool_driver.send_text，包成 SendResult。
    P3 阶段：orchestrator 非空、xdotool_driver 为 None，send_text 委托给
    FlowOrchestrator.send_text（TODO: P3 时统一走 orchestrator）。
    """

    def __init__(self, xdotool_driver=None, orchestrator=None) -> None:
        """初始化能力 API。

        Args:
            xdotool_driver: 旧 XdotoolDriver 实例（P1 阶段非空）
            orchestrator: P3 阶段的 FlowOrchestrator 实例（P1 阶段为 None）
        """
        self.xdotool_driver = xdotool_driver
        self.orchestrator = orchestrator

    async def send_text(
        self,
        to_wxid: str,
        content: str,
        display_name: Optional[str] = None,
        client_request_id: str = "",
    ) -> SendResult:
        """发送文本消息。

        P1 阶段：若 orchestrator 非空则委托 orchestrator.send_text；
        否则调 xdotool_driver.send_text，把返回的 local_send_id 包成
        SendResult(success=True, local_id=..., verified=True)。

        TODO: P3 时统一走 orchestrator，移除 xdotool_driver 分支。

        Args:
            to_wxid: 目标 wxid
            content: 文本内容
            display_name: 用于搜索定位会话的显示名（备注/昵称/微信号）
            client_request_id: 幂等键维度（P1 阶段忽略，P3 接入 IdemCache）

        Returns:
            SendResult：发送结果
        """
        # TODO: P3 时统一走 orchestrator
        if self.orchestrator is not None:
            return await self.orchestrator.send_text(
                to_wxid=to_wxid,
                content=content,
                display_name=display_name,
                client_request_id=client_request_id,
            )

        # P1 阶段：委托给旧 xdotool_driver
        if self.xdotool_driver is None:
            return SendResult(
                success=False,
                error="no backend available (xdotool_driver and orchestrator both None)",
                error_code="BRIDGE_NOT_INITIALIZED",
                retryable=False,
            )

        try:
            local_send_id = await self.xdotool_driver.send_text(
                to_wxid=to_wxid,
                content=content,
                display_name=display_name,
            )
            return SendResult(
                success=True,
                local_id=str(local_send_id),
                verified=True,
            )
        except Exception as exc:
            logger.error(
                "[capability] send_text failed to=%s: %s", to_wxid, exc
            )
            return SendResult(
                success=False,
                error=str(exc),
                error_code="SEND_FAILED",
                retryable=True,
            )
