"""
AI Decision API
================
CAI-101: OpenClaw 自動化立案 API

Endpoints:
- POST /api/v1/ai/analyze-and-propose

流程:
1. 拉取當前監控數據 (host_aggregator)
2. 交給 OpenClaw AI 分析
3. 若需要修復 → 自動建立 ApprovalRecord
4. 前端戰情室即時拉取待簽核卡片
"""

from fastapi import APIRouter, HTTPException, status

from src.core.logging import get_logger
from src.core.trust_engine import get_trust_engine
from src.models.ai import (
    AIRiskLevel,
    OpenClawAnalysisRequest,
    OpenClawAnalysisResponse,
    OpenClawDecision,
    SuggestedAction,
)
from src.models.approval import (
    ApprovalRequestCreate,
    BlastRadius,
    DataImpact,
    DryRunCheck,
    RiskLevel,
)
from src.services.host_aggregator import HostAggregator
from src.services.openclaw import get_openclaw

router = APIRouter(prefix="/ai", tags=["AI Decision"])
logger = get_logger("awoooi.ai")


# =============================================================================
# Helper Functions
# =============================================================================

def _map_risk_level(ai_risk: AIRiskLevel) -> RiskLevel:
    """將 AI 風險等級轉換為 Approval 風險等級"""
    mapping = {
        AIRiskLevel.LOW: RiskLevel.LOW,
        AIRiskLevel.MEDIUM: RiskLevel.MEDIUM,
        AIRiskLevel.CRITICAL: RiskLevel.CRITICAL,
    }
    return mapping.get(ai_risk, RiskLevel.MEDIUM)


def _build_action_string(decision: OpenClawDecision) -> str:
    """根據決策建構操作字串"""
    action_map = {
        SuggestedAction.RESTART_DEPLOYMENT: f"Restart deployment {decision.target_resource} -n {decision.namespace}",
        SuggestedAction.DELETE_POD: f"kubectl delete pod {decision.target_resource} -n {decision.namespace}",
        SuggestedAction.SCALE_DEPLOYMENT: f"Scale deployment {decision.target_resource} -n {decision.namespace}",
        SuggestedAction.NO_ACTION: "No action required",
    }
    return action_map.get(decision.suggested_action, str(decision.suggested_action))


def _create_approval_from_decision(decision: OpenClawDecision) -> ApprovalRequestCreate:
    """從 AI 決策建立授權請求"""
    return ApprovalRequestCreate(
        action=_build_action_string(decision),
        description=decision.reasoning,
        risk_level=_map_risk_level(decision.risk_level),
        blast_radius=BlastRadius(
            affected_pods=1,
            estimated_downtime="~30s",
            related_services=decision.affected_services,
            data_impact=DataImpact.NONE,
        ),
        dry_run_checks=[
            DryRunCheck(
                name="AI Confidence",
                passed=decision.confidence >= 0.7,
                message=f"{decision.confidence:.0%}",
            ),
            DryRunCheck(
                name="Risk Assessment",
                passed=True,
                message=decision.risk_level.value.upper(),
            ),
        ],
        requested_by="OpenClaw",
    )


# =============================================================================
# Endpoints
# =============================================================================

