import { useMemo, useState } from "react";
import type { SystemPointOfInterest } from "../r3f/shared/types";
import { buildGalaxyConnections, findGalaxyRoute, GalaxyScene, generateGalaxy, type GeneratedGalaxySystem } from "../r3f/galaxy/GalaxyScene";
import { useGameSliceSession } from "../game-slice/useGameSliceSession";
import { withGameSliceSession } from "../game-slice/gameSliceState";

export function GalaxyDemo() {
  const { session: sliceSession } = useGameSliceSession();
  const [seed, setSeed] = useState(4242);
  const [count, setCount] = useState(120);
  const [arms, setArms] = useState(4);
  const [verticalArms, setVerticalArms] = useState(0);
  const [size, setSize] = useState(280);
  const [twist, setTwist] = useState(3);
  const [verticalTwist, setVerticalTwist] = useState(1.1);
  const [selected, setSelected] = useState<GeneratedGalaxySystem | null>(null);
  const [selectedPoi, setSelectedPoi] = useState<{ system: GeneratedGalaxySystem; poi: SystemPointOfInterest } | null>(null);
  const [destinationPoi, setDestinationPoi] = useState<{ system: GeneratedGalaxySystem; poi: SystemPointOfInterest } | null>(null);
  const [routePick, setRoutePick] = useState<string[]>([]);

  const systems = useMemo(() => generateGalaxy(seed, { count, arms, verticalArms, size, twist, verticalTwist }), [seed, count, arms, verticalArms, size, twist, verticalTwist]);
  const connections = useMemo(() => buildGalaxyConnections(systems), [systems]);
  const routeIds = routePick.length === 2 ? findGalaxyRoute(routePick[0], routePick[1], connections) : routePick;

  const routePickSystem = (system: GeneratedGalaxySystem) => {
    setDestinationPoi(null);
    setRoutePick((prev) => prev.length >= 2 ? [system.id] : [...prev, system.id]);
  };

  const navigateToPoi = (system: GeneratedGalaxySystem, poi: SystemPointOfInterest) => {
    setSelected(system);
    setSelectedPoi({ system, poi });
    setDestinationPoi({ system, poi });
    setRoutePick((prev) => prev[0] && prev[0] !== system.id ? [prev[0], system.id] : [system.id]);
  };

  return (
    <div style={{ position: "relative", width: "100%", height: "100vh", background: "#040810", overflow: "hidden", color: "#d4dce8" }}>
      <GalaxyScene
        systems={systems}
        connections={connections}
        selectedId={selected?.id ?? null}
        selectedPoiId={selectedPoi?.poi.id ?? destinationPoi?.poi.id ?? null}
        routeIds={routeIds}
        onSelect={(system) => {
          setSelected(system);
          setSelectedPoi(null);
        }}
        onPoiSelect={(system, poi) => {
          setSelected(system);
          setSelectedPoi({ system, poi });
        }}
        onRoutePick={routePickSystem}
      />
      <div style={{ position: "absolute", inset: 0, zIndex: 1, display: "flex", pointerEvents: "none", padding: 12, gap: 12 }}>
        <div style={{ width: 280, pointerEvents: "auto", background: "rgba(15,22,35,0.9)", border: "1px solid var(--border)", borderRadius: 8, padding: 12, alignSelf: "flex-start" }}>
          <a href="/docs/overview" style={{ display: "inline-flex", alignItems: "center", gap: 4, fontSize: "0.75rem", fontFamily: "var(--font-mono)", color: "var(--muted)", textDecoration: "none", marginBottom: 10 }}>
            &larr; Back to Docs
          </a>
          {sliceSession && (
            <button onClick={() => { window.location.href = withGameSliceSession("/docs/demos/game-loop", sliceSession.id); }} style={{ marginLeft: 8 }}>
              Return to Loop
            </button>
          )}
          <h2 style={{ marginTop: 0 }}>Galaxy Demo</h2>
          <label>Seed <input type="number" value={seed} onChange={(event) => setSeed(Number(event.target.value))} style={{ width: "100%" }} /></label>
          <label>Systems {count}<input type="range" min={40} max={220} value={count} onChange={(event) => setCount(Number(event.target.value))} style={{ width: "100%" }} /></label>
          <label>Disk Arms {arms}<input type="range" min={1} max={6} value={arms} onChange={(event) => setArms(Number(event.target.value))} style={{ width: "100%" }} /></label>
          <label>Vertical Arms {verticalArms}<input type="range" min={0} max={4} value={verticalArms} onChange={(event) => setVerticalArms(Number(event.target.value))} style={{ width: "100%" }} /></label>
          <label>Size {size}<input type="range" min={140} max={420} value={size} onChange={(event) => setSize(Number(event.target.value))} style={{ width: "100%" }} /></label>
          <label>Twist {twist.toFixed(1)}<input type="range" min={1} max={6} step={0.1} value={twist} onChange={(event) => setTwist(Number(event.target.value))} style={{ width: "100%" }} /></label>
          <label>Vertical Twist {verticalTwist.toFixed(1)}<input type="range" min={0} max={6} step={0.1} value={verticalTwist} onChange={(event) => setVerticalTwist(Number(event.target.value))} style={{ width: "100%" }} /></label>
          <button onClick={() => setSeed((value) => value + 1)}>Regenerate</button>
          <button onClick={() => { setRoutePick([]); setDestinationPoi(null); }} style={{ marginLeft: 8 }}>Clear Route</button>
          <p style={{ color: "var(--fg-dim)" }}>Click to inspect. Right-click two systems to plot a connected BFS route.</p>
          {destinationPoi && <p style={{ color: "#f0a030" }}>Navigating to {destinationPoi.poi.name} @ {destinationPoi.system.name}</p>}
        </div>
        <div style={{ marginLeft: "auto", width: 280, pointerEvents: "auto", background: "rgba(15,22,35,0.9)", border: "1px solid var(--border)", borderRadius: 8, padding: 12, alignSelf: "flex-start" }}>
          <h3 style={{ marginTop: 0 }}>{selected?.name ?? "No system selected"}</h3>
          {selected && (
            <>
              <p>Faction: {selected.faction}</p>
              <p>Security: {selected.security.toFixed(2)}</p>
              <p>Position: {selected.x.toFixed(0)}, {selected.y.toFixed(0)}, {selected.z.toFixed(0)}</p>
              <p>{selected.planets.length} planets · {selected.pointsOfInterest.length} POIs</p>
              <div style={{ marginBottom: 10 }}>
                <strong style={{ display: "block", marginBottom: 4 }}>Planets</strong>
                <div style={{ display: "grid", gap: 4, maxHeight: 130, overflow: "auto" }}>
                  {selected.planets.map((planet) => (
                    <span key={planet.id} style={{ color: "var(--fg-dim)", fontSize: 12 }}>
                      {planet.name} · {planet.type}{planet.moons ? ` · ${planet.moons} moons` : ""}
                    </span>
                  ))}
                </div>
              </div>
              <div style={{ marginBottom: 10 }}>
                <strong style={{ display: "block", marginBottom: 4 }}>Points of Interest</strong>
                <div style={{ display: "grid", gap: 4, maxHeight: 110, overflow: "auto" }}>
                  {selected.pointsOfInterest.map((poi) => (
                    <button
                      key={poi.id}
                      onClick={() => setSelectedPoi({ system: selected, poi })}
                      style={{ textAlign: "left", color: selectedPoi?.poi.id === poi.id ? "#f0a030" : "var(--fg-dim)", fontSize: 12, padding: "3px 0", background: "transparent", border: 0 }}
                    >
                      {poi.name} · {poi.type.replace(/_/g, " ")}
                    </button>
                  ))}
                </div>
              </div>
              {selectedPoi?.system.id === selected.id && (
                <div style={{ marginBottom: 10, padding: 8, border: "1px solid rgba(240,160,48,0.35)", borderRadius: 6, background: "rgba(240,160,48,0.08)" }}>
                  <strong style={{ color: "#f0a030" }}>{selectedPoi.poi.name}</strong>
                  <p style={{ margin: "4px 0 8px", color: "var(--fg-dim)", fontSize: 12 }}>{selectedPoi.poi.description}</p>
                  <button onClick={() => navigateToPoi(selected, selectedPoi.poi)}>Navigate to POI</button>
                </div>
              )}
            </>
          )}
          <p>Route: {routeIds.length ? routeIds.map((id) => systems.find((system) => system.id === id)?.name ?? id).join(" -> ") : "None"}{destinationPoi ? ` -> ${destinationPoi.poi.name}` : ""}</p>
        </div>
      </div>
    </div>
  );
}
