import "dotenv/config";

import { mkdir, readFile, writeFile } from "node:fs/promises";
import path from "node:path";
import process from "node:process";
import { pathToFileURL } from "node:url";

import {
  buildFinalResultPayload,
  syncFinalResult,
} from "./row-pipeline-sync.ts";
import {
  enrichSelectedOfferCandidates,
  normalizeLlmMatchJsonCandidates,
} from "./offer-contact-enrichment.ts";
import { updateSearchRoundStageDiagnostics } from "../internal/db.ts";

function normalizeSpace(value: unknown) {
  return String(value ?? "").replace(/\s+/g, " ").trim();
}

function parseArgs(argv: string[]) {
  const options = {
    llmJson: "",
    outputDir: "",
    materialId: "",
    batchId: "",
    contactLimit: 5,
    headless: (process.env.SEARCH_HEADLESS ?? "0") === "1",
    stageOrder: 1,
    stageLabel: "关键词搜索（AI 自动多轮）",
    stageKind: "keyword",
    mainKeyword: "",
    syncDb: true,
  };

  for (const arg of argv) {
    if (!arg.startsWith("--")) {
      continue;
    }

    const [flag, rawValue] = arg.slice(2).split("=", 2);
    const value = rawValue ?? "";
    if (flag === "llm-json" && value) {
      options.llmJson = path.resolve(process.cwd(), value);
    } else if (flag === "output-dir" && value) {
      options.outputDir = path.resolve(process.cwd(), value);
    } else if (flag === "material-id" && value) {
      options.materialId = value;
    } else if (flag === "batch-id" && value) {
      options.batchId = value;
    } else if (flag === "contact-limit" && value) {
      options.contactLimit = Number.parseInt(value, 10);
    } else if (flag === "headless" && value) {
      options.headless = value === "1" || value === "true";
    } else if (flag === "stage-order" && value) {
      options.stageOrder = Number.parseInt(value, 10);
    } else if (flag === "stage-label" && value) {
      options.stageLabel = normalizeSpace(value);
    } else if (flag === "stage-kind" && value) {
      options.stageKind = normalizeSpace(value);
    } else if (flag === "main-keyword" && value) {
      options.mainKeyword = normalizeSpace(value);
    } else if (flag === "no-sync-db") {
      options.syncDb = false;
    }
  }

  if (!options.llmJson) {
    throw new Error("参数 --llm-json 必填，例如 --llm-json=/path/to/llm-match-results.json");
  }

  if (!Number.isInteger(options.contactLimit) || options.contactLimit < 0) {
    throw new Error("参数 --contact-limit 必须是大于等于 0 的整数");
  }

  if (options.syncDb && (!options.materialId || !options.batchId)) {
    throw new Error("同步入库需要同时提供 --material-id 和 --batch-id；仅本地自测可加 --no-sync-db");
  }

  return options;
}

async function main() {
  const options = parseArgs(process.argv.slice(2));
  const outputDir = options.outputDir || path.dirname(options.llmJson);
  const screenshotDir = path.join(outputDir, "final-selected-offers");
  const auditPath = path.join(outputDir, "contact-enrichment-results.json");
  const finalProductsPath = path.join(outputDir, "final-selected-products.json");

  await mkdir(screenshotDir, { recursive: true });
  const raw = JSON.parse(await readFile(options.llmJson, "utf8"));
  const matchedCandidates = normalizeLlmMatchJsonCandidates(raw).filter((candidate) => candidate.is_match);

  const enrichment = await enrichSelectedOfferCandidates({
    candidates: matchedCandidates,
    screenshotDir,
    headless: options.headless,
    targetQualifiedCount: options.contactLimit > 0 ? options.contactLimit : undefined,
    auditPath,
    onCandidateAttempt: ({ attemptedCount, qualifiedCount, targetQualifiedCount, status }) => {
      const target = targetQualifiedCount ?? matchedCandidates.length;
      const label = status === "started"
        ? "开始抓取"
        : status === "qualified"
          ? "有效"
          : "跳过";
      console.log(`[recover-fixed-search] ${label}: 已尝试 ${attemptedCount}，有效 ${qualifiedCount}/${target}`);
    },
  });

  const finalProducts = enrichment.enriched.map((product, index) => ({
    ...product,
    index: index + 1,
    source: "fixed_runtime_search",
    main_keyword: options.mainKeyword || product.input,
    stage_order: options.stageOrder,
    stage_label: options.stageLabel,
    stage_kind: options.stageKind,
    stage_main_keyword: options.mainKeyword || product.input,
    stage_keyword_hit_rate: null,
    stage_rank: index + 1,
    is_placeholder: false,
    placeholder_reason: "",
  }));

  await writeFile(finalProductsPath, JSON.stringify(finalProducts, null, 2), "utf8");

  if (options.syncDb) {
    await syncFinalResult(
      options.materialId,
      options.batchId,
      buildFinalResultPayload(
        options.materialId,
        "fixed_runtime_search",
        options.mainKeyword || finalProducts[0]?.main_keyword || "",
        finalProducts,
      ),
      finalProducts,
    );

    await updateSearchRoundStageDiagnostics({
      batchId: options.batchId,
      materialId: options.materialId,
      stageOrder: options.stageOrder,
      sourceCandidateCount: matchedCandidates.length,
      targetResultCount: options.contactLimit > 0 ? options.contactLimit : null,
      shortageReason: enrichment.shortageReason,
      contactEnrichmentAttempted: true,
      contactEnrichmentSkipReason: "",
    });
  }

  console.log(`[recover-fixed-search] 完成: LLM匹配候选=${matchedCandidates.length} 尝试=${enrichment.attemptedCount} 有效=${finalProducts.length}`);
  console.log(`[recover-fixed-search] 审计文件: ${auditPath}`);
  console.log(`[recover-fixed-search] 最终文件: ${finalProductsPath}`);
}

if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  main().catch((error) => {
    console.error("[recover-fixed-search] 执行失败:", error);
    process.exitCode = 1;
  });
}
