/**
 * 仓库改价对比工具
 * 库内价格 decimal(10,4)。预览对比禁止 format_price。
 * Excel IEEE 浮点常见把 0.91 读成 ≈0.8999→0.90，需在合并时与快照对账。
 */
export type PricePair = {
  market_price: number;
  price: number;
  unit_name?: string;
};

export function parsePriceValue(value: unknown): number {
  if (value === null || value === undefined || value === '') {
    return 0;
  }
  if (typeof value === 'string') {
    const cleaned = value.trim().replace(/,/g, '').replace(/￥/g, '');
    if (cleaned === '') {
      return 0;
    }
    const num = Number(cleaned);
    return Number.isFinite(num) ? num : 0;
  }
  const num = Number(value);
  return Number.isFinite(num) ? num : 0;
}

/** 对齐库字段 decimal(10,4) */
export function roundPrice4(value: unknown): number {
  return Math.round(parsePriceValue(value) * 10000) / 10000;
}

/**
 * Excel 读入价与快照对账：未改到「分」或仅 1 分浮点漂移时，强制用快照价
 * 避免 0.91→0.90、0.09→0.08 这类误报
 */
export function reconcileExcelPrice(excel: unknown, snapshot: unknown): number {
  const e = roundPrice4(excel);
  const s = roundPrice4(snapshot);
  if (e === s) {
    return s;
  }
  const fenE = Math.round(e * 100);
  const fenS = Math.round(s * 100);
  // 分位相同 → 未改价
  if (fenE === fenS) {
    return s;
  }
  // 仅差 1 分且更像浮点下漂/上漂，视为未改（用户真改 1 分极少见于每克价误触）
  if (Math.abs(fenE - fenS) === 1 && Math.abs(e - s) <= 0.011) {
    return s;
  }
  return e;
}

/**
 * 与后端 format_price 一致：仅确认落库时用
 */
export function formatPriceLikeBackend(value: unknown): number {
  const price = parsePriceValue(value);
  let milli = Math.round(price * 1000);
  if (milli % 10 > 0) {
    milli += 10;
  }
  milli -= milli % 10;
  return Math.round((milli / 1000) * 100) / 100;
}

export function normalizePricePair(pair: PricePair): PricePair {
  return {
    market_price: roundPrice4(pair.market_price),
    price: roundPrice4(pair.price),
    unit_name: (pair.unit_name ?? '').trim(),
  };
}

export function toPriceUnits(value: unknown): number {
  return Math.round(roundPrice4(value) * 10000);
}

export function formatPriceDisplay(value: unknown): string {
  const n = roundPrice4(value);
  const fixed = n.toFixed(4);
  return fixed.replace(/\.?0+$/, '') || '0';
}

export type PriceDelta = 'up' | 'down' | 'same';

export function getPriceDelta(orig: number, next: number): PriceDelta {
  const a = toPriceUnits(orig);
  const b = toPriceUnits(next);
  if (b > a) {
    return 'up';
  }
  if (b < a) {
    return 'down';
  }
  return 'same';
}

export function isFieldChanged(orig: number, next: number): boolean {
  return getPriceDelta(orig, next) !== 'same';
}

export function isUnitChanged(
  orig: string | undefined,
  next: string | undefined,
): boolean {
  return (orig ?? '').trim() !== (next ?? '').trim();
}

export function isPriceChanged(
  initial: PricePair | undefined,
  current: PricePair,
): boolean {
  if (!initial) {
    return true;
  }
  return (
    isFieldChanged(initial.market_price, current.market_price) ||
    isFieldChanged(initial.price, current.price) ||
    isUnitChanged(initial.unit_name, current.unit_name)
  );
}

export function isMarketGtPrice(current: PricePair): boolean {
  return toPriceUnits(current.market_price) > toPriceUnits(current.price);
}
