"""
预定义计费模板

提供常见厂商的计费配置模板，避免重复配置：
- CLAUDE_STANDARD: Claude/Anthropic 标准计费
- OPENAI_STANDARD: OpenAI 标准计费
- DOUBAO_STANDARD: 豆包计费（含缓存存储）
- GEMINI_STANDARD: Gemini 标准计费
- PER_REQUEST: 按次计费
"""

from typing import Dict, List, Optional

from src.services.billing.models import BillingDimension, BillingUnit


class BillingTemplates:
    """预定义的计费模板"""

    # =========================================================================
    # Claude/Anthropic 标准计费
    # - 输入 token
    # - 输出 token
    # - 缓存创建（创建时收费，约 1.25x 输入价格）
    # - 缓存读取（约 0.1x 输入价格）
    # - 按次计费（可选，配置 price_per_request 时生效）
    # =========================================================================
    CLAUDE_STANDARD: List[BillingDimension] = [
        BillingDimension(
            name="input",
            usage_field="input_tokens",
            price_field="input_price_per_1m",
        ),
        BillingDimension(
            name="output",
            usage_field="output_tokens",
            price_field="output_price_per_1m",
        ),
        BillingDimension(
            name="cache_creation",
            usage_field="cache_creation_tokens",
            price_field="cache_creation_price_per_1m",
        ),
        BillingDimension(
            name="cache_read",
            usage_field="cache_read_tokens",
            price_field="cache_read_price_per_1m",
        ),
        BillingDimension(
            name="request",
            usage_field="request_count",
            price_field="price_per_request",
            unit=BillingUnit.PER_REQUEST,
        ),
    ]

    # =========================================================================
    # OpenAI 标准计费
    # - 输入 token
    # - 输出 token
    # - 缓存读取（部分模型支持，无缓存创建费用）
    # - 按次计费（可选，配置 price_per_request 时生效）
    # =========================================================================
    OPENAI_STANDARD: List[BillingDimension] = [
        BillingDimension(
            name="input",
            usage_field="input_tokens",
            price_field="input_price_per_1m",
        ),
        BillingDimension(
            name="output",
            usage_field="output_tokens",
            price_field="output_price_per_1m",
        ),
        BillingDimension(
            name="cache_read",
            usage_field="cache_read_tokens",
            price_field="cache_read_price_per_1m",
        ),
        BillingDimension(
            name="request",
            usage_field="request_count",
            price_field="price_per_request",
            unit=BillingUnit.PER_REQUEST,
        ),
    ]

    # =========================================================================
    # 豆包计费
    # - 推理输入 (input_tokens)
    # - 推理输出 (output_tokens)
    # - 缓存命中 (cache_read_tokens) - 类似 Claude 的缓存读取
    # - 缓存存储 (cache_storage_token_hours) - 按 token 数 * 存储时长计费
    # - 按次计费（可选，配置 price_per_request 时生效）
    #
    # 注意：豆包的缓存创建是免费的，但存储需要按时付费
    # =========================================================================
    DOUBAO_STANDARD: List[BillingDimension] = [
        BillingDimension(
            name="input",
            usage_field="input_tokens",
            price_field="input_price_per_1m",
        ),
        BillingDimension(
            name="output",
            usage_field="output_tokens",
            price_field="output_price_per_1m",
        ),
        BillingDimension(
            name="cache_read",
            usage_field="cache_read_tokens",
            price_field="cache_read_price_per_1m",
        ),
        BillingDimension(
            name="cache_storage",
            usage_field="cache_storage_token_hours",
            price_field="cache_storage_price_per_1m_hour",
            unit=BillingUnit.PER_1M_TOKENS_HOUR,
        ),
        BillingDimension(
            name="request",
            usage_field="request_count",
            price_field="price_per_request",
            unit=BillingUnit.PER_REQUEST,
        ),
    ]

    # =========================================================================
    # Gemini 标准计费
    # - 输入 token
    # - 输出 token
    # - 缓存读取
    # - 按次计费（用于图片生成等模型，需配置 price_per_request）
    # =========================================================================
    GEMINI_STANDARD: List[BillingDimension] = [
        BillingDimension(
            name="input",
            usage_field="input_tokens",
            price_field="input_price_per_1m",
        ),
        BillingDimension(
            name="output",
            usage_field="output_tokens",
            price_field="output_price_per_1m",
        ),
        BillingDimension(
            name="cache_read",
            usage_field="cache_read_tokens",
            price_field="cache_read_price_per_1m",
        ),
        BillingDimension(
            name="request",
            usage_field="request_count",
            price_field="price_per_request",
            unit=BillingUnit.PER_REQUEST,
        ),
    ]

    # =========================================================================
    # 按次计费
    # - 适用于某些图片生成模型、特殊 API 等
    # - 仅按请求次数计费，不按 token 计费
    # =========================================================================
    PER_REQUEST: List[BillingDimension] = [
        BillingDimension(
            name="request",
            usage_field="request_count",
            price_field="price_per_request",
            unit=BillingUnit.PER_REQUEST,
        ),
    ]

    # =========================================================================
    # 混合计费（按次 + 按 token）
    # - 某些模型既有固定费用又有 token 费用
    # =========================================================================
    HYBRID_STANDARD: List[BillingDimension] = [
        BillingDimension(
            name="input",
            usage_field="input_tokens",
            price_field="input_price_per_1m",
        ),
        BillingDimension(
            name="output",
            usage_field="output_tokens",
            price_field="output_price_per_1m",
        ),
        BillingDimension(
            name="request",
            usage_field="request_count",
            price_field="price_per_request",
            unit=BillingUnit.PER_REQUEST,
        ),
    ]


# =========================================================================
# 模板注册表
# =========================================================================

BILLING_TEMPLATE_REGISTRY: Dict[str, List[BillingDimension]] = {
    # 按厂商名称
    "claude": BillingTemplates.CLAUDE_STANDARD,
    "anthropic": BillingTemplates.CLAUDE_STANDARD,
    "openai": BillingTemplates.OPENAI_STANDARD,
    "doubao": BillingTemplates.DOUBAO_STANDARD,
    "bytedance": BillingTemplates.DOUBAO_STANDARD,
    "gemini": BillingTemplates.GEMINI_STANDARD,
    "google": BillingTemplates.GEMINI_STANDARD,
    # 按计费模式
    "per_request": BillingTemplates.PER_REQUEST,
    "hybrid": BillingTemplates.HYBRID_STANDARD,
    # 默认
    "default": BillingTemplates.CLAUDE_STANDARD,
}


def get_template(name: Optional[str]) -> List[BillingDimension]:
    """
    获取计费模板

    Args:
        name: 模板名称（不区分大小写）

    Returns:
        计费维度列表
    """
    if not name:
        return BILLING_TEMPLATE_REGISTRY["default"]

    template = BILLING_TEMPLATE_REGISTRY.get(name.lower())
    if template is None:
        available = ", ".join(sorted(BILLING_TEMPLATE_REGISTRY.keys()))
        raise ValueError(f"Unknown billing template: {name!r}. Available: {available}")

    return template


def list_templates() -> List[str]:
    """列出所有可用的模板名称"""
    return list(BILLING_TEMPLATE_REGISTRY.keys())
