import { Line } from "@react-three/drei";
import type { ThreeEvent } from "@react-three/fiber";
import { SpaceCanvas } from "../shared/SpaceCanvas";
import { SpaceEnvironment } from "../shared/SpaceEnvironment";
import { CameraRig } from "../shared/CameraRig";
import { RouteLine } from "../shared/RouteLine";
import { StarSystemNode } from "../shared/StarSystemNode";
import { systemToGalaxyWorld } from "../shared/galaxyMap";
import type { GalaxyConnection, GalaxySystem, NavigationRoute, PoiNavigationStatus, PoiNavigationTarget, SystemPointOfInterest, Vec3 } from "../shared/types";
import type { InterstellarTravelStatus } from "../navigation/travelSession";

const toWorld = systemToGalaxyWorld;

type StarMapSceneProps = {
  systems: GalaxySystem[];
  connections: GalaxyConnection[];
  selectedSystemId: string | null;
  hoveredSystemId: string | null;
  currentSystemId: string;
  destinationSystemId: string | null;
  selectedPoiId?: string | null;
  poiNavigationTarget?: PoiNavigationTarget | null;
  waypointSystemIds: string[];
  route: NavigationRoute | null;
  travelStatus?: InterstellarTravelStatus;
  activeSegmentIndex?: number;
  segmentProgress?: number;
  focusTarget?: Vec3 | null;
  onSelect: (system: GalaxySystem) => void;
  onPoiSelect: (system: GalaxySystem, poi: SystemPointOfInterest) => void;
  onPoiNavigationStatusChange?: (status: PoiNavigationStatus) => void;
  onHover: (system: GalaxySystem | null) => void;
  onDoubleClick: (system: GalaxySystem) => void;
  onContextMenu: (system: GalaxySystem, event: ThreeEvent<MouseEvent>) => void;
};

export function StarMapScene({
  systems,
  connections,
  selectedSystemId,
  hoveredSystemId,
  currentSystemId,
  destinationSystemId,
  selectedPoiId,
  poiNavigationTarget,
  waypointSystemIds,
  route,
  travelStatus = "idle",
  activeSegmentIndex = 0,
  segmentProgress = 0,
  focusTarget,
  onSelect,
  onPoiSelect,
  onPoiNavigationStatusChange,
  onHover,
  onDoubleClick,
  onContextMenu,
}: StarMapSceneProps) {
  const byId = new Map(systems.map((system) => [system.id, system]));
  const routePoints = route?.systems.map(toWorld) ?? [];
  const activeSegment = route?.segments[activeSegmentIndex] ?? null;
  const activeFrom = activeSegment ? toWorld(activeSegment.from) : null;
  const activeTo = activeSegment ? toWorld(activeSegment.to) : null;
  const shipMarkerPosition: Vec3 | null = activeFrom && activeTo
    ? [
      activeFrom[0] + (activeTo[0] - activeFrom[0]) * segmentProgress,
      activeFrom[1] + (activeTo[1] - activeFrom[1]) * segmentProgress + 3,
      activeFrom[2] + (activeTo[2] - activeFrom[2]) * segmentProgress,
    ]
    : null;

  return (
    <SpaceCanvas camera={{ position: [0, 180, 230], fov: 50, near: 0.1, far: 5000 }}>
      <SpaceEnvironment density={3600} spread={2200} fog />
      <CameraRig orbit target={focusTarget ?? null} distance={260} />
      <gridHelper args={[460, 24, "#0d1520", "#0d1520"]} position={[0, -2.5, 0]} />
      {connections.map(([a, b]) => {
        const from = byId.get(a);
        const to = byId.get(b);
        if (!from || !to) return null;
        const onRoute = route?.segments.some((segment) => (segment.from.id === a && segment.to.id === b) || (segment.from.id === b && segment.to.id === a));
        return (
          <Line
            key={`${a}-${b}`}
            points={[toWorld(from), toWorld(to)]}
            color={onRoute ? "#22d3ee" : "#1c2a3f"}
            lineWidth={onRoute ? 2 : 1}
            transparent
            opacity={onRoute ? 0.7 : 0.35}
          />
        );
      })}
      <RouteLine points={routePoints} color="#22d3ee" width={3} />
      {route?.segments.map((segment, index) => {
        const completed = travelStatus === "in_transit" && index < activeSegmentIndex;
        const active = travelStatus === "in_transit" && index === activeSegmentIndex;
        if (!completed && !active) return null;
        return (
          <RouteLine
            key={`${segment.from.id}-${segment.to.id}-travel`}
            points={[toWorld(segment.from), toWorld(segment.to)]}
            color={active ? "#f0a030" : "#22c55e"}
            width={active ? 5 : 3}
          />
        );
      })}
      {shipMarkerPosition && travelStatus === "in_transit" && (
        <mesh position={shipMarkerPosition}>
          <coneGeometry args={[2.2, 5.8, 16]} />
          <meshBasicMaterial color="#f0a030" />
        </mesh>
      )}
      {systems.map((system) => (
        <StarSystemNode
          key={system.id}
          system={system}
          position={toWorld(system)}
          selected={system.id === selectedSystemId}
          hovered={system.id === hoveredSystemId}
          current={system.id === currentSystemId}
          destination={system.id === destinationSystemId}
          waypoint={waypointSystemIds.includes(system.id)}
          selectedPoiId={selectedPoiId}
          poiNavigationTarget={poiNavigationTarget}
          onPoiNavigationStatusChange={onPoiNavigationStatusChange}
          onClick={(sys, event) => {
            event.stopPropagation();
            onSelect(sys);
          }}
          onPoiSelect={(sys, poi, event) => {
            event.stopPropagation();
            onPoiSelect(sys, poi);
          }}
          onDoubleClick={(sys, event) => {
            event.stopPropagation();
            onDoubleClick(sys);
          }}
          onContextMenu={(sys, event) => {
            event.stopPropagation();
            onContextMenu(sys, event);
          }}
          onPointerOver={(sys, event) => {
            event.stopPropagation();
            onHover(sys);
            document.body.style.cursor = "pointer";
          }}
          onPointerOut={() => {
            onHover(null);
            document.body.style.cursor = "";
          }}
        />
      ))}
    </SpaceCanvas>
  );
}

export { toWorld as starMapToWorld };
