/**
 * sync-smoke-test.ts — 快速测试：用已有的本地产物验证 Supabase material_id 写入
 * 用法：SMOKE_BATCH_ID=<batch> SMOKE_MATERIAL_ID=<uuid> pnpm exec tsx automation/pipelines/sync-smoke-test.ts
 */
import "dotenv/config";

import { readFile } from "node:fs/promises";
import path from "node:path";

import {
  getFinalResultByMaterialId,
  upsertBestMatchImage,
  upsertExtendedBestMatches,
  upsertFinalResult,
  upsertImageSearchResult,
  upsertKeywordProcess,
  upsertKeywordSelection,
  upsertSearchRound,
} from "../internal/db.ts";
import { uploadScreenshot } from "../internal/storage.ts";

const AUTOMATION_DIR = path.resolve(import.meta.dirname!, "..");
const BATCH_ID = process.env.SMOKE_BATCH_ID || "";
const MATERIAL_ID = process.env.SMOKE_MATERIAL_ID || "";

if (!BATCH_ID || !MATERIAL_ID) {
  throw new Error("缺少 SMOKE_BATCH_ID 或 SMOKE_MATERIAL_ID 环境变量");
}

async function test(label: string, fn: () => Promise<void>) {
  try {
    await fn();
    console.log(`  ✅ ${label}`);
  } catch (error) {
    const msg = error instanceof Error ? error.message : String(error);
    console.log(`  ❌ ${label}: ${msg}`);
  }
}

