from typing import Optional, Dict, Any

from fastapi import APIRouter, Query, HTTPException
from tortoise.transactions import in_transaction

from app.models.cleaning import ProxyConfig, ProxyProvider
from app.schemas.base import Success, SuccessExtra


proxy_router = APIRouter()


@proxy_router.get("/configs")
async def list_proxy_configs(
    name: Optional[str] = Query(None, description="名称"),
    platform: Optional[str] = Query(None, description="平台标识"),
    proxy_type: Optional[str] = Query(None, description="代理类型: http/socks/tunnel"),
    is_active: Optional[bool] = Query(None, description="是否启用"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=200, description="每页数量"),
):
    qs = ProxyConfig.all()
    if name:
        qs = qs.filter(name__icontains=name)
    if platform:
        qs = qs.filter(platform=platform)
    if proxy_type:
        qs = qs.filter(proxy_type=proxy_type)
    if is_active is not None:
        qs = qs.filter(is_active=is_active)
    total = await qs.count()
    items = await qs.order_by("-id").offset((page - 1) * page_size).limit(page_size)
    data = [
        {
            "id": item.id,
            "name": item.name,
            "proxy_type": item.proxy_type,
            "platform": item.platform,
            "proxy_url": item.proxy_url,
            "is_active": item.is_active,
            "created_at": item.created_at,
            "updated_at": item.updated_at,
        }
        for item in items
    ]
    return SuccessExtra(data=data, total=total, page=page, page_size=page_size)


@proxy_router.post("/configs")
async def create_proxy_config(payload: Dict[str, Any]):
    try:
        async with in_transaction():
            item = await ProxyConfig.create(
                name=payload.get("name"),
                proxy_type=payload.get("proxy_type"),
                platform=payload.get("platform", "all"),
                proxy_url=payload.get("proxy_url"),
                is_active=bool(payload.get("is_active", True)),
            )
        return Success(data={"id": item.id})
    except Exception as exc:
        raise HTTPException(status_code=400, detail=str(exc))


@proxy_router.put("/configs/{config_id}")
async def update_proxy_config(config_id: int, payload: Dict[str, Any]):
    item = await ProxyConfig.get_or_none(id=config_id)
    if not item:
        raise HTTPException(status_code=404, detail="Proxy config not found")
    for field in ["name", "proxy_type", "platform", "proxy_url", "is_active"]:
        if field in payload:
            setattr(item, field, payload[field])
    await item.save()
    return Success(data={"id": item.id})


@proxy_router.delete("/configs/{config_id}")
async def delete_proxy_config(config_id: int):
    item = await ProxyConfig.get_or_none(id=config_id)
    if not item:
        raise HTTPException(status_code=404, detail="Proxy config not found")
    await item.delete()
    return Success(data={"id": config_id})


@proxy_router.get("/providers")
async def list_proxy_providers(
    name: Optional[str] = Query(None, description="名称"),
    platform: Optional[str] = Query(None, description="平台标识"),
    mode: Optional[str] = Query(None, description="解析模式"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=200, description="每页数量"),
):
    qs = ProxyProvider.all()
    if name:
        qs = qs.filter(name__icontains=name)
    if platform:
        qs = qs.filter(platform=platform)
    if mode:
        qs = qs.filter(mode=mode)
    total = await qs.count()
    items = await qs.order_by("-id").offset((page - 1) * page_size).limit(page_size)
    data = [
        {
            "id": item.id,
            "name": item.name,
            "platform": item.platform,
            "mode": item.mode,
            "list_path": item.list_path,
            "ip_path": item.ip_path,
            "port_path": item.port_path,
            "username_path": item.username_path,
            "password_path": item.password_path,
            "pattern": item.pattern,
            "template": item.template,
            "created_at": item.created_at,
            "updated_at": item.updated_at,
        }
        for item in items
    ]
    return SuccessExtra(data=data, total=total, page=page, page_size=page_size)


@proxy_router.post("/providers")
async def create_proxy_provider(payload: Dict[str, Any]):
    try:
        async with in_transaction():
            item = await ProxyProvider.create(
                name=payload.get("name"),
                platform=payload.get("platform", "all"),
                mode=payload.get("mode", "json"),
                list_path=payload.get("list_path"),
                ip_path=payload.get("ip_path"),
                port_path=payload.get("port_path"),
                username_path=payload.get("username_path"),
                password_path=payload.get("password_path"),
                pattern=payload.get("pattern"),
                template=payload.get("template"),
            )
        return Success(data={"id": item.id})
    except Exception as exc:
        raise HTTPException(status_code=400, detail=str(exc))


@proxy_router.put("/providers/{provider_id}")
async def update_proxy_provider(provider_id: int, payload: Dict[str, Any]):
    item = await ProxyProvider.get_or_none(id=provider_id)
    if not item:
        raise HTTPException(status_code=404, detail="Proxy provider not found")
    for field in [
        "name",
        "platform",
        "mode",
        "list_path",
        "ip_path",
        "port_path",
        "username_path",
        "password_path",
        "pattern",
        "template",
    ]:
        if field in payload:
            setattr(item, field, payload[field])
    await item.save()
    return Success(data={"id": item.id})


@proxy_router.delete("/providers/{provider_id}")
async def delete_proxy_provider(provider_id: int):
    item = await ProxyProvider.get_or_none(id=provider_id)
    if not item:
        raise HTTPException(status_code=404, detail="Proxy provider not found")
    await item.delete()
    return Success(data={"id": provider_id})
