import type { ReactNode } from "react";
import type { Tgu2DMapSelection } from "./model/mapSelectionTypes";
import type { ComplexPlanMode } from "../../api/complexPlanApi";
import type { PriorityCell } from "../../api/cellsApi";
import type { RequestMapItem } from "../../model/requestTypes";
import { statusStyle } from "../tgu-planning/tguStatus";
import { formatLocalDateTime, parseLocal } from "../../utils/localTime";
import { formatVolume } from "../../utils/dataVolume";

/**
 * Единый инспектор объектов карты для всех вкладок (Карта, Комплексный план, Редактор):
 * показывает данные объекта, выбранного на карте — заявки, маршрута/включения, ячейки тепловой
 * карты, станции, маркера КА. При наложении объектов (≥2 под точкой клика) даёт список с
 * раскрытием карточки нужного. Данные-обогащение (modes/requestItems/priorityCells) — опциональны:
 * чего нет, то берётся из самого выбора (имя, статус).
 */
type MapObjectInspectorProps = {
  /** Объекты под точкой клика (1 — карточка сразу, ≥2 — список с раскрытием). */
  hits: Tgu2DMapSelection[];
  /** id раскрытого объекта в списке. */
  activeId?: string;
  onToggle: (selection: Tgu2DMapSelection) => void;
  onClose: () => void;
  /** Режимы прогона комплексного плана — для карточки включения (layer "complexPlan"). */
  modes?: ComplexPlanMode[];
  /** Заявки активного интервала — для карточки заявки (layer "requests"). */
  requestItems?: RequestMapItem[];
  /** Ячейки карты приоритетов — для карточки ячейки тепловой карты (layer "heatmap"). */
  priorityCells?: PriorityCell[];
  /** Если задан — в карточке заявки появляется кнопка «Выбрать» (вкладка «Слоты»). */
  onSelectRequest?: (requestId: string) => void;
};

export function MapObjectInspector({
  hits,
  activeId,
  onToggle,
  onClose,
  modes = [],
  requestItems = [],
  priorityCells = [],
  onSelectRequest,
}: MapObjectInspectorProps) {
  const renderCard = (selection: Tgu2DMapSelection): ReactNode => {
    if (selection.type === "marker") {
      return selection.layer === "stations"
        ? <StationCard selection={selection} />
        : <MarkerCard selection={selection} />;
    }
    if (selection.type === "line") return <LineCard selection={selection} />;
    switch (selection.layer) {
      case "complexPlan":
        return <ModeCard selection={selection} modes={modes} />;
      case "requests":
        return <RequestCard selection={selection} requestItems={requestItems} onSelectRequest={onSelectRequest} />;
      case "heatmap":
        return <CellCard selection={selection} priorityCells={priorityCells} />;
      case "planWorks":
        return <PlanWorkCard selection={selection} />;
      default:
        return <div className="tgu-editor-panel__hint">{selection.name || selection.id}</div>;
    }
  };

  if (hits.length <= 1) {
    const selection = hits[0];
    return (
      <div className="tgu-editor-panel">
        <PanelHead title={selection ? selectionTitle(selection) : "Объект"} onClose={onClose} />
        {selection ? renderCard(selection) : <div className="tgu-editor-panel__hint">Объект не выбран.</div>}
      </div>
    );
  }

  return (
    <div className="tgu-editor-panel">
      <PanelHead title={`Объекты под курсором · ${hits.length}`} onClose={onClose} />
      <div className="tgu-editor-panel__hint">Кликните объект в списке, чтобы раскрыть его данные.</div>
      <div className="tgu-editor-pick">
        {hits.map((hit, index) => {
          const open = hit.id === activeId;
          return (
            <div className={`tgu-editor-pick__item${open ? " is-open" : ""}`} key={`${hit.id}:${index}`}>
              <button type="button" className="tgu-editor-pick__row" onClick={() => onToggle(hit)}>
                <i className={`tgu-editor-pick__swatch tgu-editor-pick__swatch--${swatchKind(hit)}`} />
                <span className="tgu-editor-pick__title">{hit.name || selectionTitle(hit)}</span>
                <small className="tgu-editor-pick__sub">{selectionTitle(hit)}</small>
                <span className="tgu-editor-pick__chevron" aria-hidden="true">{open ? "▾" : "▸"}</span>
              </button>
              {open && <div className="tgu-editor-pick__detail">{renderCard(hit)}</div>}
            </div>
          );
        })}
      </div>
    </div>
  );
}

type PolygonSelection = Extract<Tgu2DMapSelection, { type: "polygon" }>;
type MarkerSelection = Extract<Tgu2DMapSelection, { type: "marker" }>;
type LineSelection = Extract<Tgu2DMapSelection, { type: "line" }>;

