"""Agents Web API 客户端"""

import asyncio
import logging
from typing import Optional, Dict, Any, List

import aiohttp

from .config import AGENTS_HOST, AGENTS_EMAIL, AGENTS_PASSWORD

logger = logging.getLogger(__name__)


class WebAPIClient:
    """Agents Web API 客户端（基于 Session + CSRF）"""

    def __init__(
        self,
        host: str = AGENTS_HOST,
        email: str = AGENTS_EMAIL,
        password: str = AGENTS_PASSWORD,
    ):
        self.host = host.rstrip("/")
        self.email = email
        self.password = password
        self.session: Optional[aiohttp.ClientSession] = None
        self.csrf_token: Optional[str] = None

    async def __aenter__(self):
        # 创建 session 并启用 cookie jar
        self.session = aiohttp.ClientSession(
            cookie_jar=aiohttp.CookieJar(unsafe=True)
        )
        await self.login()
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        if self.session:
            await self.session.close()

    async def _get_csrf_token(self) -> str:
        """获取 CSRF Token"""
        url = f"{self.host}/api/csrf-token"
        async with self.session.get(url) as resp:
            data = await resp.json()
            if not data.get("success"):
                raise RuntimeError("获取 CSRF Token 失败")
            return data["token"]

    async def login(self):
        """登录到 Agents 系统"""
        # 获取 CSRF Token
        self.csrf_token = await self._get_csrf_token()
        logger.info("已获取 CSRF Token")

        # 登录
        url = f"{self.host}/login"
        headers = {"X-CSRF-Token": self.csrf_token}
        data = {"email": self.email, "password": self.password}

        async with self.session.post(url, json=data, headers=headers) as resp:
            result = await resp.json()
            if not result.get("success"):
                raise RuntimeError(f"登录失败: {result.get('error')}")
            logger.info(f"已登录为用户: {self.email}")

        # 刷新 CSRF Token
        self.csrf_token = await self._get_csrf_token()

    async def _request(
        self,
        method: str,
        endpoint: str,
        data: Optional[Dict[str, Any]] = None,
        params: Optional[Dict[str, Any]] = None,
    ) -> Dict[str, Any]:
        """发送请求到 Web API"""
        if not self.session:
            raise RuntimeError("Client not initialized")

        url = f"{self.host}{endpoint}"
        headers = {}
        if method.upper() not in {"GET", "HEAD", "OPTIONS", "TRACE"}:
            headers["X-CSRF-Token"] = self.csrf_token

        try:
            async with self.session.request(
                method, url, json=data, params=params, headers=headers
            ) as resp:
                if resp.status == 401:
                    # Session 过期，重新登录
                    logger.warning("Session 过期，重新登录")
                    await self.login()
                    # 重试请求
                    headers["X-CSRF-Token"] = self.csrf_token
                    async with self.session.request(
                        method, url, json=data, params=params, headers=headers
                    ) as retry_resp:
                        return await retry_resp.json()
                return await resp.json()
        except Exception as e:
            logger.error(f"Web API 请求失败: {e}")
            raise

    async def create_conversation(
        self, thinking_mode: bool = False, mode: str = "fast"
    ) -> Dict[str, Any]:
        """创建新对话"""
        data = {
            "preserve_mode": True,
            "mode": mode,
            "thinking_mode": thinking_mode,
        }
        return await self._request("POST", "/api/conversations", data)

    async def list_conversations(self, limit: int = 20, offset: int = 0) -> Dict[str, Any]:
        """获取对话列表"""
        params = {"limit": limit, "offset": offset}
        return await self._request("GET", "/api/conversations", params=params)

    async def load_conversation(self, conversation_id: str) -> Dict[str, Any]:
        """加载/切换对话"""
        return await self._request("PUT", f"/api/conversations/{conversation_id}/load")

    async def send_message(
        self,
        message: str,
        conversation_id: str,
        max_iterations: int = 100,
    ) -> Dict[str, Any]:
        """发送消息（创建任务）"""
        data = {
            "message": message,
            "conversation_id": conversation_id,
            "images": [],
            "videos": [],
            "model_key": None,
            "thinking_mode": None,
            "run_mode": None,
            "max_iterations": max_iterations,
        }
        return await self._request("POST", "/api/tasks", data)

    async def poll_task(self, task_id: str, from_offset: int = 0) -> Dict[str, Any]:
        """轮询任务事件"""
        params = {"from": from_offset}
        return await self._request("GET", f"/api/tasks/{task_id}", params=params)

    async def cancel_task(self, task_id: str) -> Dict[str, Any]:
        """取消任务"""
        return await self._request("POST", f"/api/tasks/{task_id}/cancel")
