"""``POST /deep_dive`` —— 单次跑 TradingAgents 风格研究链路。

D-8b 范围：同步调用，单 deep dive < 90s（DeepSeek API + 2 analyst + 1 manager）。
D-9+ 升级 async + jobId + polling/WS（ADR-0002 §长任务）。
"""
from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Depends, Header
from inalpha_shared.auth import User, get_current_user
from inalpha_shared.errors import UnauthorizedError

from ..config import ResearchSettings, get_research_settings
from ..data_client import DataClient
from ..factor_client import FactorClient
from ..llm.client import (
    LanguageScopedClient,
    build_llm_client,
    infer_output_language,
)
from ..runner import run_deep_dive
from ..schemas import DeepDiveRequest, ResearchPlan

router = APIRouter(tags=["research"])


@router.post("/deep_dive", response_model=ResearchPlan)
async def post_deep_dive(
    req: DeepDiveRequest,
    settings: Annotated[ResearchSettings, Depends(get_research_settings)],
    _user: Annotated[User, Depends(get_current_user)],
    authorization: Annotated[str | None, Header()] = None,
) -> ResearchPlan:
    """跑研究：每次都新建 LLM + DataClient（D-8b 单次，连接池等 D-9 再加）。"""
    if not authorization or not authorization.startswith("Bearer "):
        raise UnauthorizedError("missing Authorization header")
    user_token = authorization.removeprefix("Bearer ").strip()

    llm = build_llm_client(
        provider=settings.llm_provider,
        api_key=settings.effective_api_key,
        base_url=settings.effective_base_url,
        model=settings.llm_model,
        timeout_seconds=settings.llm_timeout_seconds,
        max_concurrent=settings.llm_max_concurrent,
        max_retries=settings.llm_max_retries,
        retry_base_seconds=settings.llm_retry_base_seconds,
    )
    # Fix C：输出语言 = 显式 language 优先，否则从 user_question 兜底推断（防 orchestrator
    # 漏传 language 时研究结果跑去英文、再把最终报告带跑）。两者都缺才保持模型默认。
    output_language = req.language or infer_output_language(req.user_question)
    if output_language:
        llm = LanguageScopedClient(llm, output_language)

    try:
        # factor-service 透传同一 user_token（factor 再转发给 data /bars）；
        # 服务不可达时 analyst 内部降级，不影响主链路。
        async with (
            DataClient(settings.data_service_url, user_token) as data,
            FactorClient(settings.factor_service_url, user_token) as factor,
        ):
            return await run_deep_dive(req, llm=llm, data=data, factor=factor)
    finally:
        await llm.aclose()
