"use client";

/**
 * ResourceReservesCard — «Ресурсные резервы» для §3 «Сети» (#connection-capacity).
 *
 * Показывает свободную мощность для технологического присоединения (ТП) из
 * ОБЯЗАТЕЛЬНОГО раскрытия сетевых организаций:
 *   • Электричество — ближайший центр питания (ЦП, ПС 35/110 кВ) Россетей со
 *     свободной мощностью + бейдж статуса по индексу загрузки (open/limited/closed).
 *   • Вода/канализация — резервы ЦСВ/ЦСК Водоканала: городская система отдельной
 *     строкой (ОТРИЦАТЕЛЬНЫЙ резерв = дефицит, красный бейдж), посёлковые —
 *     свёрнуты в details.
 *
 * Числа приводятся через toFiniteNumber (Pydantic Decimal→str). Пока лоадеры
 * бэка не отработали, показываем нейтральный «загружаются», а не «нет данных».
 */

import { Info, Zap, Droplets, Flame, Thermometer, Route } from "lucide-react";

import type {
  ConnectionCapacityResponse,
  GasCapacityBlock,
  GasGrsRow,
  HeatCapacityBlock,
  HeatSystemRow,
  NearbyNetworkZone,
  WaterCapacityRow,
} from "@/hooks/useConnectionCapacity";
import { CONNECTION_CAPACITY_RADIUS_M } from "@/hooks/useConnectionCapacity";
import {
  LOAD_INDEX_BADGE,
  classifyLoadIndex,
  formatGcalHour,
  formatMeters,
  formatMva,
  formatThousandM3Day,
  formatThousandM3Hour,
  formatZoneDistance,
  humanizeLoadIndex,
  humanizeNetKind,
  isThermalNear,
  pickCitySystem,
  pluralizeSystems,
  sortNearbyNetworkZones,
  toFiniteNumber,
} from "@/components/site-finder/connection-capacity";

const RADIUS_KM = CONNECTION_CAPACITY_RADIUS_M / 1000;

// Semantic-бейдж (резерв/дефицит) — token-палитра карточек (не карта).
const RESERVE_BADGE = {
  reserve: {
    label: "резерв",
    bg: "var(--success-soft)",
    fg: "var(--success)",
  },
  deficit: {
    label: "дефицит",
    bg: "var(--danger-soft)",
    fg: "var(--danger)",
  },
  depleted: {
    label: "исчерпана",
    bg: "var(--danger-soft)",
    fg: "var(--danger)",
  },
} as const;

function StatusBadge({
  label,
  bg,
  fg,
  border,
}: {
  label: string;
  bg: string;
  fg: string;
  border?: string;
}) {
  return (
    <span
      style={{
        display: "inline-block",
        padding: "1px 8px",
        borderRadius: 6,
        fontSize: 12,
        fontWeight: 500,
        color: fg,
        background: bg,
        border: border ? `1px solid ${border}` : undefined,
        whiteSpace: "nowrap",
      }}
    >
      {label}
    </span>
  );
}

// ── Электричество ──────────────────────────────────────────────────────────────

function PowerRow({ data }: { data: ConnectionCapacityResponse }) {
  const nearest = data.power_summary.nearest_with_reserve;

  if (!nearest) {
    return (
      <div style={{ fontSize: 13, color: "var(--fg-secondary)" }}>
        Данные о резервах ПС загружаются.
      </div>
    );
  }

  const idx = classifyLoadIndex(nearest.load_index);
  const badge = idx ? LOAD_INDEX_BADGE[idx] : null;
  const humanIdx = humanizeLoadIndex(nearest.load_index);

  const voltage = nearest.voltage_class?.trim() || null;
  const reserve = formatMva(nearest.reserve_mva, nearest.reserve_unit);
  const distance = formatMeters(nearest.distance_m);
  const district = nearest.district?.trim() || null;

  const parts: string[] = [];
  if (voltage) parts.push(`${voltage} кВ`);
  if (reserve) parts.push(`резерв ${reserve}`);
  if (humanIdx) parts.push(humanIdx);
  if (district) parts.push(`район ${district}`);
  if (distance) parts.push(distance);

  return (
    <div
      style={{
        display: "flex",
        alignItems: "flex-start",
        gap: 8,
        flexWrap: "wrap",
      }}
    >
      <span style={{ fontSize: 13, color: "var(--fg-primary)" }}>
        Ближайший центр питания: <strong>{nearest.name}</strong>
        {parts.length > 0 ? ` · ${parts.join(" · ")}` : ""}
      </span>
      {badge && (
        <StatusBadge
          label={badge.label}
          bg={badge.bg}
          fg={badge.fg}
          border={badge.border}
        />
      )}
    </div>
  );
}

