import * as THREE from "three";
import type {
  ClaimVisual,
  ConstructionSiteVisual,
  NodeVisual,
  Selectable,
  ShipVisual,
  StructureVisual,
} from "./viewerTypes";

/**
 * Local rendering layer.
 * Scene coordinate unit: reserved for future close-up detail.
 * Camera far plane covers immediate surroundings.
 */
export class LocalLayer {
  readonly scene = new THREE.Scene();
  readonly camera = new THREE.PerspectiveCamera(50, 1, 0.1, 2000);
  readonly nodeGroup = new THREE.Group();
  readonly stationGroup = new THREE.Group();
  readonly claimGroup = new THREE.Group();
  readonly constructionSiteGroup = new THREE.Group();
  readonly shipGroup = new THREE.Group();

  readonly selectableTargets = new Map<THREE.Object3D, Selectable>();
  readonly shipVisuals = new Map<string, ShipVisual>();
  readonly nodeVisuals = new Map<string, NodeVisual>();
  readonly stationVisuals = new Map<string, StructureVisual>();
  readonly claimVisuals = new Map<string, ClaimVisual>();
  readonly constructionSiteVisuals = new Map<string, ConstructionSiteVisual>();

  private static readonly ORIGIN = new THREE.Vector3(0, 0, 0);

  constructor() {
    this.scene.add(new THREE.AmbientLight(0x90a6c0, 0.8));
    const keyLight = new THREE.DirectionalLight(0xdcecff, 1.4);
    keyLight.position.set(180, 220, 140);
    this.scene.add(keyLight);
    this.scene.add(
      this.nodeGroup,
      this.stationGroup,
      this.claimGroup,
      this.constructionSiteGroup,
      this.shipGroup,
    );
  }

  updateCamera(orbitOffset: THREE.Vector3) {
    this.camera.position.copy(orbitOffset);
    this.camera.lookAt(LocalLayer.ORIGIN);
  }

  onResize(aspect: number) {
    this.camera.aspect = aspect;
    this.camera.updateProjectionMatrix();
  }

  render(renderer: THREE.WebGLRenderer) {
    renderer.render(this.scene, this.camera);
  }
}
