"use client";

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

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

import type {
  ConnectionCapacityResponse,
  GasCapacityBlock,
  GasGrsRow,
  WaterCapacityRow,
} from "@/hooks/useConnectionCapacity";
import { CONNECTION_CAPACITY_RADIUS_M } from "@/hooks/useConnectionCapacity";
import {
  LOAD_INDEX_BADGE,
  classifyLoadIndex,
  formatMeters,
  formatMva,
  formatThousandM3Day,
  formatThousandM3Hour,
  humanizeLoadIndex,
  pickCitySystem,
  pluralizeSystems,
  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);
  const distance = formatMeters(nearest.distance_m);

  const parts: string[] = [];
  if (voltage) parts.push(`${voltage} кВ`);
  if (reserve) parts.push(`резерв ${reserve}`);
  if (humanIdx) parts.push(humanIdx);
  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>
  );
}

function GasBlock({ gas }: { gas: GasCapacityBlock | null | undefined }) {
  if (!gas || gas.city_grs.length === 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>
      )}

      <span style={{ fontSize: 12, color: "var(--fg-tertiary)" }}>
        Газпром трансгаз Екатеринбург · техвозможность ГРС
      </span>
    </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}>
          <Droplets size={14} strokeWidth={1.5} aria-hidden="true" />
          Вода и водоотведение
        </div>
        <WaterBlock rows={data.water} />
      </div>

      {/* 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>
  );
}
