import sys
from pathlib import Path
from dotenv import load_dotenv



load_dotenv()

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import RedirectResponse
from contextlib import asynccontextmanager

from api import router


# ============================================================
# 应用生命周期
# ============================================================

@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用启动/关闭时的生命周期管理"""
    import threading

    print("=" * 60)
    print("  煤矿通风数据智能解读系统 启动中...")
    print("=" * 60)

    # === 关键优化：在后台线程预热 Agent，不阻塞 uvicorn 启动 ===
    # 原因：create_deep_agent 需要导入 langchain/langgraph 并编译状态图，
    # 首次执行耗时可达数分钟，阻塞 uvicorn 等待 lifespan 完成后才接受请求。
    # 改为后台预热后，服务可以在几秒内就绪，Agent 在后台慢慢初始化。
    #
    # 首次请求如果 Agent 还没预热完，routes.py 中的 get_xxx_agent() 会触发懒加载，
    # 第一个请求会稍慢（等待编译完成），后续请求就是热实例直接用了。

    agent_ready = threading.Event()

    def _warmup_agents():
        """后台线程：预热 Agent 实例"""
        try:
            from agents.vent_agent import get_click_agent, get_dialog_agent
            print("[启动] 后台预热点选解读 Agent...（不阻塞服务就绪）")
            get_click_agent()
            print("[启动] 后台预热对话解读 Agent...（不阻塞服务就绪）")
            get_dialog_agent()

            # ── 预热配风计划审查 Agent（消除首次请求的图编译开销）──
            from agents.review_agent import (
                get_form_review_agent,
                get_data_consistency_agent,
                get_calc_verification_agent,
                get_summary_agent,
            )
            print("[启动] 后台预热形式审查 Agent...")
            get_form_review_agent()
            print("[启动] 后台预热数据一致性审查 Agent...")
            get_data_consistency_agent()
            print("[启动] 后台预热计算核验审查 Agent...")
            get_calc_verification_agent()
            print("[启动] 后台预热汇总审查 Agent...")
            get_summary_agent()

            print("[启动] Agent 预热完成，服务已完全就绪")
        except Exception as e:
            print(f"[警告] Agent 预初始化失败（将在首次请求时懒加载）: {e}")
        finally:
            agent_ready.set()

    threading.Thread(target=_warmup_agents, daemon=True, name="agent-warmup").start()

    print("[启动] 服务已就绪（Agent 后台预热中），监听 http://0.0.0.0:8000")
    print("[启动] API 文档: http://localhost:8000/docs")
    print("=" * 60)

    yield

    # 关闭时清理
    print("[关闭] 服务停止")


# ============================================================
# 创建 FastAPI 应用
# ============================================================

app = FastAPI(
    title="煤矿通风数据智能解读系统",
    description="""
基于 DeepAgents 框架的煤矿通风监测数据智能解读服务。

## 功能

- **点选数据解读**: 对单条巷道监测数据进行深度合规分析
- **对话式数据解读**: 通过自然语言对话查询和分析通风数据
- **聊天历史**: 查询和管理对话历史记录

## 技术栈

- DeepAgents (LangChain) - Agent 编排
- FastAPI - Web 框架
- SQLite - 聊天历史存储
- SSE - 流式响应
    """,
    version="1.0.0",
    lifespan=lifespan,
)

# CORS 配置（允许前端跨域访问）
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(router)

# 静态文件服务（审查报告 .docx 下载）
_static_dir = Path(__file__).parent / "static"
_static_dir.mkdir(parents=True, exist_ok=True)
(_static_dir / "reports").mkdir(exist_ok=True)
app.mount("/static", StaticFiles(directory=str(_static_dir)), name="static")


# ============================================================
# 根路由 → Chat UI
# ============================================================

@app.get("/")
async def root():
    """根路径重定向到聊天界面"""
    return RedirectResponse(url="/static/index.html")


# ============================================================
# 健康检查
# ============================================================

@app.get("/health")
async def health_check():
    """健康检查接口"""
    return {
        "status": "ok",
        "service": "煤矿通风数据智能解读系统",
        "version": "1.0.0",
    }


# ============================================================
# 直接运行入口
# ============================================================

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8070,
        reload=True,
        log_level="info",
    )
