"""
Telegram Gateway API - OpenClaw 行動簽核通道
=============================================
Phase 5.4: Telegram Gateway 整合
Phase 5.5: Long Polling 重構 (內網修復)

架構變更 (2026-03-22):
- 舊: Webhook 模式 (需外網可達) - 已廢除
- 新: Long Polling 模式 (主動輪詢) - 適用內網環境

Endpoints:
- POST /api/v1/telegram/webhook - [已棄用] 接收 Telegram Bot Update
- POST /api/v1/telegram/test-push - 測試推送 (僅開發模式)
- GET /api/v1/telegram/health - Gateway 健康檢查

安全鐵律:
- 所有簽核必須通過 SecurityInterceptor 驗證
- 只有白名單內的 user_id 可以簽核
- 每個 Nonce 只能使用一次
"""

from uuid import UUID

from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel

from src.core.config import settings
from src.core.logging import get_logger
from src.services.approval_db import get_approval_service
from src.services.security_interceptor import (
    NonceReplayError,
    UserNotWhitelistedError,
)
from src.services.telegram_gateway import TelegramGatewayError, get_telegram_gateway

logger = get_logger("awoooi.telegram")
router = APIRouter(prefix="/telegram", tags=["Telegram"])


# =============================================================================
# Request Models
# =============================================================================

class TelegramUpdate(BaseModel):
    """
    Telegram Bot API Update

    簡化版本，僅處理 callback_query (簽核按鈕點擊)
    """
    update_id: int
    callback_query: dict | None = None
    message: dict | None = None


class TestPushRequest(BaseModel):
    """測試推送請求 (僅開發模式)"""
    approval_id: str
    risk_level: str = "medium"
    resource_name: str = "test-pod-123"
    root_cause: str = "Test alert for development"
    suggested_action: str = "DELETE_POD"
    estimated_downtime: str = "~30s"


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

