from __future__ import annotations

from typing import Any, Dict, List

from common import shared as _shared


def _int_or_zero(value: Any) -> int:
    try:
        return int(value)
    except Exception:
        return 0


def _huawei_client_class() -> Any:
    from HUAWEI.cloud_client import HuaweiCloudClient

    return HuaweiCloudClient


def is_target_region(region: str) -> bool:
    """判断地区编码是否属于当前项目管理的华为云地区。"""
    return region in {plan.region for plan in _shared.REGION_PLANS}


def resource_id_candidates(item: Dict[str, Any]) -> List[str]:
    """从云资源或订购资源对象里提取所有可能的资源 ID。"""
    ids: List[str] = []
    for key in (
        "resource_id",
        "resourceId",
        "cloud_resource_id",
        "cloudResourceId",
        "server_id",
        "serverId",
        "id",
    ):
        value = item.get(key)
        if isinstance(value, list):
            for part in value:
                text = str(part or "").strip()
                if text and text not in ids:
                    ids.append(text)
        else:
            text = str(value or "").strip()
            if text and text not in ids:
                ids.append(text)
    return ids


def resource_search_text(item: Dict[str, Any]) -> str:
    """拼出资源类型搜索文本，用于识别 ECS/EIP 订购资源。"""
    return " ".join(
        str(item.get(key) or "")
        for key in (
            "service_type_code",
            "service_type_name",
            "resource_type_code",
            "resource_type_name",
            "resource_name",
            "resource_spec_code",
        )
    ).lower()


def is_ecs_subscription_resource(item: Dict[str, Any]) -> bool:
    """判断订购资源是否像 ECS。"""
    text = resource_search_text(item)
    return any(token in text for token in ("ecs", "cloudserver", "cloudservers", "弹性云服务器", "hws.resource.type.vm"))


def is_eip_subscription_resource(item: Dict[str, Any]) -> bool:
    """判断订购资源是否像 EIP。"""
    text = resource_search_text(item)
    return any(token in text for token in ("eip", "publicip", "public_ip", "弹性公网ip", "弹性公网IP".lower(), "hws.resource.type.ip"))


def subscription_status_text(item: Dict[str, Any]) -> str:
    """把订购资源状态码转换成中文。"""
    status = item.get("status")
    return {2: "使用中", 3: "已关闭", 4: "已冻结", 5: "已过期"}.get(status, str(status or ""))


def subscription_operation_kind(item: Dict[str, Any]) -> str:
    """判断订购资源是否允许走退订流程。"""
    if str(item.get("status") or "").strip() == "3":
        return "none"
    if not is_target_region(str(item.get("region_code") or "")):
        return "none"
    return "subscription_unsubscribe"


def server_status_text(server: Dict[str, Any]) -> str:
    """把 ECS 状态码转换成中文。"""
    status = str(server.get("status") or "").upper()
    return {
        "ACTIVE": "运行中",
        "SHUTOFF": "已关机",
        "BUILD": "创建中",
        "ERROR": "故障",
        "DELETED": "已删除",
        "REBUILD": "重建中",
    }.get(status, status)


def server_charging_text(server: Dict[str, Any]) -> str:
    """根据服务器字段判断包周期或按需。"""
    metadata = server.get("metadata") if isinstance(server.get("metadata"), dict) else {}
    charging = str(
        server.get("chargingMode")
        or server.get("charging_mode")
        or metadata.get("chargingMode")
        or metadata.get("metering.chargingMode")
        or ""
    ).lower()
    if charging in {"prepaid", "pre_paid", "prepaid"}:
        return "包周期"
    if charging in {"postpaid", "post_paid", "postpaid"}:
        return "按需"
    if metadata.get("metering.order_id"):
        return "包周期"
    return "按需"


def server_flavor_label(server: Dict[str, Any]) -> str:
    """把服务器规格字段转换成界面展示文本。"""
    flavor = server.get("flavor") or {}
    if isinstance(flavor, dict):
        client = _huawei_client_class()
        flavor_id = client.server_flavor_id(server)
        if flavor_id:
            return flavor_id
        vcpus = _int_or_zero(flavor.get("vcpus") or flavor.get("cpu"))
        ram_mb = _int_or_zero(flavor.get("ram") or flavor.get("memory"))
        if vcpus and ram_mb:
            ram_gb = max(1, int(round(ram_mb / 1024)))
            return f"{vcpus}vCPUs | {ram_gb}GiB"
        return flavor_id
    return str(flavor or "")