// ── Вода / канализация ─────────────────────────────────────────────────────────

function WaterSystemLine({
  label,
  row,
}: {
  label: string;
  row: WaterCapacityRow;
}) {
  const reserveNum = toFiniteNumber(row.reserve_thousand_m3_day);
  const reserveStr = formatThousandM3Day(row.reserve_thousand_m3_day);
  const isDeficit = reserveNum !== null && reserveNum < 0;
  const badge = isDeficit ? RESERVE_BADGE.deficit : RESERVE_BADGE.reserve;

  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 4,
      }}
    >
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 8,
          flexWrap: "wrap",
        }}
      >
        <span style={{ fontSize: 13, color: "var(--fg-primary)" }}>
          {label}:{" "}
          {reserveStr ? (
            <strong
              style={{
                color: isDeficit ? "var(--danger)" : "var(--fg-primary)",
              }}
            >
              {reserveStr}
            </strong>
          ) : (
            <span style={{ color: "var(--fg-tertiary)" }}>—</span>
          )}
        </span>
        {reserveNum !== null && (
          <StatusBadge label={badge.label} bg={badge.bg} fg={badge.fg} />
        )}
      </div>
      {row.note && (
        <span style={{ fontSize: 12, color: "var(--fg-secondary)" }}>
          {row.note}
        </span>
      )}
    </div>
  );
}

function WaterBlock({ rows }: { rows: WaterCapacityRow[] }) {
  if (rows.length === 0) {
    return (
      <div style={{ fontSize: 13, color: "var(--fg-secondary)" }}>
        Данные о резервах водоснабжения загружаются.
      </div>
    );
  }

  // Разделяем водоснабжение (ЦСВ, system_kind="water") и водоотведение
  // (ЦСК, system_kind="sewerage") — значения из бэка (vodokanal_reserve_loader).
  const supply = rows.filter((r) => r.system_kind === "water");
  const sewage = rows.filter((r) => r.system_kind === "sewerage");
  const other = rows.filter(
    (r) => r.system_kind !== "water" && r.system_kind !== "sewerage",
  );

  const citySupply = pickCitySystem(supply);
  const citySewage = pickCitySystem(sewage);

  // Остальные (посёлковые) системы — свернуть в details. Городские строки уже
  // показаны отдельно, поэтому исключаем их из «прочих».
  const rest = [
    ...(citySupply ? supply.filter((r) => r !== citySupply) : supply),
    ...(citySewage ? sewage.filter((r) => r !== citySewage) : sewage),
    ...other,
  ];

  // Источник-подпись: период из данных (первый ненулевой).
  const period = rows.find((r) => r.period)?.period?.trim() || null;

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      {citySupply && (
        <WaterSystemLine label="Водоснабжение (город)" row={citySupply} />
      )}
      {citySewage && (
        <WaterSystemLine label="Водоотведение (город)" row={citySewage} />
      )}

      {rest.length > 0 && (
        <details>
          <summary
            style={{
              fontSize: 12,
              color: "var(--accent)",
              cursor: "pointer",
            }}
          >
            + {pluralizeSystems(rest.length)}
          </summary>
          <div
            style={{
              display: "flex",
              flexDirection: "column",
              gap: 6,
              marginTop: 6,
            }}
          >
            {rest.map((r, i) => (
              <WaterSystemLine
                key={`${r.system_kind}-${r.system_name}-${i}`}
                label={r.system_name || "Система"}
                row={r}
              />
            ))}
          </div>
        </details>
      )}

      <span style={{ fontSize: 12, color: "var(--fg-tertiary)" }}>
        Раскрытие МУП «Водоканал»{period ? ` · ${period}` : ""}
      </span>
    </div>
  );
}

