"""
Vidu 回调路由
============

仅保留 Vidu 视频生成任务完成回调接口。
视频生成任务统一走 /tasks/video 创建，/tasks/{task_id} 轮询。

Vidu 任务完成后主动 POST 通知此接口。
回调更新 Async Engine TaskRegistry，供前端统一轮询。
"""

import logging

from fastapi import APIRouter, HTTPException, Request

from app.config import get_settings
from app.core.exceptions import PlatformError
from app.core.redis_client import get_redis_client
from app.platform_gateway import PlatformGateway
from app.schemas.common import success_response

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/vidu", tags=["Vidu"])


def get_platform_gateway(request: Request) -> PlatformGateway:
    """从 app.state 获取 PlatformGateway"""
    return request.app.state.platform_gateway


@router.post("/callback")
async def vidu_callback(request: Request):
    """
    Vidu 视频生成任务完成回调

    Vidu 任务完成后主动 POST 通知此接口。
    无需登录校验（Vidu 外部调用），统一走 PlatformGateway 处理。
    回调结果写入 Async Engine TaskRegistry，前端通过 /tasks/{task_id} 统一轮询。
    """
    # 1. 统一走 PlatformGateway 处理回调（签名验证 + nonce 防重放）
    gateway = request.app.state.platform_gateway
    body_bytes = await request.body()
    headers_dict = dict(request.headers)

    # 使用 APP_BASE_URL 构建 callback_url，确保与提交任务时传给 Vidu 的一致
    #（Nginx 反向代理可能导致 request.url 的 scheme 为 http，与 Vidu 签名时的 https 不一致）
    app_base_url = get_settings().app_base_url
    callback_url = f"{app_base_url}/api/v1/vidu/callback" if app_base_url else str(request.url)
    logger.info(f"[Vidu] 收到回调: request_url={request.url}, callback_url={callback_url}, body={body_bytes.decode('utf-8', errors='replace')[:500]}")

    try:
        task_status = await gateway.handle_webhook(
            platform="vidu",
            headers=headers_dict,
            body=body_bytes,
            secret=get_settings().VIDU_API_KEY,
            callback_url=callback_url,
        )
    except PlatformError as e:
        logger.warning(f"[Vidu] 回调验证失败: {e}")
        raise HTTPException(status_code=401, detail="回调签名验证失败")
    except Exception as e:
        logger.error(f"[Vidu] 回调处理失败: {e}")
        raise HTTPException(status_code=500, detail="回调处理失败，请稍后重试")

    logger.info(f"[Vidu] 回调解析完成: state={task_status.state}, result={task_status.result}, error={task_status.error_message}")

    # 2. 通过 platform_task_id 反查 Async Engine 内部 task_id，更新 TaskRegistry
    platform_task_id = (
        task_status.result.get("task_id") if task_status.result else None
    )
    video_url = (
        task_status.result.get("video_url") if task_status.result else None
    )

    logger.info(f"[Vidu] 准备反查 internal_task_id: platform_task_id={platform_task_id}")

    internal_task_id = None
    if platform_task_id:
        internal_task_id = await gateway.get_internal_task_id_by_platform_task_id(
            "vidu", platform_task_id
        )

    if internal_task_id:
        # 更新 Async Engine TaskRegistry，供前端统一轮询 /tasks/{task_id}
        #
        # ⚠️ 注意：此处仅更新任务状态，不执行积分扣费。
        # 视频生成的扣费在前端 VideoGeneration.tsx 拼接完成后执行。
        # 如果用户在 Vidu 任务提交后关闭应用，前端不会执行扣费，形成漏扣。
        # 当前接受此风险，详情见前端注释。
        from app.scheduler.registry import TaskRegistry

        registry = TaskRegistry(get_redis_client())
        task_record = await registry.get(internal_task_id)
        if task_record:
            if task_status.state == "completed":
                await registry.update(
                    internal_task_id,
                    status="completed",
                    progress=100,
                    message="视频生成完成",
                    completed=1,
                    total=1,
                    result={"video_url": video_url, "state": "success"},
                )
            elif task_status.state == "failed":
                await registry.update(
                    internal_task_id,
                    status="failed",
                    message="视频生成失败",
                    error=task_status.error_message or "视频生成失败",
                )
            logger.info(
                f"[Vidu] 回调已更新 TaskRegistry: task={internal_task_id}, "
                f"state={task_status.state}, video_url={video_url}"
            )
        else:
            logger.warning(
                f"[Vidu] 回调找不到对应任务记录: internal={internal_task_id}, "
                f"platform={platform_task_id}"
            )
    else:
        logger.warning(
            f"[Vidu] 回调无法反查内部 task_id: platform={platform_task_id}"
        )

    return success_response(message="回调已接收")
