"use client";

/**
 * PowerConnectionPointsLayer — центры питания (ЦП, ПС 35/110 кВ) Россетей со
 * свободной мощностью для ТП (#connection-capacity). Отдельный слой поверх карты
 * §3 «Сети»: CircleMarker per power_point, цвет по индексу загрузки (load_index),
 * чтобы визуально отличаться от оранжевых точек НСПД / инж.сетей OSM.
 *
 * Источник — обязательное раскрытие сетевых организаций (Россети), а НЕ OSM:
 * это разные слои. Координаты ЦП округлены источником (~±100 м) — предупреждаем
 * об этом в попапе.
 *
 * Цвета/подписи/приведение чисел — из общего модуля connection-capacity.ts
 * (идентичны карточке «Ресурсные резервы»). Inline token-hex в popup —
 * документированное исключение raw-Leaflet попапов (ui-tokens.md).
 */

import { CircleMarker, LayerGroup, Popup } from "react-leaflet";

import type { PowerConnectionPoint } from "@/hooks/useConnectionCapacity";
import {
  LOAD_INDEX_BADGE,
  classifyLoadIndex,
  formatMeters,
  formatMva,
  loadIndexColor,
  powerPointReserveIsNegative,
  toFiniteNumber,
} from "@/components/site-finder/connection-capacity";

// ── Point coordinate guard ─────────────────────────────────────────────────────
// lat/lon могут прийти строкой (Decimal→str) — приводим через toFiniteNumber, а
// не typeof-гвардом (иначе валидная точка молча не рисуется).
function pointLatLon(p: PowerConnectionPoint): [number, number] | null {
  const lat = toFiniteNumber(p.lat);
  const lon = toFiniteNumber(p.lon);
  if (lat === null || lon === null) return null;
  return [lat, lon];
}

// ── Popup ──────────────────────────────────────────────────────────────────────

function PowerPopup({ point }: { point: PowerConnectionPoint }) {
  const idx = classifyLoadIndex(point.load_index);
  const badge = idx ? LOAD_INDEX_BADGE[idx] : null;
  const color = loadIndexColor(point.load_index);

  const voltage = point.voltage_class?.trim() || null;
  // reserve_unit — единица ТОЛЬКО для строки резерва: у ЕЭСК установленная
  // мощность в файле раскрытия дана в МВА, а свободная — в МВт (разные строки
  // источника), поэтому unit НЕ распространяем на установленную/загрузку.
  const installed = formatMva(point.installed_capacity_mva);
  const load = formatMva(point.current_load_mva);
  const reserve = formatMva(point.reserve_mva, point.reserve_unit);
  const reserveNegative = powerPointReserveIsNegative(point);
  const distance = formatMeters(point.distance_m);
  const district = point.district?.trim() || null;

  return (
    <Popup>
      <div style={{ fontSize: 12, lineHeight: 1.55, minWidth: 200 }}>
        <div
          style={{
            fontWeight: 700,
            marginBottom: 4,
            display: "flex",
            alignItems: "center",
            gap: 5,
          }}
        >
          <span
            aria-hidden
            style={{
              display: "inline-block",
              width: 10,
              height: 10,
              borderRadius: "50%",
              background: color,
              flexShrink: 0,
            }}
          />
          Центр питания (Россети)
        </div>
        <div style={{ marginBottom: 4 }}>
          <strong>{point.name}</strong>
        </div>
        {district && (
          <div style={{ color: "#374151", marginBottom: 2 }}>
            Район: {district}
          </div>
        )}
        {voltage && (
          <div style={{ color: "#374151", marginBottom: 2 }}>
            Напряжение: {voltage} кВ
          </div>
        )}
        {installed && (
          <div style={{ color: "#374151", marginBottom: 2 }}>
            Установленная мощность: {installed}
          </div>
        )}
        {load && (
          <div style={{ color: "#374151", marginBottom: 2 }}>
            Загрузка: {load}
          </div>
        )}
        {reserve && (
          <div
            style={{
              color: reserveNegative ? "#b91c1c" : "#374151",
              marginBottom: 4,
            }}
          >
            Резерв для ТП:{" "}
            <strong style={{ color: reserveNegative ? "#b91c1c" : "#111827" }}>
              {reserve}
            </strong>
          </div>
        )}
        {badge && (
          <span
            style={{
              display: "inline-block",
              padding: "1px 8px",
              borderRadius: 6,
              fontSize: 11,
              fontWeight: 600,
              color: badge.fg,
              background: badge.bg,
              border: `1px solid ${badge.border}`,
            }}
          >
            {badge.label}
          </span>
        )}
        {point.reserve_note && (
          <div style={{ marginTop: 4, fontSize: 11, color: "#6b7280" }}>
            {point.reserve_note}
          </div>
        )}
        {distance && (
          <div style={{ marginTop: 4, color: "#374151" }}>
            До участка: {distance}
          </div>
        )}
        <div
          style={{
            marginTop: 4,
            fontSize: 11,
            color: "#9ca3af",
            borderTop: "1px solid #f3f4f6",
            paddingTop: 4,
          }}
        >
          Россети{point.reserve_asof ? ` · срез ${point.reserve_asof}` : ""}
        </div>
        <div style={{ fontSize: 11, color: "#9ca3af" }}>
          Координаты ЦП ~±100 м (округление источника)
        </div>
      </div>
    </Popup>
  );
}

// ── Layer ──────────────────────────────────────────────────────────────────────

interface Props {
  points: PowerConnectionPoint[];
}

export function PowerConnectionPointsLayer({ points }: Props) {
  return (
    <LayerGroup>
      {points.map((point, idx) => {
        const latLon = pointLatLon(point);
        if (!latLon) return null;
        const color = loadIndexColor(point.load_index);
        return (
          <CircleMarker
            key={`power-cp-${point.name}-${idx}`}
            center={latLon}
            radius={9}
            pathOptions={{
              color: "#ffffff",
              weight: 2,
              fillColor: color,
              fillOpacity: 0.85,
            }}
          >
            <PowerPopup point={point} />
          </CircleMarker>
        );
      })}
    </LayerGroup>
  );
}

// Число рисуемых точек (с валидными координатами) — для легенды/счётчика.
export function countMappablePowerPoints(
  points: PowerConnectionPoint[] | undefined,
): number {
  if (!points) return 0;
  return points.filter((p) => pointLatLon(p) !== null).length;
}
