import { useMemo, type MouseEvent } from "react";
import { VESSEL_TYPES } from "../../entities/vessel/model/meta";
import type { DerivedLegacyVessel } from "../../features/legacyDashboard/model/types";
import { haversineNm } from "../../shared/lib/geo/haversineNm";
import { OVERLAY_RGB, rgbToHex, rgba } from "../../shared/lib/map/palette";

type FleetSortMode = "count" | "range";

type Props = {
  selectedVessel: DerivedLegacyVessel | null;
  vessels: DerivedLegacyVessel[];
  fleetVessels: DerivedLegacyVessel[];
  onSelectMmsi: (mmsi: number) => void;
  onToggleHighlightMmsi: (mmsi: number) => void;
  onHoverMmsi: (mmsis: number[]) => void;
  onClearHover: () => void;
  onHoverPair: (mmsis: number[]) => void;
  onClearPairHover: () => void;
  onHoverFleet: (ownerKey: string | null, mmsis: number[]) => void;
  onClearFleetHover: () => void;
  hoveredFleetOwnerKey?: string | null;
  hoveredFleetMmsiSet?: number[];
  onContextMenuFleet?: (ownerKey: string, mmsis: number[]) => void;
  fleetSortMode?: FleetSortMode;
};

export function RelationsPanel({
  selectedVessel,
  vessels,
  fleetVessels,
  onSelectMmsi,
  onToggleHighlightMmsi,
  onHoverMmsi,
  onClearHover,
  onHoverPair,
  onClearPairHover,
  onHoverFleet,
  onClearFleetHover,
  hoveredFleetOwnerKey,
  hoveredFleetMmsiSet,
  onContextMenuFleet,
  fleetSortMode = "count",
}: Props) {
  const handlePrimaryAction = (e: MouseEvent, mmsi: number) => {
    if (e.shiftKey || e.ctrlKey || e.metaKey) {
      onToggleHighlightMmsi(mmsi);
      return;
    }
    onSelectMmsi(mmsi);
  };

  const clearAllHovers = () => {
    onClearHover();
    onClearPairHover();
    onClearFleetHover();
  };

  const hoveredFleetMmsis = useMemo(() => new Set(hoveredFleetMmsiSet ?? []), [hoveredFleetMmsiSet]);

  const isFleetHighlightByOwner = (ownerKey: string | null) =>
    hoveredFleetOwnerKey != null && ownerKey != null && hoveredFleetOwnerKey === ownerKey;

  const isVesselHighlight = (mmsi: number, ownerKey: string | null) =>
    hoveredFleetMmsis.has(mmsi) || isFleetHighlightByOwner(ownerKey);

  const topFleets = useMemo(() => {
    const group = new Map<string, DerivedLegacyVessel[]>();
    for (const v of fleetVessels) {
      if (!v.ownerKey) continue;
      const list = group.get(v.ownerKey);
      if (list) list.push(v);
      else group.set(v.ownerKey, [v]);
    }

    return Array.from(group.entries())
      .map(([ownerKey, vs]) => {
        const lon = vs.reduce((sum, v) => sum + v.lon, 0) / vs.length;
        const lat = vs.reduce((sum, v) => sum + v.lat, 0) / vs.length;
        const radiusNm = vs.reduce((max, v) => {
          const d = haversineNm(lat, lon, v.lat, v.lon);
          return Math.max(max, d);
        }, 0);

        return { ownerKey, vs, radiusNm };
      })
      .filter((x) => x.vs.length >= 3)
      .sort((a, b) => {
        if (fleetSortMode === "range") {
          return b.radiusNm - a.radiusNm || b.vs.length - a.vs.length;
        }
        return b.vs.length - a.vs.length || b.radiusNm - a.radiusNm;
      });
  }, [fleetVessels, fleetSortMode]);

  if (selectedVessel) {
    const v = selectedVessel;
    const meta = VESSEL_TYPES[v.shipCode];
    const ownerLabel = v.ownerCn || v.ownerRoman || v.ownerKey || "-";
    const sameOwner = v.ownerKey ? vessels.filter((v2) => v2.ownerKey === v.ownerKey && v2.mmsi !== v.mmsi) : [];
    const pair = v.pairPermitNo ? vessels.find((v2) => v2.permitNo === v.pairPermitNo) ?? null : null;
    const fcNearby = vessels.filter((fc) => fc.shipCode === "FC" && fc.mmsi !== v.mmsi && haversineNm(fc.lat, fc.lon, v.lat, v.lon) < 5);

    return (
      <div className="rel-panel" onMouseLeave={clearAllHovers}>
        <div className="rel-header">
          <span style={{ fontSize: 14 }}>{meta.icon}</span>
          <span style={{ fontSize: 11, fontWeight: 800, color: meta.color }}>{v.permitNo}</span>
          <span className="rel-badge" style={{ background: `${meta.color}22`, color: meta.color }}>
            {v.shipCode}
          </span>
        </div>

        <div style={{ fontSize: 9, color: "var(--muted)", marginBottom: 6 }}>
          소유주:{" "}
          <b
            style={{
              color: "var(--text)",
              display: "inline-block",
              maxWidth: 230,
              verticalAlign: "bottom",
              whiteSpace: "nowrap",
              overflow: "hidden",
              textOverflow: "ellipsis",
            }}
            title={ownerLabel}
          >
            {ownerLabel}
          </b>
        </div>

        {pair ? (
          <>
            <div style={{ fontSize: 8, fontWeight: 700, color: "var(--muted)", margin: "6px 0 3px", letterSpacing: 1 }}>
              ⛓ 쌍끌이 쌍
            </div>
            {(() => {
              const dist = haversineNm(v.lat, v.lon, pair.lat, pair.lon);
              const warn = dist > 3;
              const pairMeta = VESSEL_TYPES[pair.shipCode];
              return (
                <>
                  <div className="rel-line">
                    <div className="dot" style={{ background: meta.color }} />
                    <span
                      style={{ fontSize: 9, fontWeight: 600, cursor: "pointer" }}
                      onMouseEnter={() => onHoverPair([v.mmsi, pair.mmsi])}
                      onMouseLeave={onClearPairHover}
                      onClick={(e) => handlePrimaryAction(e, v.mmsi)}
                    >
                      {v.permitNo}
                    </span>
                    <div className="rel-link">{warn ? "⚠" : "⟷"}</div>
                    <div className="dot" style={{ background: pairMeta.color }} />
                    <span
                      style={{ fontSize: 9, fontWeight: 600, cursor: "pointer" }}
                      onMouseEnter={() => onHoverPair([v.mmsi, pair.mmsi])}
                      onMouseLeave={onClearPairHover}
                      onClick={(e) => handlePrimaryAction(e, pair.mmsi)}
                    >
                      {pair.permitNo}
                    </span>
                    <span
                      className="rel-dist"
                      style={{
                        background: warn ? rgba(OVERLAY_RGB.pairWarn, 0.13) : "#22C55E22",
                        color: warn ? rgbToHex(OVERLAY_RGB.pairWarn) : "#22C55E",
                      }}
                    >
                      {dist.toFixed(2)}NM
                    </span>
                  </div>
                  <div style={{ fontSize: 8, color: "var(--muted)", marginLeft: 10 }}>
                    정상 범위: 0.3~1.0NM | {warn ? "⚠ 이격 경고" : "✓ 정상 동기화"}
                  </div>
                </>
              );
            })()}
          </>
        ) : null}

        {fcNearby.length && v.shipCode !== "FC" ? (
          <>
            <div style={{ fontSize: 8, fontWeight: 700, color: "var(--muted)", margin: "6px 0 3px", letterSpacing: 1 }}>
              🚛 근접 운반선
            </div>
            {fcNearby.slice(0, 6).map((fc) => {
              const dist = haversineNm(v.lat, v.lon, fc.lat, fc.lon);
              const isSameOwner = !!v.ownerKey && v.ownerKey === fc.ownerKey;
              const warn = dist < 0.5;
              return (
                <div key={fc.mmsi} className="rel-line">
                  <div className="dot" style={{ background: VESSEL_TYPES.FC.color }} />
                  <span
                    style={{ fontSize: 9, fontWeight: 600, cursor: "pointer" }}
                    onMouseEnter={() => onHoverPair([v.mmsi, fc.mmsi])}
                    onMouseLeave={onClearPairHover}
                    onClick={(e) => handlePrimaryAction(e, fc.mmsi)}
                  >
                    {fc.permitNo}
                  </span>
                  <span className="rel-dist" style={{ background: rgba(OVERLAY_RGB.fcTransfer, 0.13), color: rgbToHex(OVERLAY_RGB.fcTransfer) }}>
                    {dist.toFixed(1)}NM
                  </span>
                  {isSameOwner ? (
                    <span
                      style={{
                        fontSize: 7,
                        background: "#F59E0B22",
                        color: "#F59E0B",
                        padding: "1px 3px",
                        borderRadius: 2,
                      }}
                    >
                      동일소유주
                    </span>
                  ) : null}
                  {warn ? (
                    <span
                      style={{
                        fontSize: 7,
                        background: "#EF444422",
                        color: "#EF4444",
                        padding: "1px 3px",
                        borderRadius: 2,
                      }}
                    >
                      환적의심
                    </span>
                  ) : null}
                </div>
              );
            })}
          </>
        ) : null}

        {sameOwner.length ? (
          <>
            <div style={{ fontSize: 8, fontWeight: 700, color: "var(--muted)", margin: "6px 0 3px", letterSpacing: 1 }}>
              🏢 동일 소유주 선단 ({sameOwner.length + 1}척)
            </div>
            {sameOwner.slice(0, 8).map((sv) => {
              const m = VESSEL_TYPES[sv.shipCode];
              return (
                <div
                  key={sv.mmsi}
                  className={`fleet-vessel ${isVesselHighlight(sv.mmsi, v.ownerKey) ? "hl" : ""}`}
                  onMouseEnter={() => onHoverFleet(v.ownerKey, [v.mmsi, ...sameOwner.map((x) => x.mmsi), sv.mmsi])}
                  onMouseLeave={onClearFleetHover}
                  onClick={(e) => handlePrimaryAction(e, sv.mmsi)}
                  style={{ cursor: "pointer" }}
                >
                  <div className="dot" style={{ background: m.color }} />
                  <span style={{ color: m.color, fontWeight: 600 }}>{sv.shipCode}</span> {sv.permitNo}
                  <span style={{ color: "var(--muted)" }}>
                    {sv.sog ?? "?"}kt {sv.state.label}
                  </span>
                </div>
              );
            })}
            {sameOwner.length > 8 ? <div style={{ fontSize: 8, color: "var(--muted)" }}>... +{sameOwner.length - 8}척</div> : null}
          </>
        ) : null}
      </div>
    );
  }

  if (fleetVessels.length === 0) {
    return <div style={{ fontSize: 11, color: "var(--muted)" }}>(현재 지도에 표시중인 대상 선박이 없습니다)</div>;
  }

  if (topFleets.length === 0) {
    return <div style={{ fontSize: 11, color: "var(--muted)" }}>(표시 중인 선단(3척 이상) 없음)</div>;
  }

  return (
    <div onMouseLeave={clearAllHovers}>
      {topFleets.map(({ ownerKey, vs }) => {
        const displayOwner = vs.find((v) => v.ownerCn)?.ownerCn || vs.find((v) => v.ownerRoman)?.ownerRoman || ownerKey;
        const displayTitle = ownerKey && displayOwner !== ownerKey ? `${displayOwner} (${ownerKey})` : displayOwner;
        const isHighlightedFleetRow = isFleetHighlightByOwner(ownerKey) || vs.some((v) => hoveredFleetMmsis.has(v.mmsi));
        const codes: Record<string, number> = {};
        for (const v of vs) codes[v.shipCode] = (codes[v.shipCode] ?? 0) + 1;

        return (
          <div
            key={ownerKey}
            className={`fleet-card ${isHighlightedFleetRow ? "hl" : ""}`}
            onContextMenu={(e) => {
              e.preventDefault();
              onContextMenuFleet?.(ownerKey, vs.map((x) => x.mmsi));
            }}
            onMouseEnter={() => onHoverFleet(ownerKey, vs.map((v) => v.mmsi))}
            onMouseLeave={onClearFleetHover}
          >
            <div className={`fleet-owner ${isHighlightedFleetRow ? "hl" : ""}`}>
              🏢{" "}
                <span
                  style={{
                    display: "inline-block",
                    maxWidth: 240,
                    verticalAlign: "bottom",
                    whiteSpace: "nowrap",
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                    color: "var(--text)",
                    marginRight: 4,
                  }}
                  title={displayTitle}
                >
                  {displayTitle}
                </span>{" "}
                <span style={{ fontSize: 8, color: "var(--muted)" }}>{vs.length}척</span>
              </div>
            <div style={{ display: "flex", gap: 4, flexWrap: "wrap", marginBottom: 3 }}>
              {Object.entries(codes).map(([c, n]) => {
                const meta = VESSEL_TYPES[c as keyof typeof VESSEL_TYPES];
                return (
                  <span
                    key={c}
                    style={{
                      fontSize: 8,
                      background: `${meta.color}22`,
                      color: meta.color,
                      padding: "1px 4px",
                      borderRadius: 2,
                      fontWeight: 600,
                    }}
                  >
                    {c}×{n}
                  </span>
                );
              })}
            </div>

            <div style={{ display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap" }}>
              {vs.slice(0, 18).map((v) => {
                const m = VESSEL_TYPES[v.shipCode];
                const text =
                  v.shipCode === "FC" ? "F" : v.shipCode === "PT" ? "M" : v.shipCode === "PT-S" ? "S" : v.shipCode[0];
                return (
                  <span key={v.mmsi} style={{ display: "inline-flex", alignItems: "center", gap: 2 }}>
                    <div
                      className={`fleet-dot ${isVesselHighlight(v.mmsi, ownerKey) ? "hl" : ""}`}
                      onMouseEnter={() => onHoverMmsi([v.mmsi])}
                      onMouseLeave={onClearHover}
                      onClick={(e) => handlePrimaryAction(e, v.mmsi)}
                      style={{
                        cursor: "pointer",
                        width: 16,
                        height: 16,
                        borderRadius: v.shipCode === "FC" ? 2 : "50%",
                        background: m.color,
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        fontSize: 6,
                        color: "#fff",
                        border: "1px solid rgba(255,255,255,.2)",
                      }}
                      title={`${v.permitNo} ${v.shipCode} ${v.sog ?? "?"}kt`}
                    >
                      {text}
                    </div>
                    {v.pairPermitNo && (v.shipCode === "PT" || v.shipCode === "PT-S") ? <span style={{ fontSize: 8, color: "var(--muted)" }}>⟷</span> : null}
                  </span>
                );
              })}
              {vs.length > 18 ? <span style={{ fontSize: 8, color: "var(--muted)" }}>+{vs.length - 18}</span> : null}
            </div>
          </div>
        );
      })}
    </div>
  );
}