// ── Газ ────────────────────────────────────────────────────────────────────────

function GasGrsLine({ row }: { row: GasGrsRow }) {
  const freeNum = toFiniteNumber(row.free_capacity_th_m3_h);
  const freeStr = formatThousandM3Hour(row.free_capacity_th_m3_h);
  const designStr = formatThousandM3Hour(row.design_capacity_th_m3_h);
  const isDepleted = freeNum !== null && freeNum <= 0;
  const badge = isDepleted ? RESERVE_BADGE.depleted : RESERVE_BADGE.reserve;
  const upgrade = row.upgrade_due?.trim() || null;

  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: 8,
        flexWrap: "wrap",
      }}
    >
      <span style={{ fontSize: 13, color: "var(--fg-primary)" }}>
        <strong>{row.grs_name}</strong>: свободно{" "}
        {freeStr ? (
          <strong
            style={{
              color: isDepleted ? "var(--danger)" : "var(--fg-primary)",
            }}
          >
            {freeStr}
          </strong>
        ) : (
          <span style={{ color: "var(--fg-tertiary)" }}>—</span>
        )}
        {designStr ? ` из ${designStr}` : ""}
        {row.outputs_count > 1 && (
          <span style={{ color: "var(--fg-tertiary)" }}>
            {" "}
            ({row.outputs_count} выхода)
          </span>
        )}
        {upgrade && (
          <span style={{ color: "var(--fg-tertiary)" }}>
            {" "}
            · расшивка: {upgrade}
          </span>
        )}
      </span>
      <StatusBadge label={badge.label} bg={badge.bg} fg={badge.fg} />
    </div>
  );
}

// Строка-сводка точек выхода газосети по городу (форма 6 Екатеринбурггаза,
// последний срез). Отдельная единица (млн м³/мес) от ГРС (тыс. м³/ч) — поэтому
// caveat про источник/единицу; счётчики city-level, не в радиусе участка.
function GasOutletsSummaryLine({ gas }: { gas: GasCapacityBlock }) {
  const total = gas.outlets_total ?? 0;
  if (total === 0) return null;

  const deficit = gas.outlets_deficit ?? 0;
  const needsCalc = gas.outlets_needs_calc ?? 0;

  return (
    <span
      title="Форма 6 АО «Екатеринбурггаз» (ФАС №960), млн м³/мес за последний месяц"
      style={{ fontSize: 12, color: "var(--fg-secondary)", cursor: "help" }}
    >
      Точки выхода газосети (город): {total.toLocaleString("ru-RU")} · дефицит{" "}
      {deficit.toLocaleString("ru-RU")} · требуют гидрорасчёта{" "}
      {needsCalc.toLocaleString("ru-RU")}
    </span>
  );
}

function GasBlock({ gas }: { gas: GasCapacityBlock | null | undefined }) {
  // Нет ни ГРС-строк, ни счётчиков точек выхода → данные ещё грузятся.
  if (!gas || (gas.city_grs.length === 0 && (gas.outlets_total ?? 0) === 0)) {
    return (
      <div style={{ fontSize: 13, color: "var(--fg-secondary)" }}>
        Данные о загрузке ГРС загружаются.
      </div>
    );
  }

  const totalNum = toFiniteNumber(gas.total_free_th_m3_h);
  const totalStr = formatThousandM3Hour(gas.total_free_th_m3_h);

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      {gas.city_grs.map((row, i) => (
        <GasGrsLine key={`grs-${row.grs_name}-${i}`} row={row} />
      ))}

      {totalNum !== null && totalStr && (
        <span style={{ fontSize: 13, color: "var(--fg-primary)" }}>
          Суммарно по городским ГРС: <strong>{totalStr}</strong>
        </span>
      )}

      <GasOutletsSummaryLine gas={gas} />

      <span style={{ fontSize: 12, color: "var(--fg-tertiary)" }}>
        Газпром трансгаз Екатеринбург · техвозможность ГРС
      </span>
    </div>
  );
}

// ── Тепло ────────────────────────────────────────────────────────────────────