function ModeCard({ selection, modes }: { selection: PolygonSelection; modes: ComplexPlanMode[] }) {
  const mode = modes.find((m) => m.id === selection.modeId);
  if (!mode) return <div className="tgu-editor-panel__hint">{selection.name || selection.id}</div>;
  return (
    <section className="tgu-editor-panel__section">
      <div className="tgu-editor-eyebrow">{selection.name}</div>
      <dl className="tgu-map-request-details__grid">
        <dt>КА</dt>
        <dd className="mono">{mode.satelliteId}</dd>
        <dt>Тип</dt>
        <dd>{modeTypeLabel(mode.type)}</dd>
        <dt>Виток</dt>
        <dd className="mono">{mode.revolution}</dd>
        <dt>Начало</dt>
        <dd className="mono">{formatIso(mode.startTime)}</dd>
        <dt>Конец</dt>
        <dd className="mono">{formatIso(mode.endTime)}</dd>
        <dt>Длительность, с</dt>
        <dd className="mono">{mode.duration?.toFixed(1) ?? "—"}</dd>
        <dt>Крен, °</dt>
        <dd className="mono">{mode.roll != null ? mode.roll.toFixed(1) : "—"}</dd>
        <dt>Объём</dt>
        <dd className="mono">{mode.volumeMb != null ? formatVolume(mode.volumeMb) : "—"}</dd>
        <dt>№ ячейки</dt>
        <dd className="mono">{mode.cellNum || "—"}</dd>
        <dt>Источник</dt>
        <dd>{mode.source || "—"}</dd>
      </dl>
    </section>
  );
}

function RequestCard({
  selection,
  requestItems,
  onSelectRequest,
}: {
  selection: PolygonSelection;
  requestItems: RequestMapItem[];
  onSelectRequest?: (requestId: string) => void;
}) {
  const item = selection.requestId ? requestItems.find((r) => r.id === selection.requestId) : undefined;
  if (!item) return <div className="tgu-editor-panel__hint">{selection.name || selection.id}</div>;
  return (
    <section className="tgu-editor-panel__section">
      <dl className="tgu-map-request-details__grid">
        <dt>ID</dt>
        <dd className="mono">{item.id}</dd>
        <dt>Название</dt>
        <dd>{item.name || "—"}</dd>
        <dt>Статус</dt>
        <dd>{item.status}</dd>
        <dt>Тип съёмки</dt>
        <dd>{surveyTypeLabel(item.surveyType)}</dd>
        <dt>Начало</dt>
        <dd className="mono">{formatIso(item.beginDateTime)}</dd>
        <dt>Конец</dt>
        <dd className="mono">{formatIso(item.endDateTime)}</dd>
        <dt>Важность</dt>
        <dd className="mono">{item.importance}</dd>
        <dt>Покрытие</dt>
        <dd className="mono">{item.coveragePercent != null ? `${item.coveragePercent.toFixed(1)} %` : "—"}</dd>
        <dt>КПП</dt>
        <dd className="mono">{item.kpp?.join(", ") || "—"}</dd>
        <dt>Приоритет передачи</dt>
        <dd>{item.highPriorityTransmit ? "Да" : "Нет"}</dd>
      </dl>
      {onSelectRequest && (
        <div className="tgu-editor-panel__actions">
          <button
            className="tgu-button tgu-button--primary"
            type="button"
            onClick={() => onSelectRequest(item.id)}
          >
            Выбрать
          </button>
        </div>
      )}
    </section>
  );
}

function CellCard({ selection, priorityCells }: { selection: PolygonSelection; priorityCells: PriorityCell[] }) {
  const cell = selection.cellNum != null ? priorityCells.find((c) => c.cellNum === selection.cellNum) : undefined;
  const importance = cell?.importance ?? selection.importance;
  return (
    <section className="tgu-editor-panel__section">
      <div className="tgu-editor-eyebrow">{selection.name}</div>
      <dl className="tgu-map-request-details__grid">
        <dt>№ ячейки</dt>
        <dd className="mono">{cell?.cellNum ?? selection.cellNum ?? "—"}</dd>
        <dt>Важность</dt>
        <dd className="mono">{importance != null ? importance.toFixed(4) : "—"}</dd>
        {cell && (
          <>
            <dt>Центр</dt>
            <dd className="mono">{cell.latitude.toFixed(2)}°, {cell.longitude.toFixed(2)}°</dd>
            <dt>Заявок</dt>
            <dd className="mono">{cell.requests.length}</dd>
          </>
        )}
      </dl>
      {cell && cell.requests.length > 0 && (
        <div className="tgu-editor-panel__section">
          <div className="tgu-editor-eyebrow">Заявки в ячейке</div>
          <dl className="tgu-map-request-details__grid">
            {cell.requests.map((req) => (
              <ReqFragmentRow key={req.requestId} requestId={req.requestId} coveragePercent={req.coveragePercent} importance={req.importance} />
            ))}
          </dl>
        </div>
      )}
    </section>
  );
}

