"use client";

/**
 * 6.1 Прогноз по горизонтам — compact table over future_market.forecasts_by_horizon.
 *
 * Columns: горизонт (мес) · индекс дефицита (color-coded) ·
 * прогноз спроса/предложения · ставка (% годовых) · фраза чувствительности к ставке.
 *
 * MOI (months_of_inventory) НЕ выводим по горизонтам: по определению он не зависит
 * от горизонта проекции, поэтому колонка дублировала одно и то же число 4 раза
 * (выглядело сломанным). MOI показан один раз в Section6Forecast key_numbers.
 *
 * Deficit semantics (HARD, see frontend rules):
 *   deficit_index > 0  → недонасыщенность (повод строить)  → success/green
 *   deficit_index < 0  → затоварка (предложения > спроса)  → warn/danger
 *   deficit_index ≈ 0  → баланс                            → neutral
 */

import { Badge } from "@/components/ui/Badge";
import type { DemandSupplyForecast } from "@/types/forecast";
import {
  deficitPegPlaque,
  deficitVariant,
  deficitWord,
  fmtNum,
  isDeficitPegged,
  type DeficitPegState,
} from "./forecast-helpers";

interface Props {
  forecasts: DemandSupplyForecast[];
  /** Horizon (мес) to emphasise as the current target — highlights its row. */
  targetHorizon?: number;
  /**
   * B1 (#1958/#1959) — pegged-signal state (deficit_index уперся в край шкалы на
   * всех горизонтах). Считается в Section6Forecast по общему ряду и прокидывается
   * сюда + в 6.2, чтобы плашка «на пределе» не разъезжалась. Когда не задан —
   * по умолчанию «не pegged» (плашка скрыта).
   */
  peg?: DeficitPegState;
}

const TH_STYLE: React.CSSProperties = {
  textAlign: "left",
  padding: "8px 12px",
  fontSize: 11,
  fontWeight: 500,
  letterSpacing: "0.04em",
  textTransform: "uppercase",
  color: "var(--fg-secondary)",
  whiteSpace: "nowrap",
  borderBottom: "1px solid var(--border-card)",
};

const TD_STYLE: React.CSSProperties = {
  padding: "10px 12px",
  fontSize: 13,
  color: "var(--fg-primary)",
  verticalAlign: "top",
  borderBottom: "1px solid var(--border-soft)",
  fontVariantNumeric: "tabular-nums",
};

const NUM_TD: React.CSSProperties = { ...TD_STYLE, textAlign: "right" };

