"""火山方舟 Doubao-embedding-vision 文本向量化客户端（scope-link 用）。

接口由 .env 配置：
  - ARK_EMBEDDING_URL: 默认 POST .../api/v3/embeddings/multimodal
  - ARK_EMBEDDING_EP: 预置推理接入点 ep-id，作为 model 字段传入
  - 输入 input=[{"type":"text","text":...}]，输出 data.embedding = 2048 维
  - 单条调用（一次请求一个向量），批量靠并发多次请求。

密钥、endpoint、URL 全部从 .env 读，不硬编码。
"""
from __future__ import annotations

import time
from dataclasses import dataclass
from pathlib import Path

import httpx

from core.config import env_value, load_env_file

_DEFAULT_URL = "https://ark.cn-beijing.volces.com/api/v3/embeddings/multimodal"


@dataclass
class ArkEmbedConfig:
    api_key: str
    endpoint: str  # ep-id，作为 model 字段传入
    url: str = _DEFAULT_URL
    dim: int = 2048
    timeout: int = 30

    @classmethod
    def from_env(cls, env_file: str | Path = ".env") -> "ArkEmbedConfig":
        fe = load_env_file(env_file)
        return cls(
            api_key=env_value("ARK_API_KEY", fe, required=True),
            endpoint=env_value("ARK_EMBEDDING_EP", fe, required=True),
            url=env_value("ARK_EMBEDDING_URL", fe, _DEFAULT_URL),
            dim=int(env_value("ARK_EMBEDDING_DIM", fe, "2048")),
        )


def embed_text(text: str, cfg: ArkEmbedConfig, retries: int = 4) -> list[float]:
    """文本 → 2048 维向量。失败指数退避重试，最终仍失败则抛出。"""
    payload = {"model": cfg.endpoint, "input": [{"type": "text", "text": text}]}
    headers = {
        "Authorization": f"Bearer {cfg.api_key}",
        "Content-Type": "application/json",
    }
    last_err: Exception | None = None
    for attempt in range(retries):
        try:
            resp = httpx.post(cfg.url, json=payload, headers=headers, timeout=cfg.timeout)
            resp.raise_for_status()
            return resp.json()["data"]["embedding"]
        except Exception as err:  # noqa: BLE001 — 网络/限流统一退避重试
            last_err = err
            time.sleep(1.0 * (attempt + 1))
    raise RuntimeError(f"ark embed failed for {text!r}: {last_err}")