function HeatSystemLine({ row }: { row: HeatSystemRow }) {
  const reserveNum = toFiniteNumber(row.reserve_gcal_h);
  const reserveStr = formatGcalHour(row.reserve_gcal_h);
  const isDepleted = reserveNum !== null && reserveNum <= 0;
  const badge = isDepleted ? RESERVE_BADGE.depleted : RESERVE_BADGE.reserve;

  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: 8,
        flexWrap: "wrap",
      }}
    >
      <span style={{ fontSize: 13, color: "var(--fg-primary)" }}>
        <strong>{row.org}</strong> · {row.system_name}: резерв{" "}
        {reserveStr ? (
          <strong
            style={{
              color: isDepleted ? "var(--danger)" : "var(--fg-primary)",
            }}
          >
            {reserveStr}
          </strong>
        ) : (
          <span style={{ color: "var(--fg-tertiary)" }}>—</span>
        )}
      </span>
      {reserveNum !== null && (
        <StatusBadge label={badge.label} bg={badge.bg} fg={badge.fg} />
      )}
    </div>
  );
}

function HeatBlock({ heat }: { heat: HeatCapacityBlock | null | undefined }) {
  if (!heat || heat.systems.length === 0) {
    return (
      <div style={{ fontSize: 13, color: "var(--fg-secondary)" }}>
        Данные о резервах теплоснабжения загружаются.
      </div>
    );
  }

  const head = heat.systems.slice(0, 5);
  const rest = heat.systems.slice(5);

  const totalNum = toFiniteNumber(heat.total_reserve_gcal_h);
  const totalStr = formatGcalHour(heat.total_reserve_gcal_h);

  // Источник-подпись: период первой системы (первый ненулевой).
  const period = heat.systems.find((s) => s.period)?.period?.trim() || null;

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      {head.map((row, i) => (
        <HeatSystemLine
          key={`heat-${row.org}-${row.system_name}-${i}`}
          row={row}
        />
      ))}

      {rest.length > 0 && (
        <details>
          <summary
            style={{
              fontSize: 12,
              color: "var(--accent)",
              cursor: "pointer",
            }}
          >
            + {pluralizeSystems(rest.length)}
          </summary>
          <div
            style={{
              display: "flex",
              flexDirection: "column",
              gap: 6,
              marginTop: 6,
            }}
          >
            {rest.map((row, i) => (
              <HeatSystemLine
                key={`heat-rest-${row.org}-${row.system_name}-${i}`}
                row={row}
              />
            ))}
          </div>
        </details>
      )}

      {totalNum !== null && totalStr && (
        <span style={{ fontSize: 13, color: "var(--fg-primary)" }}>
          Суммарно: <strong>{totalStr}</strong>
        </span>
      )}

      <span style={{ fontSize: 12, color: "var(--fg-tertiary)" }}>
        Раскрытие ФАС (ЕТК, Екатеринбургэнерго)
        {period ? ` · ${period}` : ""}
      </span>
    </div>
  );
}

// ── Сети рядом с участком (охранные зоны, #2119 C2) ────────────────────────────
//
// Где ФИЗИЧЕСКИ проходит сеть (охранный коридор в радиусе 300 м) — позитив-разрез:
// теплотрасса в 24 м → дешёвая врезка. Порядок уже по (distance_m, net_kind) с
// бэка; thermal ≤50 м выводим первым и подсвечиваем success-тоном.

// Маленький нейтральный чип net_kind (тепло/электро/газ/связь/не уточнено).
function NetKindChip({ netKind }: { netKind: string }) {
  return (
    <span
      style={{
        display: "inline-block",
        padding: "0 6px",
        borderRadius: 6,
        fontSize: 11,
        fontWeight: 500,
        lineHeight: "18px",
        color: "var(--fg-secondary)",
        background: "var(--bg-card-alt)",
        border: "1px solid var(--border-card)",
        whiteSpace: "nowrap",
      }}
    >
      {humanizeNetKind(netKind)}
    </span>
  );
}

