"""DigitalOcean 适配器（REST API v2，Bearer Token）

API 文档：https://docs.digitalocean.com/reference/api/
所需配置：{"api_key": "..."}
"""

import httpx

from app.adapters.base import (
    AccountInfo,
    BaseAdapter,
    NormalizedDomain,
    NormalizedVPS,
)
from app.adapters.registry import register


@register("do-api")
class DigitalOceanAdapter(BaseAdapter):
    required_config = ["api_key"]
    BASE = "https://api.digitalocean.com/v2"

    def _headers(self) -> dict:
        return {"Authorization": f"Bearer {self.config.get('api_key', '')}"}

    def _get(self, path: str) -> dict:
        with httpx.Client(timeout=30) as client:
            resp = client.get(self.BASE + path, headers=self._headers())
            resp.raise_for_status()
            return resp.json()

    def test_connection(self) -> dict:
        try:
            data = self._get("/account")
            balance = data.get("account", {}).get("balance")
            return {"ok": True, "message": f"连接成功，账户余额 {balance} USD"}
        except httpx.HTTPStatusError as e:
            return {"ok": False, "message": f"HTTP {e.response.status_code}：Token 无效或权限不足"}
        except Exception as e:  # noqa: BLE001
            return {"ok": False, "message": str(e)}

    def get_account(self) -> AccountInfo:
        acc = self._get("/account").get("account", {})
        return AccountInfo(balance=acc.get("balance"), currency="USD", raw=acc)

    @staticmethod
    def _main_ip(droplet: dict) -> str:
        try:
            v4 = droplet.get("networks", {}).get("v4", [])
            return v4[0].get("ip_address") if v4 else None
        except Exception:  # noqa: BLE001
            return None

    def list_vps(self) -> list:
        result = []
        page = 1
        while True:
            data = self._get(f"/droplets?per_page=100&page={page}")
            for d in data.get("droplets", []):
                image = d.get("image", {})
                os_name = f"{image.get('distribution', '')} {image.get('name', '')}".strip()
                mem_mb = d.get("memory") or 0
                region = d.get("region", {})
                result.append(
                    NormalizedVPS(
                        external_id=str(d.get("id")),
                        name=d.get("name"),
                        ip_address=self._main_ip(d),
                        region=region.get("slug") or region.get("name"),
                        os=os_name or None,
                        cpu_cores=d.get("vcpus"),
                        memory_gb=round(mem_mb / 1024, 1) if mem_mb else None,
                        disk_gb=d.get("disk"),
                        status="active" if d.get("status") == "active" else (d.get("status") or "unknown"),
                        currency="USD",
                        raw=d,
                    )
                )
            if not data.get("links", {}).get("pages", {}).get("next"):
                break
            page += 1
        return result

    def list_domains(self) -> list:
        result = []
        page = 1
        while True:
            data = self._get(f"/domains?per_page=100&page={page}")
            for d in data.get("domains", []):
                result.append(
                    NormalizedDomain(
                        external_id=d.get("name"),
                        domain_name=d.get("name"),
                        registrar="digitalocean",
                        raw=d,
                    )
                )
            if not data.get("links", {}).get("pages", {}).get("next"):
                break
            page += 1
        return result
