"use client";

/**
 * 6.3 Уровень уверенности — level pill + EXPLICIT drivers list from
 * confidence.factors (DoD: «явный список drivers»).
 *
 * The factors map is mostly { note, level, value } entries, but the prod
 * envelope also carries a stray boolean `advisory_capped` — narrowed out via a
 * runtime type guard so we never render a non-factor.
 */

import { Badge } from "@/components/ui/Badge";
import type { ConfidenceFactor, ReportConfidence } from "@/types/forecast";
import { CONFIDENCE_RU, confidenceVariant } from "./forecast-helpers";

interface Props {
  confidence: ReportConfidence;
}

// Human-readable labels for known factor keys; unknown keys fall back to the key.
const FACTOR_RU: Record<string, string> = {
  deal_count: "Объём сделок",
  analog_count: "Аналоги (ЖК)",
  domrf_coverage: "Покрытие ДОМ.РФ",
  history_months: "Глубина истории",
  component: "Компонент",
};

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): string {
  if (FACTOR_RU[key]) return FACTOR_RU[key];
  // component_2..N → «Компонент N» (note уже несёт «вкладывающий сервис: …»)
  const m = key.match(/^component_(\d+)$/);
  if (m) return `Компонент ${m[1]}`;
  return key;
}

function formatFactorValue(value: number | null): string | null {
  if (value == null) return null;
  // Fractions in 0..1 read as percent (e.g. coverage); integers/large stay raw.
  // Upper bound is inclusive so full coverage (1.0) renders as «100%», not «1».
  if (value > 0 && value <= 1) return `${Math.round(value * 100)}%`;
  return Math.round(value).toLocaleString("ru");
}

export function ForecastConfidenceBlock({ confidence }: Props) {
  const level = confidence.level;

  const drivers = Object.entries(confidence.factors)
    .filter((entry): entry is [string, ConfidenceFactor] =>
      isConfidenceFactor(entry[1]),
    )
    // Sort high → medium → low so the strongest evidence reads first.
    .sort((a, b) => LEVEL_RANK[a[1].level] - LEVEL_RANK[b[1].level]);

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {/* Level pill + rationale */}
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <span
            style={{
              fontSize: 11,
              fontWeight: 500,
              letterSpacing: "0.04em",
              textTransform: "uppercase",
              color: "var(--fg-secondary)",
            }}
          >
            Уровень уверенности
          </span>
          {level ? (
            <Badge variant={confidenceVariant(level)} size="md">
              {CONFIDENCE_RU[level]}
            </Badge>
          ) : (
            <span style={{ fontSize: 13, color: "var(--fg-tertiary)" }}>
              не определена
            </span>
          )}
        </div>
        {confidence.rationale && (
          <p
            style={{
              margin: 0,
              fontSize: 13,
              lineHeight: 1.5,
              color: "var(--fg-secondary)",
            }}
          >
            {confidence.rationale}
          </p>
        )}
      </div>

      {/* Explicit drivers list */}
      {drivers.length > 0 ? (
        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          <span
            style={{
              fontSize: 11,
              fontWeight: 500,
              letterSpacing: "0.04em",
              textTransform: "uppercase",
              color: "var(--fg-secondary)",
            }}
          >
            Факторы достоверности ({drivers.length})
          </span>
          <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
            {drivers.map(([key, factor]) => {
              const valueStr = formatFactorValue(factor.value);
              return (
                <div
                  key={key}
                  style={{
                    display: "flex",
                    alignItems: "flex-start",
                    gap: 8,
                    padding: "8px 12px",
                    background: "var(--bg-card-alt)",
                    border: "1px solid var(--border-soft)",
                    borderRadius: 8,
                  }}
                >
                  <Badge variant={confidenceVariant(factor.level)} size="sm">
                    {CONFIDENCE_RU[factor.level]}
                  </Badge>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div
                      style={{
                        fontSize: 13,
                        fontWeight: 500,
                        color: "var(--fg-primary)",
                      }}
                    >
                      {factorLabel(key)}
                      {valueStr != null && (
                        <span
                          style={{
                            marginLeft: 6,
                            fontWeight: 400,
                            color: "var(--fg-secondary)",
                            fontVariantNumeric: "tabular-nums",
                          }}
                        >
                          · {valueStr}
                        </span>
                      )}
                    </div>
                    <div
                      style={{
                        fontSize: 12,
                        color: "var(--fg-tertiary)",
                        marginTop: 2,
                      }}
                    >
                      {factor.note}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      ) : (
        <p style={{ fontSize: 13, color: "var(--fg-tertiary)", margin: 0 }}>
          Факторы достоверности недоступны.
        </p>
      )}
    </div>
  );
}

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