// 社交 BI v2 的展示格式化层：所有视图共用，保证同一指标在任何视图里的写法一致。
// 后端金额一律是 USD 分（*_usd_minor），比例一律是 0-1 小数，这里统一换算。

const numberFormatter = new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 });
const decimalFormatter = new Intl.NumberFormat("en-US", { maximumFractionDigits: 1, minimumFractionDigits: 1 });

export function isBlank(value) {
  return value === null || value === undefined || value === "" || (typeof value === "number" && !Number.isFinite(value));
}

export function formatMoneyMinor(value) {
  if (isBlank(value)) {
    return "--";
  }
  return formatMoney(Number(value) / 100);
}

export function formatMoney(value) {
  if (isBlank(value)) {
    return "--";
  }
  const numeric = Number(value);
  const digits = Math.abs(numeric) < 1000 && !Number.isInteger(numeric) ? 1 : 0;
  return `$${numeric.toLocaleString("en-US", { maximumFractionDigits: digits, minimumFractionDigits: digits })}`;
}

export function formatCount(value) {
  if (isBlank(value)) {
    return "--";
  }
  return numberFormatter.format(Number(value));
}

// 金币等大数值在卡片/图表标签里用紧凑写法（1.2亿 视觉负担太大，用 en 缩写与后台其余模块一致）。
export function formatCompact(value) {
  if (isBlank(value)) {
    return "--";
  }
  const numeric = Number(value);
  const abs = Math.abs(numeric);
  if (abs >= 1_000_000_000) {
    return `${(numeric / 1_000_000_000).toFixed(1)}B`;
  }
  if (abs >= 1_000_000) {
    return `${(numeric / 1_000_000).toFixed(1)}M`;
  }
  if (abs >= 10_000) {
    return `${(numeric / 1_000).toFixed(1)}K`;
  }
  return numberFormatter.format(numeric);
}

export function formatRatioPercent(value) {
  if (isBlank(value)) {
    return "--";
  }
  return `${decimalFormatter.format(Number(value) * 100)}%`;
}

export function formatPercentValue(value) {
  if (isBlank(value)) {
    return "--";
  }
  return `${decimalFormatter.format(Number(value))}%`;
}

export function formatDurationMs(value) {
  if (isBlank(value)) {
    return "--";
  }
  const totalSeconds = Math.max(0, Math.round(Number(value) / 1000));
  if (totalSeconds < 60) {
    return `${totalSeconds}秒`;
  }
  const totalMinutes = Math.round(totalSeconds / 60);
  if (totalMinutes < 60) {
    return `${totalMinutes}分`;
  }
  const hours = Math.floor(totalMinutes / 60);
  const minutes = totalMinutes % 60;
  return minutes ? `${hours}小时${minutes}分` : `${hours}小时`;
}

// 环比：后端 delta 字段是 0-1 增幅（0.12 = +12%）。
export function formatDeltaRate(value) {
  if (isBlank(value)) {
    return "";
  }
  const numeric = Number(value) * 100;
  const sign = numeric >= 0 ? "+" : "";
  return `${sign}${decimalFormatter.format(numeric)}%`;
}

export function deltaDirection(value) {
  if (isBlank(value) || Number(value) === 0) {
    return "flat";
  }
  return Number(value) > 0 ? "up" : "down";
}

export function csvEscape(value) {
  const text = String(value ?? "");
  if (/[",\n]/.test(text)) {
    return `"${text.replace(/"/g, '""')}"`;
  }
  return text;
}

export function downloadCsv(filename, headerCells, rows) {
  const lines = [headerCells.map(csvEscape).join(",")];
  rows.forEach((cells) => {
    lines.push(cells.map(csvEscape).join(","));
  });
  const blob = new Blob(["\uFEFF", lines.join("\n")], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = filename;
  anchor.click();
  URL.revokeObjectURL(url);
}