export function ForecastHorizonsBlock({
  forecasts,
  targetHorizon,
  peg,
}: Props) {
  if (forecasts.length === 0) {
    return (
      <p style={{ fontSize: 13, color: "var(--fg-tertiary)", margin: 0 }}>
        Прогноз по горизонтам недоступен.
      </p>
    );
  }

  const rows = [...forecasts].sort(
    (a, b) => a.horizon_months - b.horizon_months,
  );

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {/* B1 — честная плашка, когда индекс упёрся в край шкалы на всех горизонтах:
          точное «−1.00 ×4» не различает горизонты, оценка грубая. */}
      {peg?.pegged && peg.sign != null && <DeficitPegPlaque sign={peg.sign} />}

      <div style={{ overflowX: "auto" }}>
        <table
          style={{
            width: "100%",
            borderCollapse: "collapse",
            minWidth: 720,
          }}
        >
          <thead>
            <tr>
              <th style={TH_STYLE}>Горизонт</th>
              <th style={TH_STYLE}>Индекс дефицита</th>
              <th style={{ ...TH_STYLE, textAlign: "right" }}>
                Прогноз спроса, квартир
              </th>
              <th style={{ ...TH_STYLE, textAlign: "right" }}>
                Прогноз предложения, квартир
              </th>
              <th style={{ ...TH_STYLE, textAlign: "right" }}>Ставка</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((f) => {
              const di = f.deficit_index;
              const isTarget = f.horizon_months === targetHorizon;
              return (
                <tr
                  key={f.horizon_months}
                  style={
                    isTarget ? { background: "var(--accent-soft)" } : undefined
                  }
                >
                  <td
                    style={
                      isTarget
                        ? {
                            ...TD_STYLE,
                            fontWeight: 600,
                            color: "var(--accent)",
                          }
                        : TD_STYLE
                    }
                  >
                    {f.horizon_months} мес.
                    {isTarget && (
                      <span
                        style={{
                          marginLeft: 8,
                          fontSize: 11,
                          fontWeight: 500,
                          letterSpacing: "0.04em",
                          textTransform: "uppercase",
                          color: "var(--accent)",
                        }}
                      >
                        Целевой
                      </span>
                    )}
                  </td>
                  <td style={TD_STYLE}>
                    <Badge variant={deficitVariant(di)} size="sm">
                      {di > 0 ? "+" : ""}
                      {fmtNum(di, 2)}
                    </Badge>
                    <span
                      style={{
                        marginLeft: 8,
                        fontSize: 12,
                        color: "var(--fg-secondary)",
                      }}
                    >
                      {deficitWord(di)}
                    </span>
                    {/* B1 — значение на краю шкалы: помечаем «на пределе», чтобы
                        одинаковые −1.00 ×4 не читались как ложно-точные. */}
                    {peg?.pegged && isDeficitPegged(di) && (
                      <span
                        style={{
                          marginLeft: 8,
                          fontSize: 11,
                          fontWeight: 500,
                          letterSpacing: "0.04em",
                          textTransform: "uppercase",
                          color: "var(--fg-tertiary)",
                        }}
                      >
                        на пределе
                      </span>
                    )}
                  </td>
                  <td style={NUM_TD}>
                    {Math.round(f.projected_demand_units).toLocaleString("ru")}
                  </td>
                  <td style={NUM_TD}>
                    {Math.round(f.projected_supply_units).toLocaleString("ru")}
                  </td>
                  <td style={NUM_TD}>{fmtNum(f.rate_future, 2)}%</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {/* Caveat — единицы и статус оценки под таблицей (advisory, не решение). */}
      <p
        style={{
          margin: 0,
          fontSize: 12,
          lineHeight: "16px",
          color: "var(--fg-tertiary)",
        }}
      >
        Спрос/предложение — прогнозные квартиры за горизонт; оценка advisory,
        уверенность ≤ средней.
      </p>

      {/* B3 — почему «Прогноз предложения» здесь может быть 0, хотя в §4.3 виден
          крупный pipeline: баланс §6 посегментный (класс/район), а §4.3 — класс-
          агностичный будущий ввод. Снимает кажущееся противоречие 4.3 ↔ 6. */}
      <p
        style={{
          margin: 0,
          fontSize: 12,
          lineHeight: "16px",
          color: "var(--fg-tertiary)",
        }}
      >
        Баланс считается по сегменту (класс/район); класс-агностичный будущий
        pipeline из раздела 4.3 в посегментный баланс не входит — поэтому
        будущее предложение здесь может быть 0.
      </p>

      {/* Rate-sensitivity phrase — shared across horizons in current data; show
          the distinct phrases once each to avoid noisy repetition. */}
      <RateSensitivityNotes forecasts={rows} />
    </div>
  );
}

/**
 * B1 (#1958/#1959) — honest plaque shown above 6.1 / inside 6.2 when the deficit
 * signal is saturated at the scale edge on every horizon. Exported so 6.2
 * (ScenariosBlock) renders the identical plaque (one visual source of truth). The
 * RU text comes from `deficitPegPlaque` (helper) — never hardcoded per block.
 * Warn pattern (--warn-soft / role="note") как у остальных caveat-плашек §6.
 */
export function DeficitPegPlaque({ sign }: { sign: -1 | 1 }) {
  return (
    <div
      role="note"
      style={{
        padding: "10px 14px",
        borderRadius: 8,
        background: "var(--warn-soft, #FEF3C7)",
        border: "1px solid var(--warn, #9A6700)",
        fontSize: 12,
        lineHeight: "16px",
        color: "var(--warn, #9A6700)",
      }}
    >
      {deficitPegPlaque(sign)}
    </div>
  );
}

function RateSensitivityNotes({
  forecasts,
}: {
  forecasts: DemandSupplyForecast[];
}) {
  const phrases = Array.from(
    new Set(
      forecasts
        .map((f) => f.rate_sensitivity_phrase?.trim())
        .filter((p): p is string => !!p),
    ),
  );
  if (phrases.length === 0) return null;

  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 4,
        fontSize: 12,
        color: "var(--fg-tertiary)",
      }}
    >
      <span
        style={{
          fontSize: 11,
          fontWeight: 500,
          letterSpacing: "0.04em",
          textTransform: "uppercase",
          color: "var(--fg-secondary)",
        }}
      >
        Чувствительность к ключевой ставке
      </span>
      {phrases.map((p, i) => (
        <span key={i}>
          {p.charAt(0).toUpperCase() + p.slice(1)}
          {/\.$/.test(p) ? "" : "."}
        </span>
      ))}
    </div>
  );
}
