import logging
import time
from fastapi import APIRouter, Depends, HTTPException, Request
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.models.user import User
from app.routers.auth import get_current_user
from app.schemas.settings import (
    SettingsOut, ProfileUpdateIn, LLMConfigIn, SchedulerConfigIn, LLMTestIn
)
from app.services.log_service import LogService
from app.services.settings_service import (
    get_user_settings, update_user_profile, update_llm_config,
    update_scheduler_config, test_llm_connection
)
from app.logging_utils import summarize_llm_config

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/settings", tags=["设置"])


@router.get("", response_model=SettingsOut)
async def get_settings(
    request: Request,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    request.state.user_id = current_user.id
    settings = await get_user_settings(current_user.id, db)
    if not settings:
        raise HTTPException(status_code=404, detail="用户不存在")

    await LogService(db).system_log(
        message="加载用户设置",
        source="settings",
        user_id=current_user.id,
        request_id=request.state.request_id,
        route=request.url.path,
        method=request.method,
        status_code=200,
        operation="settings.get",
        details={"llm_config": summarize_llm_config(settings.get("llm_config"))},
    )
    return settings


@router.put("/profile")
async def update_profile(
    data: ProfileUpdateIn,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    try:
        user = await update_user_profile(
            current_user.id, db,
            full_name=data.full_name,
            password=data.password,
            current_password=data.current_password
        )
        return user
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.put("/llm")
async def update_llm(
    data: LLMConfigIn,
    request: Request,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    request.state.user_id = current_user.id
    log_service = LogService(db)
    start = time.perf_counter()
    payload = data.model_dump(exclude_none=True)
    try:
        config = await update_llm_config(current_user.id, payload, db)
        await log_service.system_log(
            message="更新 LLM 配置成功",
            source="settings",
            user_id=current_user.id,
            request_id=request.state.request_id,
            route=request.url.path,
            method=request.method,
            status_code=200,
            operation="settings.update_llm",
            duration_ms=int((time.perf_counter() - start) * 1000),
            details={
                "request": summarize_llm_config(payload),
                "stored": summarize_llm_config(config),
            },
        )
        return {"llm_config": config}
    except ValueError as e:
        await log_service.system_log(
            message="更新 LLM 配置失败",
            level="warning",
            source="settings",
            user_id=current_user.id,
            request_id=request.state.request_id,
            route=request.url.path,
            method=request.method,
            status_code=400,
            error_type=e.__class__.__name__,
            operation="settings.update_llm",
            duration_ms=int((time.perf_counter() - start) * 1000),
            details={"request": summarize_llm_config(payload), "detail": str(e)},
        )
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/llm/test")
async def test_llm(
    data: LLMTestIn,
    request: Request,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    request.state.user_id = current_user.id
    start = time.perf_counter()
    result = await test_llm_connection(
        provider=data.provider,
        model=data.model,
        base_url=data.base_url,
        api_key=data.api_key
    )
    await LogService(db).system_log(
        message="测试 LLM 连接",
        level="info" if result.get("success") else "warning",
        source="settings",
        user_id=current_user.id,
        request_id=request.state.request_id,
        route=request.url.path,
        method=request.method,
        status_code=200,
        error_type=None if result.get("success") else "llm_test_failed",
        operation="settings.test_llm",
        duration_ms=int((time.perf_counter() - start) * 1000),
        details={
            "provider": data.provider,
            "model": data.model,
            "has_base_url": bool(data.base_url),
            "has_api_key": bool(data.api_key),
            "success": result.get("success"),
            "error": result.get("error"),
        },
    )
    return result


@router.put("/scheduler")
async def update_scheduler(
    data: SchedulerConfigIn,
    request: Request,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    request.state.user_id = current_user.id
    payload = data.model_dump(exclude_none=True)
    try:
        config = await update_scheduler_config(
            current_user.id,
            payload,
            db
        )
        await LogService(db).system_log(
            message="更新调度配置成功",
            source="settings",
            user_id=current_user.id,
            request_id=request.state.request_id,
            route=request.url.path,
            method=request.method,
            status_code=200,
            operation="settings.update_scheduler",
            details={"request": payload, "stored": config},
        )
        return {"scheduler_config": config}
    except ValueError as e:
        await LogService(db).system_log(
            message="更新调度配置失败",
            level="warning",
            source="settings",
            user_id=current_user.id,
            request_id=request.state.request_id,
            route=request.url.path,
            method=request.method,
            status_code=400,
            error_type=e.__class__.__name__,
            operation="settings.update_scheduler",
            details={"request": payload, "detail": str(e)},
        )
        raise HTTPException(status_code=400, detail=str(e))