async function main() {
  console.log(`\n🧪 Supabase 同步测试 (material_id=${MATERIAL_ID})\n`);

  const kwDir = path.join(AUTOMATION_DIR, "output", "linked-row-runs");
  const searchDir = path.join(AUTOMATION_DIR, "output", "search-plan");
  const imageDir = path.join(AUTOMATION_DIR, "output", "image-search-keywords");

  await test("keyword_process upsert", async () => {
    const report = JSON.parse(await readFile(path.join(kwDir, "keyword-process.json"), "utf8"));
    await upsertKeywordProcess({
      batch_id: BATCH_ID,
      material_id: MATERIAL_ID,
      row_name: String(report.row_name ?? ""),
      row_spec: String(report.row_spec ?? ""),
      row_brand: String(report.row_brand ?? ""),
      llm_model: String(report.llm_model ?? ""),
      ai_keyword_analysis: report.ai_keyword_analysis ?? {},
      full_report: report,
    });
  });

  await test("search_rounds upsert", async () => {
    const summary = JSON.parse(await readFile(path.join(searchDir, "run-summary.json"), "utf8"));
    const round = (summary.rounds ?? []).find((item: { material_id?: string }) => item.material_id === MATERIAL_ID);
    if (!round) throw new Error("无搜索轮次数据");
    await upsertSearchRound({
      batch_id: BATCH_ID,
      material_id: MATERIAL_ID,
      search_round: Number(round.search_round ?? 1),
      run_type: "initial",
      primary_keyword: String(round.primary_keyword ?? ""),
      search_strategy: String(round.search_strategy ?? ""),
      stage_order: round.stage_order != null ? Number(round.stage_order) : null,
      stage_label: String(round.stage_label ?? ""),
      stage_kind: String(round.stage_kind ?? ""),
      stage_main_keyword: String(round.stage_main_keyword ?? ""),
      brand_keyword: String(round.brand_keyword ?? ""),
      brand_keyword_hit_rate: round.brand_keyword_hit_rate != null ? Number(round.brand_keyword_hit_rate) : null,
      is_valid_search: Boolean(round.is_valid_search),
      visual_confidence: round.visual_confidence != null ? Number(round.visual_confidence) : null,
      visual_reason: String(round.visual_reason ?? ""),
      stop_reason: String(round.stop_reason ?? ""),
      results_count: Number(round.results_count ?? 0),
      results: Array.isArray(round.results) ? round.results : [],
      screenshot_url: "",
      keyword_hit_rate: round.keyword_hit_rate != null ? Number(round.keyword_hit_rate) : null,
      contact_enrichment_attempted: Boolean(round.contact_enrichment_attempted),
      contact_enrichment_skip_reason: String(round.contact_enrichment_skip_reason ?? ""),
      keyword_hit_rate_source: String(round.keyword_hit_rate_source ?? "local"),
      keyword_hit_rate_reason: String(round.keyword_hit_rate_reason ?? ""),
      keyword_hit_rate_sample_count: round.keyword_hit_rate_sample_count != null ? Number(round.keyword_hit_rate_sample_count) : null,
    });
  });

  await test("best_match_images upsert", async () => {
    const summary = JSON.parse(await readFile(path.join(searchDir, "run-summary.json"), "utf8"));
    const bestMatch = (summary.best_match_images ?? []).find((item: { material_id?: string }) => item.material_id === MATERIAL_ID);
    if (!bestMatch) throw new Error("无 best match image 数据");
    await upsertBestMatchImage({
      batch_id: BATCH_ID,
      material_id: MATERIAL_ID,
      image_url: "",
      offer_url: String(bestMatch.offer_url ?? ""),
      title: String(bestMatch.title ?? ""),
      merchant_name: String(bestMatch.merchant_name ?? ""),
      wangwang_url: String(bestMatch.wangwang_url ?? ""),
      selected_from_round: bestMatch.selected_from_round != null ? Number(bestMatch.selected_from_round) : null,
      selected_from_keyword: String(bestMatch.selected_from_keyword ?? ""),
      method: String(bestMatch.method ?? ""),
      reason: String(bestMatch.reason ?? ""),
    });
  });

  await test("extended_best_matches upsert", async () => {
    const reportPath = path.join(searchDir, "extended-best-matches", "extended-best-matches-report.json");
    const report = JSON.parse(await readFile(reportPath, "utf8"));
    await upsertExtendedBestMatches({ batch_id: BATCH_ID, material_id: MATERIAL_ID, report });
  });

  await test("image_search_results upsert", async () => {
    const report = JSON.parse(await readFile(path.join(imageDir, "image-search-keyword-report.json"), "utf8"));
    const imageSearch = report.image_search ?? {};
    await upsertImageSearchResult({
      batch_id: BATCH_ID,
      material_id: MATERIAL_ID,
      is_valid_image_search: imageSearch.is_valid_image_search !== false,
      screenshot_url: "",
      top_titles: Array.isArray(imageSearch.top_titles) ? imageSearch.top_titles : [],
      similar_products: Array.isArray(report.similar_products) ? report.similar_products : [],
      text_rule: imageSearch.text_rule ?? {},
      image_similarity: imageSearch.image_similarity ?? {},
      full_report: report,
    });
  });

  await test("keyword_selections upsert", async () => {
    await upsertKeywordSelection({
      batch_id: BATCH_ID,
      material_id: MATERIAL_ID,
      main_keyword: "测试关键词",
      judgment_reason: "测试原因",
      debug_data: { test: true },
    });
  });

  await test("final_results upsert", async () => {
    const data = JSON.parse(await readFile(path.join(AUTOMATION_DIR, "output", "final-results", "row-002.json"), "utf8"));
    await upsertFinalResult({
      batch_id: BATCH_ID,
      material_id: MATERIAL_ID,
      source: String(data.source ?? ""),
      main_keyword: String(data.main_keyword ?? ""),
      product_count: Number(data.product_count ?? 0),
      products: Array.isArray(data.products) ? data.products : [],
      finished_at: String(data.finished_at ?? new Date().toISOString()),
    });
  });

  await test("Storage 截图上传", async () => {
    const screenshotPath = path.join(imageDir, "image-search-page.jpg");
    const url = await uploadScreenshot(screenshotPath, `${MATERIAL_ID}/test/image-search-page.jpg`);
    console.log(`       → URL: ${url}`);
  });

  await test("final_results 回读验证", async () => {
    const row = await getFinalResultByMaterialId(MATERIAL_ID);
    if (!row) throw new Error("回读为空");
    if (row.material_id !== MATERIAL_ID) throw new Error(`material_id 不匹配: ${row.material_id}`);
    console.log(`       → source=${row.source}, products=${row.product_count}`);
  });

  console.log("\n🏁 测试完成\n");
}

main().catch((err) => {
  console.error("❌ 测试脚本失败:", err);
  process.exit(1);
});