def server_attribute_summary(server: Dict[str, Any]) -> str:
    """生成服务器核心属性摘要，方便日志排查。"""
    flavor = server.get("flavor") if isinstance(server.get("flavor"), dict) else {}
    image = server.get("image") if isinstance(server.get("image"), dict) else {}
    vcpus = flavor.get("vcpus") or flavor.get("cpu") or server.get("vcpus") or server.get("cpu")
    ram = flavor.get("ram") or flavor.get("memory") or server.get("ram") or server.get("memory")
    az = (
        server.get("OS-EXT-AZ:availability_zone")
        or server.get("availability_zone")
        or server.get("availabilityZone")
        or server.get("az")
        or ""
    )
    image_text = image.get("name") or image.get("id") or server.get("image_name") or server.get("imageName") or ""
    client = _huawei_client_class()
    return (
        f"name={server.get('name') or ''} id={server.get('id') or ''} "
        f"status={server_status_text(server)} flavor={server_flavor_label(server)} "
        f"vcpus={vcpus or ''} ram={ram or ''} image={image_text} az={az} "
        f"public_ip={client.public_ip_from_server(server)} "
        f"charging={server_charging_text(server)}"
    )


def server_expire_time(server: Dict[str, Any]) -> str:
    """从服务器对象和 metadata 中查找过期时间。"""
    metadata = server.get("metadata") if isinstance(server.get("metadata"), dict) else {}
    keys = (
        "expire_time",
        "expireTime",
        "expired_time",
        "expiredTime",
        "expire_date",
        "expireDate",
        "expiration_time",
        "expirationTime",
        "resource_expire_time",
        "resourceExpireTime",
        "resource_expire_date",
        "resourceExpireDate",
        "valid_to",
        "validTo",
        "end_time",
        "endTime",
        "metering.expire_time",
        "metering.expireTime",
        "metering.resourcespecexpiretime",
    )
    for source in (server, metadata):
        for key in keys:
            value = source.get(key) if isinstance(source, dict) else None
            if value:
                return str(value)
    return ""


def resource_expire_time(resource: Dict[str, Any]) -> str:
    """递归从云资源对象里查找过期时间字段。"""
    keys = {
        "expire_time",
        "expireTime",
        "expired_time",
        "expiredTime",
        "expire_date",
        "expireDate",
        "expiration_time",
        "expirationTime",
        "resource_expire_time",
        "resourceExpireTime",
        "resource_expire_date",
        "resourceExpireDate",
        "valid_to",
        "validTo",
        "end_time",
        "endTime",
        "expireTimeStr",
        "expire_time_str",
    }

    def walk(value: Any) -> str:
        if isinstance(value, dict):
            for key, nested in value.items():
                key_text = str(key)
                if key_text in keys or ("expire" in key_text.lower() and nested):
                    if not isinstance(nested, (dict, list)):
                        return str(nested)
                found = walk(nested)
                if found:
                    return found
        elif isinstance(value, list):
            for nested in value:
                found = walk(nested)
                if found:
                    return found
        return ""

    return walk(resource)


ON_DEMAND_EXPIRE_TEXT = "按需计费"


def billing_text_is_on_demand(value: Any) -> bool:
    """判断计费文字或枚举是否表示按需/后付费。"""
    text = str(value or "").strip().lower()
    if not text:
        return False
    return any(
        token in text
        for token in (
            "按需",
            "按量",
            "后付费",
            "按小时",
            "小时计费",
            "postpaid",
            "post_pay",
            "postpay",
            "payasyougo",
            "pay_as_you_go",
            "on_demand",
            "ondemand",
            "on demand",
        )
    )


def billing_text_is_prepaid(value: Any) -> bool:
    """判断计费文字或枚举是否表示包年包月/包周期。"""
    text = str(value or "").strip().lower()
    if not text:
        return False
    return any(
        token in text
        for token in (
            "包年",
            "包月",
            "包周期",
            "预付费",
            "prepaid",
            "pre_paid",
            "prepay",
            "subscription",
            "yearly",
            "monthly",
            "cycle",
        )
    )


def display_expire_time_for_billing(
    resource: Dict[str, Any] | None = None,
    *,
    billing_text: Any = "",
    explicit_expire_time: Any = "",
    assume_on_demand: bool = False,
) -> str:
    """资源库到期时间显示：包年包月显示真实到期时间，按需统一显示按需计费。"""
    expire_time = str(explicit_expire_time or "").strip()
    if not expire_time and isinstance(resource, dict):
        expire_time = resource_expire_time(resource).strip()

    if billing_text_is_on_demand(billing_text):
        return ON_DEMAND_EXPIRE_TEXT
    if str(expire_time or "").startswith("2200-01-01"):
        return ON_DEMAND_EXPIRE_TEXT
    if billing_text_is_prepaid(billing_text):
        return expire_time
    if expire_time:
        return expire_time
    return ON_DEMAND_EXPIRE_TEXT if assume_on_demand else ""


def is_on_demand_server(server: Dict[str, Any]) -> bool:
    """判断服务器是否按需计费。"""
    return server_charging_text(server) == "按需"


def public_ip_address(item: Dict[str, Any]) -> str:
    """从不同云资源字段里读取公网 IP。"""
    return str(item.get("public_ip_address") or item.get("public_ip") or item.get("ip_address") or "")
