#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
智能体导入/导出
"""
import logging
from typing import Any, Dict, List, Optional

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from ai_platform.models import Agent, AIWorkflow, LLMModel
from ai_platform.knowledge.models import KnowledgeBase

logger = logging.getLogger(__name__)


class AgentImportExportException(Exception):
    """智能体导入导出异常"""
    pass


async def export_config(db: AsyncSession, agent_id: str) -> Dict[str, Any]:
    """导出智能体配置（外部引用使用 code / model_name）"""
    result = await db.execute(
        select(Agent).where(
            Agent.id == agent_id,
            Agent.is_deleted == False,
        )
    )
    agent = result.scalar_one_or_none()
    if not agent:
        raise AgentImportExportException("智能体不存在")

    model_name = ""
    if agent.model_id:
        model_result = await db.execute(
            select(LLMModel.model_name).where(
                LLMModel.id == agent.model_id,
                LLMModel.is_deleted == False,
            )
        )
        row = model_result.first()
        if row:
            model_name = row[0] or ""

    workflow_code = ""
    if agent.workflow_id:
        wf_result = await db.execute(
            select(AIWorkflow.code).where(
                AIWorkflow.id == agent.workflow_id,
                AIWorkflow.is_deleted == False,
            )
        )
        row = wf_result.first()
        if row:
            workflow_code = row[0] or ""

    knowledge_base_codes: List[str] = []
    kb_ids = agent.knowledge_base_ids or []
    if kb_ids:
        kb_result = await db.execute(
            select(KnowledgeBase.code).where(
                KnowledgeBase.id.in_(kb_ids),
                KnowledgeBase.is_deleted == False,
            )
        )
        knowledge_base_codes = [row[0] for row in kb_result if row[0]]

    return {
        "name": agent.name,
        "code": agent.code,
        "description": agent.description or "",
        "avatar": agent.avatar or "",
        "mode": agent.mode or "autonomous",
        "is_global": agent.is_global or False,
        "persona": agent.persona or {},
        "system_prompt": agent.system_prompt or "",
        "model_name": model_name,
        "temperature": agent.temperature if agent.temperature is not None else 0.7,
        "top_p": agent.top_p if agent.top_p is not None else 1.0,
        "max_tokens": agent.max_tokens or 4096,
        "max_iterations": agent.max_iterations or 10,
        "welcome_message": agent.welcome_message or "",
        "suggested_questions": agent.suggested_questions or [],
        "workflow_code": workflow_code,
        "knowledge_base_codes": knowledge_base_codes,
        "knowledge_config": agent.knowledge_config or {},
        "enable_memory": agent.enable_memory or False,
        "memory_window": agent.memory_window or 10,
        "enable_streaming": (
            agent.enable_streaming if agent.enable_streaming is not None else True
        ),
        "is_public": agent.is_public or False,
    }


async def check_import(db: AsyncSession, code: str) -> Dict[str, Any]:
    """导入预检查：编码是否冲突"""
    code_exists = False
    if code:
        result = await db.execute(
            select(Agent).where(
                Agent.code == code,
                Agent.is_deleted == False,
            )
        )
        code_exists = result.scalar_one_or_none() is not None

    return {
        "code_exists": code_exists,
        "can_import": not code_exists,
    }


async def _resolve_model_id(db: AsyncSession, model_name: str) -> Optional[str]:
    if not model_name:
        return None
    result = await db.execute(
        select(LLMModel.id).where(
            LLMModel.model_name == model_name,
            LLMModel.is_deleted == False,
            LLMModel.is_active == True,
        ).limit(1)
    )
    row = result.first()
    return row[0] if row else None


async def _resolve_workflow_id(db: AsyncSession, workflow_code: str) -> Optional[str]:
    if not workflow_code:
        return None
    result = await db.execute(
        select(AIWorkflow.id).where(
            AIWorkflow.code == workflow_code,
            AIWorkflow.is_deleted == False,
        )
    )
    row = result.first()
    return row[0] if row else None


async def _resolve_knowledge_base_ids(
    db: AsyncSession,
    codes: List[str],
) -> tuple[List[str], List[str]]:
    if not codes:
        return [], []
    result = await db.execute(
        select(KnowledgeBase.id, KnowledgeBase.code).where(
            KnowledgeBase.code.in_(codes),
            KnowledgeBase.is_deleted == False,
        )
    )
    code_to_id = {row.code: row.id for row in result}
    resolved_ids = []
    unresolved: List[str] = []
    for code in codes:
        if code in code_to_id:
            resolved_ids.append(code_to_id[code])
        else:
            unresolved.append(code)
    return resolved_ids, unresolved


async def import_config(db: AsyncSession, data: Dict[str, Any]) -> Agent:
    """导入智能体配置"""
    required_fields = ["name", "code"]
    for field in required_fields:
        if not data.get(field):
            raise AgentImportExportException(f"缺少必要字段: {field}")

    exists = await db.execute(
        select(Agent).where(
            Agent.code == data["code"],
            Agent.is_deleted == False,
        )
    )
    if exists.scalar_one_or_none():
        raise AgentImportExportException(f"智能体编码已存在: {data['code']}")

    model_id = await _resolve_model_id(db, data.get("model_name") or "")
    if data.get("model_name") and not model_id:
        logger.warning("导入智能体时未找到模型: %s", data.get("model_name"))

    workflow_id = await _resolve_workflow_id(db, data.get("workflow_code") or "")
    if data.get("workflow_code") and not workflow_id:
        logger.warning("导入智能体时未找到工作流: %s", data.get("workflow_code"))

    kb_codes = data.get("knowledge_base_codes") or []
    knowledge_base_ids, unresolved_kb = await _resolve_knowledge_base_ids(db, kb_codes)
    if unresolved_kb:
        logger.warning(
            "导入智能体时部分知识库未找到: %s",
            ", ".join(unresolved_kb),
        )

    agent = Agent(
        application_id=data.get("application_id"),
        is_global=data.get("is_global", False),
        name=data["name"],
        code=data["code"],
        description=data.get("description", ""),
        avatar=data.get("avatar", ""),
        mode=data.get("mode", "autonomous"),
        status="draft",
        persona=data.get("persona") or {},
        system_prompt=data.get("system_prompt", ""),
        model_id=model_id,
        temperature=data.get("temperature", 0.7),
        top_p=data.get("top_p", 1.0),
        max_tokens=data.get("max_tokens", 4096),
        max_iterations=data.get("max_iterations", 10),
        welcome_message=data.get("welcome_message", ""),
        suggested_questions=data.get("suggested_questions") or [],
        workflow_id=workflow_id,
        knowledge_base_ids=knowledge_base_ids,
        knowledge_config=data.get("knowledge_config") or {},
        enable_memory=data.get("enable_memory", False),
        memory_window=data.get("memory_window", 10),
        enable_streaming=data.get("enable_streaming", True),
        is_public=data.get("is_public", False),
    )
    db.add(agent)
    await db.flush()
    await db.refresh(agent)

    logger.info("智能体导入成功: %s", agent.code)
    return agent
