"""Cloudflare 适配器（REST API v4，Bearer Token）

API 文档：https://developers.cloudflare.com/api/
所需配置：{"api_token": "..."}（建议用 API Token，权限含 Zone:Read / Account:Read）
Cloudflare 无传统 VPS，主要同步托管域名（zones）；Workers/R2/Tunnel 子资产留待后续阶段。
"""

import httpx

from app.adapters.base import BaseAdapter, NormalizedDomain
from app.adapters.registry import register


@register("cloudflare-api")
class CloudflareAdapter(BaseAdapter):
    required_config = ["api_token"]
    BASE = "https://api.cloudflare.com/client/v4"

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

    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()
            data = resp.json()
            if not data.get("success", True):
                errors = data.get("errors", [])
                raise RuntimeError(errors[0].get("message") if errors else "Cloudflare API 返回失败")
            return data

    def test_connection(self) -> dict:
        try:
            data = self._get("/user/tokens/verify")
            status = data.get("result", {}).get("status")
            if status == "active":
                return {"ok": True, "message": "API Token 有效"}
            return {"ok": False, "message": f"Token 状态异常：{status}"}
        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 list_domains(self) -> list:
        result = []
        page = 1
        while True:
            data = self._get(f"/zones?per_page=50&page={page}")
            for z in data.get("result", []):
                result.append(
                    NormalizedDomain(
                        external_id=z.get("id"),
                        domain_name=z.get("name"),
                        registrar="cloudflare",
                        status="active" if z.get("status") == "active" else (z.get("status") or "unknown"),
                        raw=z,
                    )
                )
            info = data.get("result_info", {})
            if page >= info.get("total_pages", 1):
                break
            page += 1
        return result
