"""腾讯云适配器（含国际版，CVM OpenAPI + TC3-HMAC-SHA256 签名）

API 文档：https://cloud.tencent.com/document/api/213/15753
所需配置：{"secret_id": "...", "secret_key": "...", "region": "ap-guangzhou"}
国际版（intl）将 region 设为海外区域即可，端点统一为 cvm.tencentcloudapi.com。
说明：此处实现 TC3-HMAC-SHA256 签名，可直接调用 CVM OpenAPI；
      生产环境也可替换为官方 tencentcloud-sdk-python，接口契约保持不变。
"""

import hashlib
import hmac
import json
import time

import httpx

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


@register("tencent-sdk", "tencent-intl-sdk")
class TencentAdapter(BaseAdapter):
    required_config = ["secret_id", "secret_key"]
    HOST = "cvm.tencentcloudapi.com"
    SERVICE = "cvm"
    VERSION = "2017-03-12"
    ALGORITHM = "TC3-HMAC-SHA256"

    def _region(self) -> str:
        return self.config.get("region") or "ap-guangzhou"

    @staticmethod
    def _hmac_sha256(key: bytes, msg: str) -> bytes:
        return hmac.new(key, msg.encode(), hashlib.sha256).digest()

    def _build_authorization(self, action: str, payload_json: str, timestamp: int, date: str):
        secret_id = self.config.get("secret_id", "")
        secret_key = self.config.get("secret_key", "")
        content_type = "application/json; charset=utf-8"
        canonical_headers = (
            f"content-type:{content_type}\nhost:{self.HOST}\nx-tc-action:{action.lower()}\n"
        )
        signed_headers = "content-type;host;x-tc-action"
        hashed_payload = hashlib.sha256(payload_json.encode()).hexdigest()
        canonical_request = (
            f"POST\n/\n\n{canonical_headers}\n{signed_headers}\n{hashed_payload}"
        )
        credential_scope = f"{date}/{self.SERVICE}/tc3_request"
        hashed_canonical = hashlib.sha256(canonical_request.encode()).hexdigest()
        string_to_sign = (
            f"{self.ALGORITHM}\n{timestamp}\n{credential_scope}\n{hashed_canonical}"
        )
        secret_date = self._hmac_sha256(("TC3" + secret_key).encode(), date)
        secret_service = self._hmac_sha256(secret_date, self.SERVICE)
        secret_signing = self._hmac_sha256(secret_service, "tc3_request")
        signature = hmac.new(secret_signing, string_to_sign.encode(), hashlib.sha256).hexdigest()
        return (
            f"{self.ALGORITHM} Credential={secret_id}/{credential_scope}, "
            f"SignedHeaders={signed_headers}, Signature={signature}"
        )

    def _call(self, action: str, payload: dict = None) -> dict:
        payload_json = json.dumps(payload or {})
        timestamp = int(time.time())
        date = time.strftime("%Y-%m-%d", time.gmtime(timestamp))
        authorization = self._build_authorization(action, payload_json, timestamp, date)
        headers = {
            "Authorization": authorization,
            "Content-Type": "application/json; charset=utf-8",
            "Host": self.HOST,
            "X-TC-Action": action,
            "X-TC-Timestamp": str(timestamp),
            "X-TC-Version": self.VERSION,
            "X-TC-Region": self._region(),
        }
        with httpx.Client(timeout=30) as client:
            resp = client.post(f"https://{self.HOST}", content=payload_json, headers=headers)
            resp.raise_for_status()
            data = resp.json()
        response = data.get("Response", {})
        if response.get("Error"):
            err = response["Error"]
            raise RuntimeError(f"{err.get('Code')}: {err.get('Message')}")
        return response

    def test_connection(self) -> dict:
        try:
            data = self._call("DescribeRegions")
            count = len(data.get("RegionSet", []))
            return {"ok": True, "message": f"连接成功，可用区域 {count} 个"}
        except httpx.HTTPStatusError as e:
            return {"ok": False, "message": f"HTTP {e.response.status_code}：凭证无效"}
        except Exception as e:  # noqa: BLE001
            return {"ok": False, "message": str(e)}

    def list_vps(self) -> list:
        data = self._call("DescribeInstances", {"Limit": 100})
        result = []
        status_map = {"RUNNING": "active", "STOPPED": "stopped"}
        for inst in data.get("InstanceSet", []):
            public_ips = inst.get("PublicIpAddresses", [])
            result.append(
                NormalizedVPS(
                    external_id=inst.get("InstanceId"),
                    name=inst.get("InstanceName") or inst.get("InstanceId"),
                    ip_address=public_ips[0] if public_ips else None,
                    region=inst.get("Placement", {}).get("Zone"),
                    os=inst.get("OsName"),
                    cpu_cores=inst.get("CPU"),
                    memory_gb=inst.get("Memory"),
                    disk_gb=inst.get("SystemDisk", {}).get("DiskSize"),
                    status=status_map.get(inst.get("InstanceState"), inst.get("InstanceState") or "unknown"),
                    currency="CNY",
                    raw=inst,
                )
            )
        return result