function PlanWorkCard({ selection }: { selection: PolygonSelection }) {
  const style = selection.status ? statusStyle(selection.status) : undefined;
  return (
    <section className="tgu-editor-panel__section">
      <div className="tgu-editor-eyebrow">{selection.name}</div>
      <dl className="tgu-map-request-details__grid">
        {selection.spacecraftId && (<><dt>КА</dt><dd className="mono">{selection.spacecraftId}</dd></>)}
        {selection.planId && (<><dt>План</dt><dd className="mono">{selection.planId}</dd></>)}
        {selection.surveyType && (<><dt>Тип съёмки</dt><dd>{surveyTypeLabel(selection.surveyType)}</dd></>)}
      </dl>
      {style && (
        <span className="tgu-map-status-pill">
          <i style={{ backgroundColor: style.color }} />
          {style.label}
        </span>
      )}
    </section>
  );
}

function StationCard({ selection }: { selection: MarkerSelection }) {
  return (
    <section className="tgu-editor-panel__section">
      <div className="tgu-editor-eyebrow">{selection.name}</div>
      <dl className="tgu-map-request-details__grid">
        <dt>Номер</dt>
        <dd className="mono">{selection.stationNumber ?? "—"}</dd>
        <dt>Широта</dt>
        <dd className="mono">{selection.lat != null ? `${selection.lat.toFixed(4)}°` : "—"}</dd>
        <dt>Долгота</dt>
        <dd className="mono">{selection.lon != null ? `${selection.lon.toFixed(4)}°` : "—"}</dd>
        <dt>Высота, м</dt>
        <dd className="mono">{selection.altitude != null ? selection.altitude.toFixed(1) : "—"}</dd>
        <dt>Угол места мин, °</dt>
        <dd className="mono">{selection.elevationMin != null ? selection.elevationMin.toFixed(1) : "—"}</dd>
        <dt>Угол места макс, °</dt>
        <dd className="mono">{selection.elevationMax != null ? selection.elevationMax.toFixed(1) : "—"}</dd>
      </dl>
    </section>
  );
}

function MarkerCard({ selection }: { selection: MarkerSelection }) {
  return (
    <section className="tgu-editor-panel__section">
      <div className="tgu-editor-eyebrow">{selection.name}</div>
      <dl className="tgu-map-request-details__grid">
        {selection.spacecraftId && (<><dt>КА</dt><dd className="mono">{selection.spacecraftId}</dd></>)}
        <dt>Широта</dt>
        <dd className="mono">{selection.lat != null ? `${selection.lat.toFixed(4)}°` : "—"}</dd>
        <dt>Долгота</dt>
        <dd className="mono">{selection.lon != null ? `${selection.lon.toFixed(4)}°` : "—"}</dd>
      </dl>
    </section>
  );
}

function LineCard({ selection }: { selection: LineSelection }) {
  return (
    <section className="tgu-editor-panel__section">
      <div className="tgu-editor-eyebrow">{selection.name}</div>
      <dl className="tgu-map-request-details__grid">
        <dt>Тип</dt>
        <dd>{selection.kind === "drop" ? "Сброс на НКПОР" : "Трасса КА"}</dd>
      </dl>
    </section>
  );
}

function ReqFragmentRow({ requestId, coveragePercent, importance }: { requestId: string; coveragePercent: number; importance: number }) {
  return (
    <>
      <dt className="mono" title={requestId}>{requestId.slice(0, 8)}…</dt>
      <dd className="mono">покрытие {coveragePercent.toFixed(1)} % · важность {importance.toFixed(3)}</dd>
    </>
  );
}

function PanelHead({ title, onClose }: { title: string; onClose: () => void }) {
  return (
    <div className="tgu-editor-panel__head">
      <h2>{title}</h2>
      <button className="tgu-icon-button" type="button" onClick={onClose} title="Закрыть">×</button>
    </div>
  );
}

/** Заголовок/подпись типа объекта по слою выбора. */
function selectionTitle(selection: Tgu2DMapSelection): string {
  if (selection.type === "marker") return selection.layer === "stations" ? "Станция" : "Маркер КА";
  if (selection.type === "line") return selection.kind === "drop" ? "Сброс на НКПОР" : "Трасса КА";
  switch (selection.layer) {
    case "complexPlan": return "Включение комплексного плана";
    case "heatmap": return "Ячейка приоритета";
    case "requests": return "Заявка на съёмку";
    case "planWorks": return "Маршрут съёмки";
    case "swath": return "Полоса обзора";
    default: return "Объект карты";
  }
}

/** Класс цветовой метки в списке выбора (стили в tgu-editor.css). */
function swatchKind(selection: Tgu2DMapSelection): string {
  if (selection.type === "marker") return selection.layer === "stations" ? "station" : "spacecraftMarkers";
  if (selection.type === "line") return selection.kind === "drop" ? "drop" : "tracks";
  return selection.layer;
}

function modeTypeLabel(type: string): string {
  switch (type) {
    case "SURVEY": return "Съёмка";
    case "DROP": return "Сброс";
    default: return type;
  }
}

function surveyTypeLabel(surveyType: string): string {
  switch (surveyType) {
    case "OPTICS": return "Оптическая";
    case "RSA": return "Радиолокационная (РСА)";
    case "COMBINED": return "Комбинированная";
    default: return surveyType;
  }
}

function formatIso(iso: string): string {
  return formatLocalDateTime(parseLocal(iso));
}
