import type {
  AiKeywordAnalysis,
  LlmAnalysisResult,
  OfflineCombinedStandardizationResult,
  ProcurementDictionaryTermType,
  ProcurementParameterInterpretation,
  RawCsvRow,
} from "../core/types.ts";
import { applyModelNumberOverride } from "./model-number-override.ts";
import { normalizeHumanFixHint } from "./human-fix-hint.ts";

type BatchOutputLine = {
  custom_id?: string;
  id?: string;
  response?: {
    status_code?: number;
    body?: {
      error?: { message?: string };
      message?: string;
      choices?: Array<{
        message?: {
          content?: string;
        };
      }>;
    };
  };
  error?: {
    message?: string;
  };
};

function cleanJsonText(value: string) {
  return value.replace(/```json\s*/g, "").replace(/```\s*/g, "").trim();
}

function toStringArray(value: unknown): string[] {
  if (!Array.isArray(value)) {
    return [];
  }

  return value
    .filter((item): item is string => typeof item === "string")
    .map((item) => item.trim())
    .filter(Boolean);
}

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

const TERM_TYPES = new Set<ProcurementDictionaryTermType>([
  "unique_model",
  "parameter",
  "brand",
  "standard",
  "general",
]);

function normalizeTermType(value: unknown): ProcurementDictionaryTermType {
  return typeof value === "string" && TERM_TYPES.has(value as ProcurementDictionaryTermType)
    ? value as ProcurementDictionaryTermType
    : "parameter";
}

export function parseParameterInterpretations(value: unknown): ProcurementParameterInterpretation[] {
  if (!Array.isArray(value)) {
    return [];
  }

  const seen = new Set<string>();
  const results: ProcurementParameterInterpretation[] = [];

  for (const item of value) {
    if (!item || typeof item !== "object" || Array.isArray(item)) {
      continue;
    }

    const candidate = item as Record<string, unknown>;
    const term = normalizeSearchTerm(candidate.term);
    const interpretation = normalizeSearchTerm(candidate.interpretation);
    if (!term || !interpretation) {
      continue;
    }

    const termType = normalizeTermType(candidate.term_type);
    const productContext = normalizeSearchTerm(candidate.product_context);
    const evidence = normalizeSearchTerm(candidate.evidence);
    const key = `${term.toUpperCase()}::${termType}::${productContext.toLowerCase()}`;
    if (seen.has(key)) {
      continue;
    }

    seen.add(key);
    results.push({
      term,
      term_type: termType,
      product_context: productContext,
      interpretation,
      evidence,
    });
  }

  return results;
}

export function formatParameterInterpretationsSummary(
  interpretations: ProcurementParameterInterpretation[] | undefined,
): string {
  const valid = (interpretations ?? [])
    .map((item) => {
      const term = normalizeSearchTerm(item.term);
      const interpretation = normalizeSearchTerm(item.interpretation);
      if (!term || !interpretation) {
        return "";
      }

      const context = normalizeSearchTerm(item.product_context);
      const evidence = normalizeSearchTerm(item.evidence);
      return [
        `${term}${context ? `（${context}）` : ""}：${interpretation}`,
        evidence ? `依据：${evidence}` : "",
      ].filter(Boolean).join("；");
    })
    .filter(Boolean);

  return valid.length > 0 ? `参数解读：${valid.join("；")}` : "";
}

function compactSearchTerm(value: string): string {
  return normalizeSearchTerm(value).replace(/\s+/g, "").toLowerCase();
}

function buildSearchPhrase(parts: unknown[]): string {
  return parts
    .map((part) => normalizeSearchTerm(part))
    .filter(Boolean)
    .join(" ")
    .trim();
}

function dedupeSearchTerms(values: string[]): string[] {
  const seen = new Set<string>();
  const results: string[] = [];

  for (const value of values) {
    const normalized = normalizeSearchTerm(value);
    if (!normalized) {
      continue;
    }

    const key = compactSearchTerm(normalized);
    if (!key || seen.has(key)) {
      continue;
    }

    seen.add(key);
    results.push(normalized);
  }

  return results;
}

function buildFallbackAlternativeTerms(
  parsed: Record<string, unknown>,
  fallbackRaw: RawCsvRow,
  suggestedKeyword: string,
): string[] {
  const originalName = normalizeSearchTerm(fallbackRaw.名称);
  const originalSpec = normalizeSearchTerm(fallbackRaw.规格型号);
  const simplifiedSpec = normalizeSearchTerm(
    typeof parsed.simplified_spec === "string" ? parsed.simplified_spec : fallbackRaw.规格型号,
  );
  const brandTerm = normalizeSearchTerm(
    typeof parsed.brand_term === "string" ? parsed.brand_term : fallbackRaw.品牌,
  );
  const material = normalizeSearchTerm(typeof parsed.material === "string" ? parsed.material : "");

  const candidates = dedupeSearchTerms([
    buildSearchPhrase([brandTerm, originalName, simplifiedSpec]),
    buildSearchPhrase([material, originalName, simplifiedSpec]),
    buildSearchPhrase([originalName, simplifiedSpec]),
    buildSearchPhrase([brandTerm, originalName]),
    buildSearchPhrase([material, originalName]),
    buildSearchPhrase([originalName, originalSpec]),
    originalName,
  ]);

  const filtered = candidates.filter((term) => compactSearchTerm(term) !== compactSearchTerm(suggestedKeyword));
  if (filtered.length > 0) {
    return filtered.slice(0, 3);
  }

  if (candidates.length > 0) {
    return candidates.slice(0, 1);
  }

  return suggestedKeyword ? [suggestedKeyword] : [];
}

export function parseJsonlLines(content: string): BatchOutputLine[] {
  return content
    .split(/\r?\n/)
    .map((line) => line.trim())
    .filter(Boolean)
    .map((line) => JSON.parse(line) as BatchOutputLine);
}

