"use client";

import { useTheme } from "@/components/theme/ThemeProvider";
import { FilterButton } from "@/components/ui/FilterButton";
import { GradeBadge } from "@/components/ui/GradeBadge";
import { ProgressBar } from "@/components/ui/ProgressBar";
import type { AreaFilter } from "@/lib/clean-logs/areas";
import { displayRate, isProblemGrade } from "@/lib/judge";
import { THEME_TOKENS } from "@/lib/theme";
import type { AreaCompletionsResponse, Grade } from "@/lib/types";
import styles from "./AreaModal.module.css";

interface AreaModalProps {
  facilityName: string;
  dateLabel: string;
  /** ★サーバ側で絞るので、切り替えたら親が再取得する★（指示書Z 決定8） */
  filter: AreaFilter;
  onChangeFilter: (filter: AreaFilter) => void;
  /** 取得できていないあいだは null（`loading` / `error` を見て出し分ける） */
  data: AreaCompletionsResponse | null;
  loading: boolean;
  error: string | null;
  onClose: () => void;
}

/** バーの色（モックと同じ対応）。★判定そのものはAPIが返した `grade` を使う★ */
function barTone(grade: Grade): "ok" | "wn" | "ng" {
  if (grade === "◎" || grade === "○") return "ok";
  if (grade === "△") return "wn";
  return "ng";
}

/**
 * エリア別清掃完了率のモーダル（F-02 の「エリア別詳細を見る →」から開く）。
 *
 * ★★並び順・判定・件数はすべてAPIが返したものをそのまま使う★★（`CLAUDE.md` §9.6）—
 *   ★フロントで並べ替え・再判定をしないこと★。`filter` の絞り込みもサーバ側。
 *
 * ★行の完了率は1回ごとの完了率★（`runCompletionRate()`。`min(clean_area ÷ task_area × 100, 100)` を
 *   小数第1位まで切り捨て。D-155）。
 * ★全体率（ヘッダの「全体」）は行の完了率の単純平均（清掃1回＝1票）★なので、
 *   ★★行の完了率を足し合わせて件数で割れば全体率と一致する★★（未実施＝完了率が `null` の行は
 *   分子にも分母にも入れない）。計算は APIルート側の `buildAreaCompletions()`
 *   （`lib/clean-logs/areas.ts`）。★以前は全体だけ面積ベースの「意図した非対称」だった★
 *   （指示書Z 決定7）が、2026-09-30 に単純平均へ揃えた（D-151。指示書AQ §5-5）。
 *   ★2026-10-02 に、平均する材料を `clean_ratio` 列から1回ごとの完了率へ変えた（D-155。指示書AS）★。
 *
 * ★未実施のエリアは `completion_rate` が `null`★ → `displayRate()` が `-` を返し、
 *   バーは 0 幅、判定は `×`。★`0%` と表示しないこと★（D-107 落とし穴1）。
 */
export function AreaModal({
  facilityName,
  dateLabel,
  filter,
  onChangeFilter,
  data,
  loading,
  error,
  onClose,
}: AreaModalProps) {
  const { t, theme } = useTheme();
  const c = THEME_TOKENS[theme];

  return (
    <div className={styles.overlay} role="dialog" aria-modal="true">
      <div className={styles.panel}>
        <div className={styles.header}>
          <div className={styles.headerRow}>
            <div>
              <div className={styles.title}>{t("エリア別清掃完了率")}</div>
              <div className={styles.meta}>
                {facilityName} | {dateLabel}
                {data && (
                  <>
                    {" "}
                    | {t("全体")} {displayRate(data.overall_completion_rate)}{" "}
                    {data.overall_grade}
                  </>
                )}
              </div>
            </div>
            <button type="button" className={styles.close} onClick={onClose}>
              ✕
            </button>
          </div>
          <div className={styles.filters}>
            <FilterButton
              active={filter === "problem"}
              color={c.pr}
              onClick={() => onChangeFilter("problem")}
            >
              {t("問題エリアのみ")}
            </FilterButton>
            <FilterButton
              active={filter === "all"}
              color={c.pr}
              onClick={() => onChangeFilter("all")}
            >
              {t("全件")}
            </FilterButton>
          </div>
        </div>

        <div className={styles.body}>
          {loading && <div className={styles.message}>{t("読み込み中…")}</div>}
          {!loading && error && <div className={styles.message}>{error}</div>}
          {!loading && !error && data && (
            <>
              <div className={styles.countLine}>
                {filter === "problem"
                  ? t("問題エリア（{n} / {m}エリア）")
                      .replace("{n}", String(data.problem_count))
                      .replace("{m}", String(data.total_count))
                  : t("全{n}エリア（完了率昇順）").replace(
                      "{n}",
                      String(data.total_count)
                    )}
              </div>
              {data.items.length === 0 && (
                <div className={styles.message}>
                  {/* ★「全部◎○だった」と「そもそもエリアが1つも無い」を区別する★ —
                      同じ文言にすると、データが取れていないことに気づけない */}
                  {data.total_count === 0
                    ? t("エリアのデータがありません")
                    : t("問題エリアはありません（全エリア◎○）")}
                </div>
              )}
              {data.items.map((item) => {
                // ★APIが返した `grade` を見るだけ（閾値でここで判定し直さない）★
                const problem = isProblemGrade(item.grade);
                return (
                  <div key={item.section_id} className={styles.row}>
                    <div
                      className={`${styles.areaName} ${problem ? styles.areaNameProblem : ""}`}
                      title={item.section_name}
                    >
                      {item.section_name}
                    </div>
                    <div className={styles.bar}>
                      {/* ★未実施（null）は 0 幅★ */}
                      <ProgressBar
                        percent={item.completion_rate ?? 0}
                        tone={barTone(item.grade)}
                      />
                    </div>
                    {/* ★丸めるのは表示のときだけ（`CLAUDE.md` §4.3）。未実施は `-`★ */}
                    <div className={styles.rate} data-tone={barTone(item.grade)}>
                      {displayRate(item.completion_rate)}
                    </div>
                    <GradeBadge grade={item.grade} />
                  </div>
                );
              })}
            </>
          )}
        </div>

        <div className={styles.footer}>
          <button type="button" className={styles.closeBtn} onClick={onClose}>
            {t("閉じる")}
          </button>
        </div>
      </div>
    </div>
  );
}
