// Adapter: 把后端 Pydantic schemas_v4 的字段转换成设计稿 JSX 期待的 mock 结构
// 保持设计稿画板组件 props 不变，转换全部发生在这一层
// M1 阶段不消费（画板还用自带 mock），M2 逐画板切换时用

const TONE_LABEL = { hard_ad: "硬广", grass: "种草", dry_goods: "干货", entertainment_hook: "娱乐" };
const RELEVANCE_LABEL = { direct: "直接", indirect: "间接", cross_industry: "可迁移", no_value: "无价值" };
const PLATFORM_HINTS = {
  "douyin.com": "douyin", "iesdouyin.com": "douyin", "v.douyin.com": "douyin",
  "xiaohongshu.com": "xhs", "xhslink.com": "xhs",
  "kuaishou.com": "ks", "v.kuaishou.com": "ks", "chenzhongtech.com": "ks",
};

function inferPlatform(jobOrMeta) {
  const src = jobOrMeta?.video_filename || jobOrMeta?.link_url || "";
  try {
    const host = new URL(src).hostname.replace(/^www\./, "");
    for (const [k, v] of Object.entries(PLATFORM_HINTS)) {
      if (host.includes(k)) return v;
    }
  } catch (_) { /* ignore */ }
  if (jobOrMeta?.source === "upload") return "sph";
  return "douyin";
}

// jobs list -> TEARDOWN_ITEMS（拆解页左列爆款选择）
function jobsToTeardownItems(jobs) {
  return (jobs || []).filter(j => j.has_result).map((j, i) => {
    const tone = j.progress?.tone_type || "";
    const relev = j.progress?.relevance_type || "";
    return {
      id: `V${String(i + 1).padStart(3, "0")}`,
      plat: inferPlatform(j),
      title: j.title || j.job_id,
      author: j.industry || "未分类",
      d1: TONE_LABEL[tone] || "",
      d2: RELEVANCE_LABEL[relev] || "",
      tag: "视频",
      stats: { play: "-", like: "-", cmt: "-" },
      jobId: j.job_id,
      createdAt: j.created_at,
    };
  });
}

// AnalysisResultV4 -> 拆解详情 timeline 数据
function resultToTimeline(result) {
  const shots = result?.rewrite?.storyboard?.shots || [];
  const frames = shots.map((s, i) => ({
    k: `F${i + 1}`,
    l: s.narration?.slice(0, 8) || `分镜${i + 1}`,
    time: (s.duration_sec || 0).toFixed(1) + "s",
    desc: s.visual_prompt || "",
    col: i < Math.ceil(shots.length * 0.3) ? "hook" : i > shots.length * 0.7 ? "cta" : "build",
  }));
  const points = result?.five_dimensions?.emotion_curve?.emotion_points || [];
  const retention = points.length >= 2
    ? points.map(p => Math.round((p.intensity || 0) * 100))
    : Array.from({ length: 20 }, (_, i) => 60 + Math.round(Math.sin(i / 3) * 15));
  const transcript = (result?.raw_script_timed || []).map(seg => ({
    t: (seg.start_sec || 0).toFixed(1) + "s",
    text: seg.text || "",
  }));
  return { frames, retention, transcript };
}

// api_credentials + providers -> 模型管理页 img[] / vid[] 卡片
function credsToModelCards(credentials, providers) {
  const specByKey = Object.fromEntries((providers?.items || []).map(p => [p.key, p]));
  const mapKind = (provKey) => {
    const spec = specByKey[provKey] || {};
    if (spec.kind === "multimodal_llm") return "llm";
    if (spec.kind === "video_api") {
      if (["seedream3", "nano_banana"].includes(provKey)) return "img";
      return "vid";
    }
    return "other";
  };
  const toCard = (c) => {
    const spec = specByKey[c.provider] || {};
    const modelName = c.extra?.model_name || "";
    return {
      id: c.id,
      n: c.name || spec.label || c.provider,
      v: modelName || "-",
      p: spec.label?.split("（")[0] || c.provider,
      st: c.is_active ? "active" : (c.last_test_status === "ok" ? "standby" : "error"),
      use: spec.kind === "multimodal_llm" ? "拆解·多模态" : (mapKind(c.provider) === "img" ? "图文·生成" : "视频·生成"),
      lat: c.last_test_latency_ms ? `${c.last_test_latency_ms}ms` : "-",
      cost: "-",
      calls: "-",
      ok: c.last_test_status === "ok" ? 100 : (c.last_test_status ? 0 : "-"),
      key: c.api_key || "****",
      provider: c.provider,
      kind: mapKind(c.provider),
    };
  };
  const cards = (credentials?.items || []).map(toCard);
  return {
    img: cards.filter(c => c.kind === "img"),
    vid: cards.filter(c => c.kind === "vid"),
    llm: cards.filter(c => c.kind === "llm"),
    other: cards.filter(c => c.kind === "other"),
    all: cards,
  };
}

// 4×4 矩阵聚合：按 tone × relevance 统计任务数量
function jobsToMatrix(jobs) {
  const tones = ["hard_ad", "grass", "dry_goods", "entertainment_hook"];
  const relevs = ["direct", "indirect", "cross_industry", "no_value"];
  const matrix = {};
  tones.forEach(t => {
    matrix[t] = {};
    relevs.forEach(r => { matrix[t][r] = { count: 0, items: [] }; });
  });
  (jobs || []).forEach(j => {
    const t = j.progress?.tone_type;
    const r = j.progress?.relevance_type;
    if (t && r && matrix[t] && matrix[t][r]) {
      matrix[t][r].count += 1;
      matrix[t][r].items.push(j);
    }
  });
  return { tones, relevs, matrix, toneLabel: TONE_LABEL, relevLabel: RELEVANCE_LABEL };
}

Object.assign(window, {
  Adapter: {
    inferPlatform,
    jobsToTeardownItems,
    resultToTimeline,
    credsToModelCards,
    jobsToMatrix,
    TONE_LABEL, RELEVANCE_LABEL,
  },
});