export function parseOfflineCombinedResult(
  content: string,
  fallbackRaw: RawCsvRow,
): OfflineCombinedStandardizationResult {
  const cleaned = cleanJsonText(content);

  try {
    const parsed = JSON.parse(cleaned) as Record<string, unknown>;
    const suggestedKeyword = typeof parsed.suggested_keyword === "string"
      ? parsed.suggested_keyword.trim()
      : "";
    const generatedAlternativeTerms = toStringArray(parsed.alternative_terms);
    const missingRequiredFields = toStringArray(parsed.missing_required_fields);
    const canSearch1688 = Boolean(parsed.can_search_1688);
    const outcome: "success" | "failed" = parsed.outcome === "success"
      && canSearch1688
      && suggestedKeyword.length > 0
      && missingRequiredFields.length === 0
      ? "success"
      : "failed";

    const result = {
      material: typeof parsed.material === "string" && parsed.material.trim()
        ? parsed.material.trim()
        : "",
      usage: typeof parsed.usage === "string" && parsed.usage.trim()
        ? parsed.usage.trim()
        : "",
      simplified_spec: typeof parsed.simplified_spec === "string"
        ? parsed.simplified_spec.trim()
        : fallbackRaw.规格型号,
      brand_term: typeof parsed.brand_term === "string" ? parsed.brand_term.trim() : "",
      keyword_parameter_terms: toStringArray(parsed.keyword_parameter_terms),
      modifier_terms: toStringArray(parsed.modifier_terms),
      alternative_terms: generatedAlternativeTerms.length > 0
        ? generatedAlternativeTerms
        : buildFallbackAlternativeTerms(parsed, fallbackRaw, suggestedKeyword),
      reasoning: typeof parsed.reasoning === "string" ? parsed.reasoning.trim() : "",
      suggested_keyword: outcome === "success" ? suggestedKeyword : "",
      product_type: typeof parsed.product_type === "string" ? parsed.product_type.trim() : "",
      structure_summary: typeof parsed.structure_summary === "string" ? parsed.structure_summary.trim() : "",
      component_roles: typeof parsed.component_roles === "string" ? parsed.component_roles.trim() : "",
      purchase_type: typeof parsed.purchase_type === "string" ? parsed.purchase_type.trim() : "",
      outcome,
      can_search_1688: outcome === "success",
      missing_required_fields: missingRequiredFields,
      failure_reason: outcome === "failed"
        ? (typeof parsed.failure_reason === "string" && parsed.failure_reason.trim()
            ? parsed.failure_reason.trim()
            : missingRequiredFields.length > 0
              ? `缺少关键采购信息：${missingRequiredFields.join("、")}`
              : "当前信息不足以确认是否可直接在 1688 采购")
        : "",
      human_fix_hint: outcome === "failed"
        ? normalizeHumanFixHint(
            typeof parsed.human_fix_hint === "string" ? parsed.human_fix_hint : "",
            missingRequiredFields,
          )
        : "",
      required_attributes_summary: typeof parsed.required_attributes_summary === "string"
        ? parsed.required_attributes_summary.trim()
        : "",
      parameter_interpretations: parseParameterInterpretations(parsed.parameter_interpretations),
      identified_unique_model: outcome === "success"
        && typeof parsed.identified_unique_model === "string"
        && parsed.identified_unique_model.trim()
        ? parsed.identified_unique_model.trim()
        : "",
    };

    // 型号关联字典后处理：对已知型号强制 success
    const matchText = `${fallbackRaw.名称 ?? ""} ${fallbackRaw.规格型号 ?? ""}`;
    return applyModelNumberOverride(matchText, result);
  } catch {
    throw new Error(`离线标准化结果不是合法 JSON: ${content}`);
  }
}

export function toLlmAnalysisResult(
  result: OfflineCombinedStandardizationResult,
): LlmAnalysisResult {
  return {
    material: result.material,
    usage: result.usage,
    simplified_spec: result.simplified_spec,
    brand_term: result.brand_term,
    keyword_parameter_terms: [...result.keyword_parameter_terms],
    modifier_terms: [...result.modifier_terms],
    alternative_terms: [...result.alternative_terms],
  };
}

export function toAiKeywordAnalysis(
  result: OfflineCombinedStandardizationResult,
): AiKeywordAnalysis {
  return {
    reasoning: result.reasoning,
    suggested_keyword: result.suggested_keyword,
    alt_search_terms: [...result.alternative_terms],
    alternative_keywords: [...result.alternative_terms],
    product_type: result.product_type,
    structure_summary: result.structure_summary,
    component_roles: result.component_roles,
    purchase_type: result.purchase_type,
    outcome: result.outcome,
    can_search_1688: result.can_search_1688,
    missing_required_fields: [...result.missing_required_fields],
    failure_reason: result.failure_reason,
    human_fix_hint: result.human_fix_hint,
    required_attributes_summary: result.required_attributes_summary,
    parameter_interpretations: [...result.parameter_interpretations],
  };
}

export function extractBatchLineMessage(line: BatchOutputLine): string {
  const content = line.response?.body?.choices?.[0]?.message?.content;
  if (typeof content === "string" && content.trim()) {
    return content;
  }

  const errorMessage = line.error?.message
    ?? line.response?.body?.error?.message
    ?? line.response?.body?.message;

  if (typeof errorMessage === "string" && errorMessage.trim()) {
    throw new Error(errorMessage.trim());
  }

  throw new Error("批处理结果缺少可解析的 message.content");
}

export function extractBatchLineStatusCode(line: BatchOutputLine): number {
  return typeof line.response?.status_code === "number" ? line.response.status_code : 0;
}
