import { RpaError } from "@/modules/rpa/errors";
import {
  resolveGuaranteedLowestTier,
} from "@/workers/rpa/quote-capture/axel-contract";
import {
  normalizeQuote,
  type CanonicalQuote,
} from "@/workers/rpa/quote-capture/quote-normalize";

export type QuoteContractRates = Record<string, unknown>;

export type QuoteContractViolation = {
  path: string;
  reason: string;
};

const PRICE_KEYS = [
  "price",
  "freight",
  "amount",
  "cost",
  "total",
  "rawfreight",
  "rate",
  "basequoteprice",
  "finalprice",
] as const;

function readPrice(tier: unknown): number | null {
  if (tier == null || typeof tier !== "object" || Array.isArray(tier)) {
    return null;
  }
  const obj = tier as Record<string, unknown>;
  for (const key of Object.keys(obj)) {
    const nk = key.replace(/[^a-z0-9]/gi, "").toLowerCase();
    if (!PRICE_KEYS.includes(nk as (typeof PRICE_KEYS)[number])) {
      continue;
    }
    const val = obj[key];
    if (typeof val === "number" && val > 0) {
      return val;
    }
    if (typeof val === "string") {
      const m = val.replace(/,/g, "").match(/(\d+(?:\.\d+)?)/);
      if (m) {
        const n = Number(m[1]);
        if (n > 0) {
          return n;
        }
      }
    }
  }
  return null;
}

function getAt(obj: unknown, ...keys: string[]): unknown {
  let cur = obj;
  for (const key of keys) {
    if (cur == null || typeof cur !== "object" || Array.isArray(cur)) {
      return undefined;
    }
    cur = (cur as Record<string, unknown>)[key];
  }
  return cur;
}

function isPricedTier(tier: unknown): boolean {
  return readPrice(tier) !== null;
}

/** 契约校验仅作用于 normalized rates */
export function inspectQuoteContractOnRates(
  rates: QuoteContractRates,
): { ok: true; rates: QuoteContractRates } | { ok: false; violations: QuoteContractViolation[] } {
  const violations: QuoteContractViolation[] = [];

  if (!isPricedTier(getAt(rates, "standard", "lowest"))) {
    violations.push({
      path: "rates.standard.lowest",
      reason: "缺失或无效价格",
    });
  }

  const fastestTop = getAt(rates, "fastest");
  const fastestStd = getAt(rates, "standard", "fastest");
  if (!isPricedTier(fastestTop) && !isPricedTier(fastestStd)) {
    violations.push({
      path: "rates.fastest",
      reason: "rates.fastest 与 rates.standard.fastest 均缺失或无效价格",
    });
  }

  const guaranteed = rates.guaranteed;
  if (
    guaranteed == null ||
    typeof guaranteed !== "object" ||
    Array.isArray(guaranteed)
  ) {
    violations.push({
      path: "rates.guaranteed",
      reason: "缺失 guaranteed 分支",
    });
  } else if (!isPricedTier(resolveGuaranteedLowestTier(guaranteed))) {
    violations.push({
      path: "rates.guaranteed.lowest",
      reason: "缺失 lowest/bestValue 或无效价格",
    });
  }

  if (violations.length > 0) {
    return { ok: false, violations };
  }

  return { ok: true, rates };
}

export function inspectQuoteContract(
  body: unknown,
):
  | { ok: true; rates: QuoteContractRates; canonical: CanonicalQuote }
  | { ok: false; violations: QuoteContractViolation[] } {
  const canonical = normalizeQuote(body);
  if (!canonical) {
    return {
      ok: false,
      violations: [{ path: "rates", reason: "normalizeQuote 未解析到 rates" }],
    };
  }

  const checked = inspectQuoteContractOnRates(canonical.rates);
  if (!checked.ok) {
    return checked;
  }

  return { ok: true, rates: checked.rates, canonical };
}

export function satisfiesQuoteContract(body: unknown): boolean {
  return inspectQuoteContract(body).ok;
}

export function assertQuoteContract(
  body: unknown,
  context?: string,
): QuoteContractRates {
  const result = inspectQuoteContract(body);
  if (!result.ok) {
    const detail = result.violations
      .map((v) => `${v.path}: ${v.reason}`)
      .join("; ");
    throw new RpaError(
      "RPA_DATA_INVALID",
      `报价契约校验失败${context ? ` (${context})` : ""}: ${detail}`,
      { retryable: false },
    );
  }
  return result.rates;
}