function NearbyNetworkZoneLine({ zone }: { zone: NearbyNetworkZone }) {
  const near = isThermalNear(zone);
  const distance = formatZoneDistance(zone.distance_m);

  return (
    <div
      style={{
        display: "flex",
        alignItems: "flex-start",
        gap: 8,
        flexWrap: "wrap",
      }}
    >
      <NetKindChip netKind={zone.net_kind} />
      <span
        style={{
          fontSize: 13,
          color: near ? "var(--success)" : "var(--fg-primary)",
          fontWeight: near ? 600 : 400,
        }}
      >
        {zone.human_label}
      </span>
      <StatusBadge
        label={distance}
        bg={near ? "var(--success-soft)" : "var(--bg-card-alt)"}
        fg={near ? "var(--success)" : "var(--fg-secondary)"}
        border={near ? undefined : "var(--border-card)"}
      />
    </div>
  );
}

function NearbyNetworkZonesBlock({ zones }: { zones: NearbyNetworkZone[] }) {
  // Пустой массив → блок не рендерится вовсе (не «нет данных»).
  if (zones.length === 0) return null;

  const ordered = sortNearbyNetworkZones(zones);

  return (
    <div>
      <div style={SUB_HEADER}>
        <Route size={14} strokeWidth={1.5} aria-hidden="true" />
        Сети рядом с участком
      </div>
      <div
        style={{
          fontSize: 12,
          color: "var(--fg-secondary)",
          marginBottom: 8,
        }}
      >
        По охранным зонам — где физически проходит сеть.
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {ordered.map((zone, i) => (
          <NearbyNetworkZoneLine
            key={`zone-${zone.net_kind}-${zone.distance_m}-${i}`}
            zone={zone}
          />
        ))}
      </div>
    </div>
  );
}

// ── Card ───────────────────────────────────────────────────────────────────────

const SUB_HEADER: React.CSSProperties = {
  display: "flex",
  alignItems: "center",
  gap: 6,
  fontSize: 12,
  fontWeight: 600,
  textTransform: "uppercase",
  letterSpacing: "0.04em",
  color: "var(--fg-tertiary)",
  marginBottom: 6,
};

interface Props {
  data: ConnectionCapacityResponse;
}

export function ResourceReservesCard({ data }: Props) {
  return (
    <div
      style={{
        border: "1px solid var(--border-card)",
        borderRadius: 12,
        background: "var(--bg-card)",
        padding: 20,
        marginBottom: 16,
        display: "flex",
        flexDirection: "column",
        gap: 16,
      }}
    >
      <h3
        style={{
          margin: 0,
          fontSize: 14,
          fontWeight: 600,
          color: "var(--fg-primary)",
        }}
      >
        Ресурсные резервы для подключения (ТП)
      </h3>

      {/* Электричество */}
      <div>
        <div style={SUB_HEADER}>
          <Zap size={14} strokeWidth={1.5} aria-hidden="true" />
          Электричество
        </div>
        <PowerRow data={data} />
      </div>

      {/* Газ */}
      <div>
        <div style={SUB_HEADER}>
          <Flame size={14} strokeWidth={1.5} aria-hidden="true" />
          Газ
        </div>
        <GasBlock gas={data.gas} />
      </div>

      {/* Тепло */}
      <div>
        <div style={SUB_HEADER}>
          <Thermometer size={14} strokeWidth={1.5} aria-hidden="true" />
          Тепло
        </div>
        <HeatBlock heat={data.heat} />
      </div>

      {/* Вода / канализация */}
      <div>
        <div style={SUB_HEADER}>
          <Droplets size={14} strokeWidth={1.5} aria-hidden="true" />
          Вода и водоотведение
        </div>
        <WaterBlock rows={data.water} />
      </div>

      {/* Сети рядом (охранные зоны) — рендерится только при наличии зон */}
      <NearbyNetworkZonesBlock zones={data.nearby_network_zones} />

      {/* Caveat */}
      <div
        style={{
          display: "flex",
          alignItems: "flex-start",
          gap: 6,
          fontSize: 12,
          color: "var(--fg-tertiary)",
          borderTop: "1px solid var(--border-soft)",
          paddingTop: 12,
        }}
      >
        <Info
          size={13}
          strokeWidth={1.5}
          aria-hidden="true"
          style={{ flexShrink: 0, marginTop: 1 }}
        />
        <span>
          Резервы — из обязательного раскрытия сетевых организаций в радиусе{" "}
          {RADIUS_KM} км; для ТП требуется запрос технических условий (ТУ).
        </span>
      </div>
    </div>
  );
}
