"use client";

/**
 * ConfidencePanel — 6.3 «Уверенность прогноза». An overall conf-pill (from
 * confidence.level) + a row per confidence.factors entry, each with a high/mid/
 * low pill. The factors map carries a stray non-factor boolean (advisory_capped)
 * in prod envelopes — narrowed out via a runtime guard (mirrors the light block).
 */

import styles from "@/app/site-finder/analysis/[cad]/ptica/ptica.module.css";
import type { ConfidenceFactor, ReportConfidence } from "@/types/forecast";
import { CONFIDENCE_RU, confidencePill } from "./scenario-helpers";

interface Props {
  confidence: ReportConfidence;
}

const FACTOR_RU: Record<string, string> = {
  deal_count: "Объём данных по сделкам",
  analog_count: "Аналоги (ЖК)",
  domrf_coverage: "Данные по будущим проектам",
  history_months: "Глубина истории",
  component: "Компонент",
  // #1963: раньше рендерились сырым ключом.
  confounded_window: "Окно ряда пересекает шок-период",
  advisory_cap: "Советующий режим",
};

// #1963: weakest-link rule — итог тянет вниз самый слабый фактор.
const WEAKEST_LINK_NOTE =
  "Итоговый уровень задаёт самый слабый фактор (правило «слабого звена»): " +
  "скорее завысим недоверие, чем недооценим риск.";

const LEVEL_RANK: Record<ConfidenceFactor["level"], number> = {
  high: 0,
  medium: 1,
  low: 2,
};

const PILL_CLASS = {
  high: styles.confPillHigh,
  medium: styles.confPillMedium,
  low: styles.confPillLow,
} as const;

function isConfidenceFactor(v: unknown): v is ConfidenceFactor {
  if (typeof v !== "object" || v === null) return false;
  const o = v as Record<string, unknown>;
  return (
    typeof o.note === "string" &&
    (o.level === "high" || o.level === "medium" || o.level === "low")
  );
}

function factorLabel(key: string, factor: ConfidenceFactor): string {
  if (factor.label) return factor.label;
  if (FACTOR_RU[key]) return FACTOR_RU[key];
  const m = key.match(/^component(?:_(\d+))?$/);
  if (m) return m[1] ? `Компонент ${m[1]}` : "Компонент";
  return key;
}

export function ConfidencePanel({ confidence }: Props) {
  const level = confidence.level;
  const drivers = Object.entries(confidence.factors)
    .filter((entry): entry is [string, ConfidenceFactor] =>
      isConfidenceFactor(entry[1]),
    )
    .sort((a, b) => LEVEL_RANK[a[1].level] - LEVEL_RANK[b[1].level]);

  return (
    <div className={styles.panel}>
      <div className={styles.cardHead}>
        <h3 className={styles.cardTitle}>Уверенность прогноза</h3>
        {level && (
          <span
            className={`${styles.confPill} ${PILL_CLASS[confidencePill(level)]}`}
          >
            {CONFIDENCE_RU[level]}
          </span>
        )}
      </div>
      {/* #1963 — почему именно такой уровень: rationale из payload + правило. */}
      {confidence.rationale && (
        <p className={styles.confRationale}>{confidence.rationale}</p>
      )}
      <p className={styles.confRule}>{WEAKEST_LINK_NOTE}</p>

      {drivers.length > 0 ? (
        drivers.map(([key, factor]) => (
          <div key={key} className={styles.confItem}>
            <div className={styles.confItemHead}>
              <span className={styles.confName}>
                {factorLabel(key, factor)}
              </span>
              <span
                className={`${styles.confPill} ${PILL_CLASS[confidencePill(factor.level)]}`}
              >
                {CONFIDENCE_RU[factor.level]}
              </span>
            </div>
            {/* #1963 — показываем note фактора (раньше скрыт). */}
            {factor.note && <p className={styles.confNote}>{factor.note}</p>}
          </div>
        ))
      ) : (
        <p className={styles.panelHint}>Факторы достоверности недоступны.</p>
      )}
    </div>
  );
}