@router.post(
    "/analyze-and-propose",
    response_model=OpenClawAnalysisResponse,
    summary="AI 分析並自動立案",
    description="拉取當前監控數據，交給 OpenClaw 分析。若判定需要修復，自動建立 ApprovalRecord。",
)
async def analyze_and_propose(
    request: OpenClawAnalysisRequest | None = None,
) -> OpenClawAnalysisResponse:
    """
    AI 智能分析與自動立案

    流程:
    1. 從 host_aggregator 取得最新狀態
    2. 交給 OpenClaw AI 分析
    3. 解析 JSON 結構化輸出
    4. 若 suggested_action != NO_ACTION → 建立 ApprovalRecord
    """
    logger.info("ai_analyze_start")

    # Step 1: 取得監控數據
    try:
        snapshot = await HostAggregator.fetch_all()

        # 轉換為 OpenClaw 需要的格式 (含基準線數據)
        host_statuses = {}
        for host in snapshot.hosts:
            # 組裝 metrics 與 baseline
            metrics_data = {}
            if host.metrics:
                metrics_data = {
                    "cpu_percent": host.metrics.cpu_percent,
                    "memory_percent": host.metrics.memory_percent,
                    "cpu_baseline": {
                        "baseline_value": host.metrics.cpu_baseline.baseline_value,
                        "std_deviation": host.metrics.cpu_baseline.std_deviation,
                        "sigma_deviation": host.metrics.cpu_baseline.sigma_deviation,
                    } if host.metrics.cpu_baseline else None,
                    "memory_baseline": {
                        "baseline_value": host.metrics.memory_baseline.baseline_value,
                        "std_deviation": host.metrics.memory_baseline.std_deviation,
                        "sigma_deviation": host.metrics.memory_baseline.sigma_deviation,
                    } if host.metrics.memory_baseline else None,
                }

            host_statuses[host.name] = {
                "ip": host.ip,
                "status": host.status,
                "services": [
                    {
                        "name": svc.name,
                        "port": svc.port,
                        "status": svc.status,
                        "latency_ms": svc.latency_ms,
                    }
                    for svc in host.services
                ],
                "metrics": metrics_data,
            }

        logger.info(
            "ai_monitoring_data_fetched",
            host_count=len(host_statuses),
            overall_status=snapshot.overall_status,
        )

    except Exception as e:
        logger.error(
            "ai_monitoring_fetch_failed",
            error=str(e),
        )
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail=f"Failed to fetch monitoring data: {str(e)}",
        ) from e

    # Step 2: 呼叫 OpenClaw AI
    try:
        openclaw = get_openclaw()
        decision, provider, raw_response = await openclaw.analyze(host_statuses)

        logger.info(
            "ai_analysis_complete",
            provider=provider,
            has_decision=decision is not None,
        )

    except Exception as e:
        logger.error(
            "ai_analysis_failed",
            error=str(e),
        )
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail=f"AI analysis failed: {str(e)}",
        ) from e

    # Step 3: 處理決策
    if decision is None:
        return OpenClawAnalysisResponse(
            success=False,
            message="AI 分析完成，但無法解析決策輸出。請檢查 LLM 回應格式。",
            ai_provider=provider,
            raw_llm_response=raw_response[:500] if raw_response else None,
        )

    # Step 4: 判斷是否需要建立 Approval
    if decision.suggested_action == SuggestedAction.NO_ACTION:
        logger.info(
            "ai_no_action_needed",
            reasoning=decision.reasoning,
        )
        return OpenClawAnalysisResponse(
            success=True,
            message="AI 判斷目前無需採取行動。",
            decision=decision,
            approval_created=False,
            ai_provider=provider,
        )

    # Step 5: 建立 ApprovalRecord
    try:
        approval_create = _create_approval_from_decision(decision)
        engine = get_trust_engine()
        approval = engine.create_approval(approval_create)

        logger.info(
            "ai_approval_created",
            approval_id=str(approval.id),
            action=decision.suggested_action.value,
            target=decision.target_resource,
            risk_level=decision.risk_level.value,
        )

        return OpenClawAnalysisResponse(
            success=True,
            message=f"OpenClaw 已建立待簽核卡片：{decision.suggested_action.value} {decision.target_resource}",
            decision=decision,
            approval_created=True,
            approval_id=str(approval.id),
            ai_provider=provider,
        )

    except Exception as e:
        logger.error(
            "ai_approval_create_failed",
            error=str(e),
        )
        return OpenClawAnalysisResponse(
            success=False,
            message=f"AI 分析成功，但建立授權請求失敗：{str(e)}",
            decision=decision,
            approval_created=False,
            ai_provider=provider,
        )


@router.get(
    "/status",
    summary="AI 服務狀態",
    description="檢查 OpenClaw AI 服務狀態與可用的 AI 提供者。",
)
async def get_ai_status() -> dict:
    """檢查 AI 服務狀態"""
    from src.core.config import settings

    return {
        "fallback_order": settings.AI_FALLBACK_ORDER,
        "ollama_url": settings.OLLAMA_URL,
        "gemini_configured": bool(settings.GEMINI_API_KEY),
        "claude_configured": bool(settings.CLAUDE_API_KEY),
    }
