import { displayRate } from "@/lib/judge/grade";
import styles from "./KpiCard.module.css";

/**
 * 数値そのものの色。モック（d-watch-mock.jsx:688）の4枚のカードに対応する。
 * `ProgressBar` の tone と同じ5つに揃えている（`StatTone` は `pr` を持たないため流用不可）。
 */
export type KpiTone = "ok" | "wn" | "ng" | "ac" | "pr";

interface KpiCardProps {
  /** 「稼働率」等。★呼び出し側で `t()` 済みの文字列を渡す★ */
  label: string;
  /** 生値(%)。分母0の期間は null（`lib/judge/kpi.ts` の `rate()` 参照） */
  value: number | null;
  /** 前期との差(%)。`value`/`prev` のどちらかが null なら null（`toKpiValue`） */
  diff: number | null;
  /** 「前週」または「前月」。★呼び出し側で `t()` 済みの文字列を渡す★ */
  prevLabel: string;
  /** 前期の生値(%) */
  prevValue: number | null;
  /**
   * 数値の色。どのKPIが何色かは呼び出し側の知識なので、ここでは受け取った色を使うだけ。
   * モック:688 では 稼働率=ok / 出発成功率=pr / 清掃完了率=ac / エラー発生率=ng。
   */
  tone: KpiTone;
  /**
   * ★前期比の色分けの向き（指示書F 5-4。間違えやすい）★
   *   true : 上がったら良い（稼働率 / 出発成功率 / 清掃完了率）
   *   false: ★下がったら良い（エラー発生率）★
   * 呼び出し側が▲▼の色を毎回組み立てなくて済むよう、反転の判断はこのコンポーネントに閉じる。
   */
  betterWhenHigher: boolean;
}

/** 前期比の意味色。good=改善 / bad=悪化 / neutral=横ばい（または判定不能） */
type DeltaTone = "good" | "bad" | "neutral";

/**
 * `betterWhenHigher` に応じて増減の意味を反転させる。
 * ★丸めた値ではなく生値の符号で判定する★（CLAUDE.md 4.3）。
 * 例: エラー発生率が -0.4 なら表示は「▼0%」だが色は good（改善）。
 */
function deltaTone(diff: number, betterWhenHigher: boolean): DeltaTone {
  if (diff === 0) return "neutral";
  return diff > 0 === betterWhenHigher ? "good" : "bad";
}

/**
 * レポート（F-04）のKPIカード。
 *
 * ★`components/ui/StatCard.tsx` を流用せず新設した理由★（指示書F 5-4 の選択肢2）
 *   - モックのカードは「前期比の行（▲▼）＋補助行（前週: N%）」の2行構成だが、
 *     `StatCard` の `sub` は1行のテキストのみ
 *   - `StatTone` に出発成功率の `pr`（青）が無い
 *   `StatCard` 本体を拡張するとダッシュボード（F-01）に影響が出るため、
 *   レポート専用のカードとして分離した。
 *
 * ★色の受け渡し★
 *   `useTheme()` は呼ばず、CSS変数（`app/globals.css` の `--ok` / `--ng` / `--tx-m` 等）
 *   だけで完結させている。トークンは `[data-theme]` で切り替わるので JS 側で色を持つ必要がなく、
 *   `StatCard` / `ProgressBar` と同じ「色を知らない純粋な表示部品」に揃えられる
 *   （`DsAlertsScreen` 等が `useTheme()` を呼ぶのは、色を条件分岐で組み立てる画面側の都合）。
 */
export function KpiCard({
  label,
  value,
  diff,
  prevLabel,
  prevValue,
  tone,
  betterWhenHigher,
}: KpiCardProps) {
  return (
    <div className={styles.card}>
      <div className={styles.label}>{label}</div>
      <div className={`${styles.value} ${styles[tone]}`}>
        {displayRate(value)}
      </div>
      {/* diff === null（新規施設など前期データなし）は▲▼を出さない。
          `lib/judge/kpi.ts` の `toKpiValue` のコメント参照。
          差が取れないので「→0%」ではなく行そのものを出さない。 */}
      {diff !== null && (
        <div className={styles.deltaRow}>
          <span
            className={`${styles.delta} ${styles[deltaTone(diff, betterWhenHigher)]}`}
          >
            {/* 矢印は生値の符号、数値は整数に丸める（モック:698 と同じ書式）。
                ここでの Math.round は表示専用。色の判定には使わない。 */}
            {diff > 0 ? "▲" : diff < 0 ? "▼" : "→"}
            {Math.round(Math.abs(diff))}%
          </span>
          <span className={styles.deltaLabel}>{prevLabel}比</span>
        </div>
      )}
      <div className={styles.prev}>
        {prevLabel}: {displayRate(prevValue)}
      </div>
    </div>
  );
}