@router.post(
    "/webhook",
    summary="[已棄用] Telegram Bot Webhook",
    description="⚠️ 已棄用：內網環境請使用 Long Polling 模式。此端點保留供外網環境或測試使用。",
    deprecated=True,
)
async def telegram_webhook(
    update: TelegramUpdate,
) -> dict:
    """
    接收 Telegram Bot Update

    處理流程:
    1. 驗證 Update 類型 (僅處理 callback_query)
    2. 安全驗證 (白名單 + Nonce)
    3. 解析簽核動作 (approve/reject)
    4. 更新資料庫
    5. 回應 Telegram
    """
    logger.info("telegram_webhook_received", update_id=update.update_id)

    # =========================================================================
    # Step 1: 僅處理 callback_query (簽核按鈕點擊)
    # =========================================================================
    if not update.callback_query:
        logger.debug("telegram_webhook_ignored", reason="not callback_query")
        return {"ok": True, "message": "Ignored (not callback_query)"}

    callback = update.callback_query
    callback_query_id = callback.get("id")
    callback_data = callback.get("data")
    user = callback.get("from", {})
    user_id = user.get("id")
    username = user.get("username") or user.get("first_name") or str(user_id)
    message = callback.get("message", {})
    message_id = message.get("message_id")
    original_text = message.get("text", "")

    if not all([callback_query_id, callback_data, user_id]):
        logger.warning("telegram_webhook_invalid", reason="missing required fields")
        return {"ok": False, "message": "Invalid callback data"}

    # =========================================================================
    # Step 2: 安全驗證 + 處理回調
    # =========================================================================
    try:
        gateway = get_telegram_gateway()
        result = await gateway.handle_callback(
            callback_query_id=callback_query_id,
            callback_data=callback_data,
            user_id=user_id,
            message_id=message_id,
            original_text=original_text,
            username=username,
        )

        if not result.get("success"):
            return {"ok": False, "message": result.get("error")}

        # =====================================================================
        # Step 3: 更新資料庫 (簽核/拒絕)
        # =====================================================================
        action = result["action"]
        approval_id = result["approval_id"]
        _telegram_user = result["user"]  # reserved for future audit logging

        service = get_approval_service()

        # 2026-03-29 ogt: 修復方法呼叫 - add_signature/reject 不存在
        # 正確方法: sign_approval / reject_approval
        if action == "approve":
            approval, msg, execution_triggered = await service.sign_approval(
                approval_id=UUID(approval_id),
                signer_id=f"tg_{user_id}",
                signer_name=user.get("username") or user.get("first_name") or str(user_id),
                comment="Telegram 簽核",
            )

            if approval:
                logger.info(
                    "telegram_approval_signed",
                    approval_id=approval_id,
                    user_id=user_id,
                    status=approval.status.value,
                    execution_triggered=execution_triggered,
                )

                return {
                    "ok": True,
                    "message": "Approved",
                    "approval_id": approval_id,
                    "status": approval.status.value,
                    "execution_triggered": execution_triggered,
                }

        elif action == "reject":
            approval, msg = await service.reject_approval(
                approval_id=UUID(approval_id),
                rejector_id=f"tg_{user_id}",
                rejector_name=user.get("username") or str(user_id),
                reason="Telegram 拒絕",
            )

            if approval:
                logger.info(
                    "telegram_approval_rejected",
                    approval_id=approval_id,
                    user_id=user_id,
                )

                return {
                    "ok": True,
                    "message": "Rejected",
                    "approval_id": approval_id,
                    "status": approval.status.value,
                }

        return {"ok": False, "message": "Unknown action"}

    except UserNotWhitelistedError as e:
        logger.warning("telegram_webhook_denied", user_id=user_id, error=str(e))
        return {"ok": False, "message": "User not authorized"}

    except NonceReplayError as e:
        logger.warning("telegram_webhook_replay", error=str(e))
        return {"ok": False, "message": "Already processed"}

    except Exception as e:
        logger.error("telegram_webhook_error", error=str(e))
        return {"ok": False, "message": str(e)}


@router.post(
    "/test-push",
    summary="測試推送 (僅開發模式)",
    description="測試推送簽核卡片到 Telegram (僅在 dev 環境可用)",
)
async def test_push(
    request: TestPushRequest,
) -> dict:
    """
    測試推送簽核卡片到 Telegram

    僅在開發模式下可用
    """
    # 生產環境禁止
    if settings.ENVIRONMENT == "prod":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Test push is disabled in production",
        )

    try:
        gateway = get_telegram_gateway()

        result = await gateway.send_approval_card(
            approval_id=request.approval_id,
            risk_level=request.risk_level,
            resource_name=request.resource_name,
            root_cause=request.root_cause,
            suggested_action=request.suggested_action,
            estimated_downtime=request.estimated_downtime,
        )

        return {
            "ok": True,
            "message": "Test push sent",
            "telegram_response": result,
        }

    except TelegramGatewayError as e:
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY,
            detail=f"Telegram API error: {str(e)}",
        ) from e


@router.get(
    "/health",
    summary="Telegram Gateway 健康檢查",
)
async def telegram_health() -> dict:
    """Telegram Gateway 健康狀態 (含 Long Polling 狀態)"""
    gateway = get_telegram_gateway()

    return {
        "status": "configured" if settings.OPENCLAW_TG_BOT_TOKEN else "not_configured",
        "mode": "long_polling",  # Phase 5.5: 已從 webhook 切換至 long_polling
        "polling_active": gateway._polling_active,
        "bot_token_set": bool(settings.OPENCLAW_TG_BOT_TOKEN),
        "chat_id_set": bool(settings.OPENCLAW_TG_CHAT_ID),
        "whitelist_count": len(settings.OPENCLAW_TG_USER_WHITELIST),
        "last_update_id": gateway._last_update_id,
        "environment": settings.ENVIRONMENT,
    }
