/**
 * D136+ · 视频批量生成 · 导演编码 → Seedance API
 * 用法: node generate-shots.js
 */
const { generateVideo } = require('./video-api-adapter');
const fs = require('fs');
const path = require('path');

const ENCODING_FILE = path.resolve(__dirname, '../outputs/付费修仙-ep01-director-encoding.json');

// D136+ 输出优先JZAO外置硬盘 · 本地fallback
const JZAO_SHOTS = '/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/视频/zai-fu-fei-xiu-xian/ep01';
const LOCAL_SHOTS = path.resolve(__dirname, '../outputs/shots');
const OUT_DIR = fs.existsSync(JZAO_SHOTS) ? JZAO_SHOTS : LOCAL_SHOTS;

async function main() {
  const encoding = JSON.parse(fs.readFileSync(ENCODING_FILE, 'utf8'));
  fs.mkdirSync(OUT_DIR, { recursive: true });

  console.log(`[Generate] ${encoding.project} · ep${encoding.episode} · ${encoding.shots.length}镜`);
  console.log(`[Generate] 输出: ${OUT_DIR}\n`);

  const results = [];
  for (let i = 0; i < encoding.shots.length; i++) {
    const s = encoding.shots[i];
    const prompt = buildPrompt(s, encoding);
    
    console.log(`━━━ 镜${i + 1}/${encoding.shots.length}: ${s.id} ━━━`);
    console.log(`  景别: ${s.framing} | 情绪: ${s.emotion?.type}(${s.emotion?.intensity}) | ${s.duration}s`);
    console.log(`  spatial_anchor: ${s.spatial_anchor}`);
    console.log(`  text_elements: ${s.text_elements}`);
    console.log(`  prompt: ${prompt.substring(0, 100)}...`);

    const outputPath = path.join(OUT_DIR, `${encoding.project}-${encoding.episode}-${s.id}.mp4`);
    if (fs.existsSync(outputPath)) {
      console.log(`  ✅ 已存在，跳过\n`);
      results.push({ ...s, file: outputPath });
      continue;
    }

    try {
      const result = await generateVideo({
        prompt,
        duration: s.duration || 5,
        shotId: `${encoding.project}-${encoding.episode}-${s.id}`,
        projectKey: `付费修仙/ep01`,
        outputPath,
      });
      console.log(`  ✅ ${path.basename(result.videoPath)}\n`);
      results.push({ ...s, file: result.videoPath, taskId: result.taskId });
    } catch (e) {
      console.error(`  ❌ ${e.message}\n`);
      results.push({ ...s, file: null, error: e.message });
      // 继续下一个
    }
  }

  const resultFile = path.join(OUT_DIR, `${encoding.project}-${encoding.episode}-results.json`);
  fs.writeFileSync(resultFile, JSON.stringify(results, null, 2));
  const success = results.filter(r => r.file).length;
  console.log(`\n═══ 完成: ${success}/${results.length} ═══`);
  console.log(`结果: ${resultFile}`);
}

function buildPrompt(shot, encoding) {
  const locks = encoding.continuity_locks;

  // ═══ 上下文+编码+自然语言 三层协议 ═══
  //
  // [Context] 英文编码 · 告诉AI前面发生了什么 + 这个故事是什么
  //   50词以内 → AI理解上下文 → 不自盲抽
  //
  // ⊢ 编码层: CHAR+PROP+ENV锁定
  //
  // ⊢ 场景层: 中文自然语言 → AI推理情节+原因

  let prompt = '';

  // ─── 上下文层: 英文编码 → 告诉AI前面发生了什么 ───
  // 每镜都带：剧集摘要 + 前一个镜头的框架
  if (encoding.episode_summary) {
    prompt += `[Ep${encoding.episode} Summary] ${encoding.episode_summary}\n`;
  }
  if (encoding.prev_shots?.[shot.id]) {
    prompt += `[Previous Shot] ${encoding.prev_shots[shot.id]}\n`;
  }
  if (prompt.length > 0) prompt += '\n';

  // ─── 编码层: CHAR+PROP+ENV ───
  if (shot.char_ref && locks?.characters?.[shot.char_ref]) {
    prompt += `⊢ CHAR-003 Su Bai: 18yr male, white robe, black hair half-up, 175cm\n`;
  }

  if (shot.prop_ref && locks?.props?.[shot.prop_ref]) {
    prompt += `⊢ PROP: vertical hanging wood sign, worn edges, 【天道宗】\n`;
  }
  if (shot.prop_ref_2 && locks?.props?.[shot.prop_ref_2]) {
    prompt += `⊢ PROP: horizontal floor board, recruitment ad\n`;
  }

  if (shot.env && locks?.environments?.[shot.env]) {
    prompt += `⊢ ENV: cultivation square, edge corner, golden sunlight\n`;
  }

  // ─── 场景层: 情节+原因 → AI推理 ───
  if (encoding.scene) {
    prompt += `\n⊢ Scene:\n  ${encoding.scene}\n`;
  }

  // ─── 动作: 当前镜头 ───
  prompt += `\n→ Shot: ${shot.framing}`;
  if (shot.emotion?.type) prompt += ` | ${shot.emotion.type}`;
  prompt += `\n`;

  if (shot.action) {
    prompt += `→ ${shot.action}\n`;
  }

  prompt += `⊢ Style: 3D animation, Chinese cultivation, cinematic lighting\n`;
  prompt += `⊢ No: photorealism, cartoon, modern elements, watermark`;

  return prompt;
}

main().catch(e => { console.error(e); process.exit(1); });
