import copy
import logging
from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.models.user import User
from app.services.auth_service import verify_password, get_password_hash
from app.logging_utils import summarize_llm_config

logger = logging.getLogger(__name__)


async def get_user_settings(user_id: str, db: AsyncSession) -> dict:
    """获取用户完整设置"""
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    if not user:
        return None
    return {
        "profile": user,
        "llm_config": user.llm_config or {},
        "scheduler_config": user.scheduler_config or {}
    }


async def update_user_profile(
    user_id: str,
    db: AsyncSession,
    full_name: Optional[str] = None,
    password: Optional[str] = None,
    current_password: Optional[str] = None
) -> User:
    """更新用户资料"""
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    if not user:
        raise ValueError("用户不存在")

    if password:
        if not current_password or not verify_password(current_password, user.hashed_password):
            raise ValueError("当前密码错误")
        user.hashed_password = get_password_hash(password)

    if full_name:
        user.full_name = full_name

    await db.commit()
    await db.refresh(user)
    return user


async def update_llm_config(user_id: str, config: dict, db: AsyncSession) -> dict:
    """更新 LLM 配置"""
    logger.info("update_llm_config called", extra={"details": {"keys": list(config.keys())}})
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    if not user:
        raise ValueError("用户不存在")

    # 创建深拷贝，避免 SQLAlchemy 变更检测问题
    current = copy.deepcopy(user.llm_config) or {}
    logger.info("llm_config before update", extra={"details": summarize_llm_config(current)})
    # 合并配置 - 直接替换整个类型配置列表
    for key, value in config.items():
        if value is not None:
            if isinstance(value, list):
                # 列表直接替换
                current[key] = value
            elif isinstance(value, dict):
                # 字典合并
                if key in current and isinstance(current[key], dict):
                    current[key] = {**current[key], **value}
                else:
                    current[key] = value
            else:
                current[key] = value
    logger.info("llm_config after update", extra={"details": summarize_llm_config(current)})
    user.llm_config = current
    await db.commit()
    await db.refresh(user)
    logger.info("user.llm_config after refresh", extra={"details": summarize_llm_config(user.llm_config)})
    return current


async def update_scheduler_config(user_id: str, config: dict, db: AsyncSession) -> dict:
    """更新定时任务配置"""
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    if not user:
        raise ValueError("用户不存在")

    current = user.scheduler_config or {}
    for key, value in config.items():
        if value is not None:
            current[key] = value
    user.scheduler_config = current
    await db.commit()
    return current


async def test_llm_connection(
    provider: str,
    model: str,
    base_url: str,
    api_key: str
) -> dict:
    """测试 LLM 连接"""
    try:
        # 根据不同 provider 创建临时 LLM 实例并测试
        if provider == "openai":
            from langchain_openai import ChatOpenAI
            llm = ChatOpenAI(
                api_key=api_key,
                model=model,
                base_url=base_url or None,
                timeout=30
            )
        elif provider == "claude":
            from langchain_anthropic import ChatAnthropic
            llm = ChatAnthropic(
                api_key=api_key,
                model=model,
                timeout=30
            )
        elif provider == "ollama":
            from langchain_ollama import ChatOllama
            llm = ChatOllama(
                base_url=base_url or "http://localhost:11434",
                model=model,
                timeout=30
            )
        elif provider == "deepseek":
            from langchain_openai import ChatOpenAI
            llm = ChatOpenAI(
                api_key=api_key,
                model=model,
                base_url=base_url or "https://api.deepseek.com/v1",
                timeout=30
            )
        else:
            return {"success": False, "error": f"不支持的 provider: {provider}"}

        # 简单测试调用
        from langchain_core.messages import HumanMessage
        response = await llm.ainvoke([HumanMessage(content="Hi")])
        return {"success": True, "message": f"连接成功，模型响应: {response.content[:50]}..."}
    except Exception as e:
        return {"success": False, "error": str(e)}
