/* global React */

// 金額フォーマット
function formatYen(n) {
  return "¥" + (n || 0).toLocaleString("ja-JP");
}
function formatYenShort(n) {
  if (n >= 10_000_000) return "¥" + (n / 10_000_000).toFixed(2).replace(/\.?0+$/, "") + "千万";
  if (n >= 10_000) return "¥" + (Math.round(n / 1000) / 10).toFixed(1).replace(/\.0$/, "") + "万";
  return "¥" + n.toLocaleString("ja-JP");
}
function formatPct(rate, digits = 1) {
  return (rate * 100).toFixed(digits) + "%";
}
function formatCount(n) {
  return (n || 0).toLocaleString("ja-JP") + "件";
}

// 達成率 → 状態 (good / warn / bad)
function rateState(rate) {
  if (rate >= 1.0)  return "good";
  if (rate >= 0.7)  return "warn-good"; // 既存仕様にはないが視覚的補強。styles では good 扱い。
  if (rate >= 0.3)  return "warn";
  return "bad";
}
// 仕様準拠: 100%+=good / 70-99%=warn / <70%=bad
function rateBand(rate) {
  if (rate >= 1.0) return "good";
  if (rate >= 0.7) return "warn";
  return "bad";
}

// 100%超を考慮したバー幅 (最大表示は 120% 程度)
function clampBarWidth(rate) {
  return Math.min(rate, 1.2) / 1.2 * 100;
}

// =========================================================================
// Donut (純粋SVG)
// =========================================================================
function Donut({ data, size = 200, thickness = 22, colors }) {
  const radius = (size - thickness) / 2;
  const cx = size / 2;
  const cy = size / 2;
  const circumference = 2 * Math.PI * radius;
  const total = data.reduce((a, b) => a + b.value, 0);

  let cumulative = 0;
  const arcs = data.map((d, i) => {
    const fraction = total > 0 ? d.value / total : 0;
    const dasharray = `${fraction * circumference} ${circumference}`;
    const offset = -cumulative * circumference;
    cumulative += fraction;
    return (
      <circle
        key={d.key}
        cx={cx}
        cy={cy}
        r={radius}
        fill="none"
        stroke={colors[i % colors.length]}
        strokeWidth={thickness}
        strokeDasharray={dasharray}
        strokeDashoffset={offset}
        transform={`rotate(-90 ${cx} ${cy})`}
        style={{ transition: "stroke-dasharray 700ms cubic-bezier(0.22,1,0.36,1), stroke-dashoffset 700ms cubic-bezier(0.22,1,0.36,1)" }}
      />
    );
  });

  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle cx={cx} cy={cy} r={radius} fill="none" stroke="var(--ctp-surface0)" strokeWidth={thickness} />
      {arcs}
    </svg>
  );
}

// =========================================================================
// ヒートマップ用カラースケール (青の濃淡)
// =========================================================================
function heatColor(value, max) {
  if (!value || value <= 0) return null;
  // 0..1 → 透明度0.10..1.0 の青
  const t = Math.min(1, value / max);
  // ease (見栄え調整: 小さな値も視認できるよう sqrt)
  const eased = Math.sqrt(t);
  const alpha = 0.12 + eased * 0.78;
  return `rgba(137, 180, 250, ${alpha.toFixed(3)})`;
}

function heatTextColor(value, max) {
  if (!value || value <= 0) return "var(--ctp-overlay1)";
  const t = Math.min(1, value / max);
  const eased = Math.sqrt(t);
  // 濃いセルでは crust 系の暗色テキスト、薄いセルではテキスト色
  return eased > 0.55 ? "var(--ctp-crust)" : "var(--ctp-text)";
}

// 公開
Object.assign(window, {
  formatYen, formatYenShort, formatPct, formatCount,
  rateBand, clampBarWidth,
  Donut, heatColor, heatTextColor,
});
