/**
 * `WorldSurfaceView` — mount a surface in world space.
 *
 * Renders a world mount node (a `kind: table` surface and its child surfaces)
 * at its anchor. Parts on the surface are placed via `PartPlacement` from the
 * derived render state. A disabled surface isn't part of the mount tree, so
 * it's never rendered.
 */
import type { Package } from '@tts/bgm';
import { useRenderState, placementKey } from '../state.js';
import { PartPlacement } from '../placement.js';
import type { MountNode } from '../mount.js';
import { MM_TO_WORLD, DEG_TO_RAD } from '../part.js';
import { SurfaceBounds } from './SurfaceBounds.js';
import { SurfacePlane } from './SurfacePlane.js';

export function WorldSurfaceView({
  pkg,
  node,
  showSurface = false,
}: {
  pkg: Package;
  node: MountNode;
  showSurface?: boolean;
}) {
  return <SurfaceNode pkg={pkg} node={node} showSurface={showSurface} />;
}

/** Render a mount node at its anchor, placing parts and recursing into children. */
export function SurfaceNode({
  pkg,
  node,
  showSurface = false,
}: {
  pkg: Package;
  node: MountNode;
  showSurface?: boolean;
}) {
  const placements = useRenderState(pkg);
  const own = placements.filter((p) => p.surface === node.id);

  return (
    <group
      position={[node.x * MM_TO_WORLD, 0, node.y * MM_TO_WORLD]}
      rotation={[0, node.rotation * DEG_TO_RAD, 0]}
    >
      {showSurface && (
        <>
          <SurfacePlane surface={node.surface} />
          <SurfaceBounds surface={node.surface} />
        </>
      )}
      {own.map((p) => (
        <PartPlacement key={placementKey(p)} pkg={pkg} placement={p} />
      ))}
      {node.children.map((child) => (
        <SurfaceNode key={child.id} pkg={pkg} node={child} showSurface={showSurface} />
      ))}
    </group>
  );
}