import { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import { ShieldAlert, RotateCcw } from 'lucide-react';
import { Plane } from '@babylonjs/core';
import { createBabylonContext, destroyBabylonContext, probeWebGLSupport } from './BabylonSceneLifecycle';
import { applyViewPreset, setProjectionMode } from './BabylonCameraController';
import { buildProsthesis } from './ProceduralProsthesisV2';
import { buildMeasurementStations } from './MeasurementStationsV2';
import { buildConceptualCover } from './ConceptualCoverV2';
import { buildBranding } from './BrandingLayerV2';
import { buildDesignPreview } from './DesignPreviewLayer';
import { buildOssiguardConnector } from './OssiguardConnectorLayer';
import { buildHumanReference } from './HumanReferenceV2';
import { buildMeasurementAnatomy } from './MeasurementAnatomyV2';
import { createSelectionManager } from './BabylonSelectionManager';
import { buildWorkshopOverlays } from './WorkshopOverlayLayerV2';
import { buildWorkshopAssembly } from './WorkshopAssemblyLayerV2';
import { buildWorkshopCover } from './WorkshopCoverLayerV2';
import DomLabelLayerV2 from './DomLabelLayerV2';
import { VIEWPORT_V2_BUILD_ID, VIEWPORT_V2_LABEL, BABYLON_VERSION } from './viewportV2Build';

const msg = (e) => (e && e.message ? e.message : String(e));

const traceBabylon = (event, details = {}) => {
  if (typeof window === 'undefined') return;
  const trace = Array.isArray(window.__LIMBFORGE_TRACE__)
    ? window.__LIMBFORGE_TRACE__
    : [];
  trace.push({
    t: Number(performance.now().toFixed(3)),
    source: 'BabylonViewportV2',
    event,
    ...details,
  });
  if (trace.length > 5000) trace.splice(0, trace.length - 5000);
  window.__LIMBFORGE_TRACE__ = trace;
};

const babylonObjectId = (value) => {
  if (typeof window === 'undefined' || !value) return null;
  if (!window.__LIMBFORGE_BABYLON_OBJECT_IDS__) {
    window.__LIMBFORGE_BABYLON_OBJECT_IDS__ = { map: new WeakMap(), next: 1 };
  }
  const store = window.__LIMBFORGE_BABYLON_OBJECT_IDS__;
  if (!store.map.has(value)) store.map.set(value, store.next++);
  return store.map.get(value);
};

const cameraTraceState = (camera) => camera ? {
  alpha: camera.alpha,
  beta: camera.beta,
  radius: camera.radius,
  target: camera.target ? {
    x: camera.target.x,
    y: camera.target.y,
    z: camera.target.z,
  } : null,
} : null;

const DEFAULT_DISPLAY = {
  measurements: true,
  sensitive: true,
  keepOut: true,
  access: true,
  cover: true,
  movement: true,
  logo: true,
};


export default function BabylonViewportV2({
  viewCommand,
  compatibility = false,
  mode = 'cover',
  showAllLabels = false,
  humanReference = false,
  geometry = null,
  designConfig = null,
  measurementStations = null,
  display = DEFAULT_DISPLAY,
  orthographic = false,
  sectionCut = false,
  highlightedStation = -1,
  selectedAngle = null,
  accessPoints = [],
  keepOutZones = [],
  sensitiveZones = [],
  movementPositions = [],
  coverConfig = {},
  coverExploded = false,
  showWorkshopCover = false,
  assembly = [],
  assemblyExploded = false,
  showAssembly = false,
  allowOsseointegrationAssembly = false,
  selectedId: externalSelectedId = null,
  paintMode = false,
  transparency = 1,
  ossiguardProfile = null,
  showOssiguard = true,
  onSelectionChanged = null,
  onOverlaySelection = null,
  onSurfacePoint = null,
  onDiagnostics = null,
}) {
  const canvasRef = useRef(null);
  const containerRef = useRef(null);
  const ctxRef = useRef(null);
  const prosthesisRef = useRef(null);
  const stationsRef = useRef(null);
  const coverRef = useRef(null);
  const brandingRef = useRef(null);
  const designRef = useRef(null);
  const ossiguardRef = useRef(null);
  const humanRefRef = useRef(null);
  const measurementAnatomyRef = useRef(null);
  const overlayRef = useRef(null);
  const assemblyRef = useRef(null);
  const workshopCoverRef = useRef(null);
  const selectionRef = useRef(null);
  const roRef = useRef(null);
  const resizeHandlerRef = useRef(null);
  const destroyedRef = useRef(false);
  const canvasWaitRef = useRef(0);

  const [attempt, setAttempt] = useState(0);
  const [engineError, setEngineError] = useState(null);
  const [layerErrors, setLayerErrors] = useState({
    prosthesis: null,
    stations: null,
    cover: null,
    branding: null,
    design: null,
    ossiguard: null,
    measurementAnatomy: null,
    workshopOverlay: null,
    assembly: null,
    workshopCover: null,
  });
  const [labels, setLabels] = useState([]);
  const [selectedId, setSelectedId] = useState(null);

  // Refs mirror state so the diagnostics interval always reads fresh values.
  const compatRef = useRef(compatibility);
  const orthographicRef = useRef(orthographic);
  const paintModeRef = useRef(paintMode);
  const surfacePointRef = useRef(onSurfacePoint);
  const overlaySelectionRef = useRef(onOverlaySelection);
  const selectionChangedRef = useRef(onSelectionChanged);
  const layerErrorsRef = useRef(layerErrors);
  const engineErrorRef = useRef(engineError);

  useEffect(() => { compatRef.current = compatibility; }, [compatibility]);
  useEffect(() => { orthographicRef.current = orthographic; }, [orthographic]);
  useEffect(() => { paintModeRef.current = paintMode; }, [paintMode]);
  useEffect(() => { surfacePointRef.current = onSurfacePoint; }, [onSurfacePoint]);
  useEffect(() => { overlaySelectionRef.current = onOverlaySelection; }, [onOverlaySelection]);
  useEffect(() => { selectionChangedRef.current = onSelectionChanged; }, [onSelectionChanged]);
  useEffect(() => { layerErrorsRef.current = layerErrors; }, [layerErrors]);
  useEffect(() => { engineErrorRef.current = engineError; }, [engineError]);

  const traceRenderState = (label, extra = {}) => {
    const ctx = ctxRef.current;
    const meshSummary = (meshes) => {
      const list = Array.isArray(meshes) ? meshes.filter(Boolean) : [];
      let enabled = 0;
      list.forEach(mesh => {
        try { if (mesh.isEnabled?.()) enabled += 1; } catch (_) {}
      });
      return {
        total: list.length,
        enabled,
        anyEnabled: enabled > 0,
        allEnabled: list.length > 0 && enabled === list.length,
      };
    };

    const scene = ctx?.scene || null;
    const canvas = ctx?.canvas || canvasRef.current;
    const container = containerRef.current;
    const containerRect = container?.getBoundingClientRect?.() || null;
    const canvasRect = canvas?.getBoundingClientRect?.() || null;

    let activeMeshCount = null;
    try { activeMeshCount = scene?.getActiveMeshes?.()?.length ?? null; } catch (_) {}

    traceBabylon('render_state', {
      label,
      engineId: babylonObjectId(ctx?.engine),
      sceneId: babylonObjectId(scene),
      sceneMeshCount: scene?.meshes?.length ?? null,
      activeMeshCount,
      anatomy: meshSummary(measurementAnatomyRef.current?.leg ? [measurementAnatomyRef.current.leg] : []),
      prosthesis: meshSummary(prosthesisRef.current?.meshes),
      stations: meshSummary(stationsRef.current?.guides),
      genericCover: meshSummary(coverRef.current?.meshes),
      workshopCover: meshSummary(workshopCoverRef.current?.meshes),
      assembly: meshSummary(assemblyRef.current?.meshes),
      camera: cameraTraceState(ctx?.camera),
      containerWidth: containerRect?.width ?? null,
      containerHeight: containerRect?.height ?? null,
      canvasClientWidth: canvas?.clientWidth ?? null,
      canvasClientHeight: canvas?.clientHeight ?? null,
      canvasRectWidth: canvasRect?.width ?? null,
      canvasRectHeight: canvasRect?.height ?? null,
      ...extra,
    });
  };

  useEffect(() => {
    traceBabylon('component_mount');
    return () => traceBabylon('component_unmount');
  }, []);

  useEffect(() => {
    window.__LIMBFORGE_SNAPSHOT__ = (label = 'manual') => {
      traceRenderState(label);
    };
    return () => {
      try { delete window.__LIMBFORGE_SNAPSHOT__; } catch (_) {}
    };
  }, []);

  useEffect(() => {
    setSelectedId(
      externalSelectedId || null
    );
  }, [externalSelectedId]);

  const buildDiagnostics = useCallback(() => {
    const ctx = ctxRef.current;
    if (!ctx) return null;
    const { scene, camera, canvas } = ctx;
    const compat = compatRef.current;
    const errs = layerErrorsRef.current;
    const activeLayers = [];
    if (prosthesisRef.current) activeLayers.push('Prosthesis');
    if (stationsRef.current && !compat) activeLayers.push('Measurement stations');
    if (coverRef.current && !compat) activeLayers.push('Conceptual cover');
    if (brandingRef.current && !compat) activeLayers.push('Branding');
    if (designRef.current && !compat) activeLayers.push('Design preview');
    if (ossiguardRef.current && !compat) activeLayers.push('Ossiguard connector');
    if (overlayRef.current && !compat) activeLayers.push('Workshop overlays');
    if (assemblyRef.current && !compat) activeLayers.push('Workshop assembly');
    if (workshopCoverRef.current && !compat) activeLayers.push('Workshop cover');
    if (measurementAnatomyRef.current && !compat) activeLayers.push('Measurement anatomy');

    const optionalError =
      errs.prosthesis ||
      errs.stations ||
      errs.cover ||
      errs.branding ||
      errs.design ||
      errs.ossiguard ||
      errs.measurementAnatomy ||
      errs.workshopOverlay ||
      errs.assembly ||
      errs.workshopCover ||
      null;
    return {
      implementation: VIEWPORT_V2_LABEL,
      babylonVersion: BABYLON_VERSION,
      engineInstances: 1,
      sceneInstances: 1,
      canvasInstances: 1,
      activeCamera: 'ArcRotateCamera',
      graphicsApi: ctx.engineMode || 'unknown',
      webgl2Available: !!ctx.webglSupport?.webgl2,
      webgl1Available: !!ctx.webglSupport?.webgl1,
      controlsAttached: !!(camera && canvas && canvas.isConnected),
      canvasConnected: !!(canvas && canvas.isConnected),
      canvasWidth: canvas ? canvas.clientWidth : 0,
      canvasHeight: canvas ? canvas.clientHeight : 0,
      renderLoopActive: !destroyedRef.current,
      resizeObservers: roRef.current ? 1 : 0,
      meshCount: scene ? scene.meshes.length : 0,
      activeLayers,
      prosthesisLoaded: !!prosthesisRef.current,
      overlaySpatialMissing: overlayRef.current?.missingSpatial?.length || 0,
      coreError: engineErrorRef.current || null,
      optionalError,
      buildId: VIEWPORT_V2_BUILD_ID,
    };
  }, []);

  // --- Engine + scene init: runs once per attempt. Cleanup order is strict. ---
  useEffect(() => {
    traceBabylon('engine_effect_entry', { attempt });
    destroyedRef.current = false;

    const canvas =
      canvasRef.current;

    const rect =
      canvas
        ?.getBoundingClientRect
        ?.();

    /*
     * React/layout can briefly mount the canvas at 0x0.
     * That is not a graphics failure.
     *
     * Keep the real canvas mounted and retry this same
     * lifecycle after layout settles instead of declaring
     * Babylon/WebGL dead.
     */
    if (
      !canvas ||
      !canvas.isConnected ||
      !rect ||
      rect.width <= 0 ||
      rect.height <= 0
    ) {
      canvasWaitRef.current += 1;

      if (canvasWaitRef.current > 40) {
        setEngineError(
          'Babylon canvas did not become layout-ready.'
        );

        return () => {
          destroyedRef.current = true;
        };
      }

      const retryTimer =
        window.setTimeout(
          () => {
            if (
              !destroyedRef.current
            ) {
              setAttempt(
                current =>
                  current + 1
              );
            }
          },
          150
        );

      return () => {
        destroyedRef.current = true;

        window.clearTimeout(
          retryTimer
        );
      };
    }

    canvasWaitRef.current = 0;

    let ctx = null;
    let initError = null;

    try {
      ctx = createBabylonContext(canvas);
    } catch (e) {
      initError = msg(e);
      setEngineError(initError);
      ctx = null;
    }

    if (!ctx) {
      if (!initError) {
        setEngineError(
          canvas && canvas.isConnected
            ? `Canvas is connected but Babylon returned no graphics context (${canvas.clientWidth}×${canvas.clientHeight})`
            : 'Babylon canvas is not connected'
        );
      }

      return;
    }
    ctxRef.current = ctx;
    const { engine, scene } = ctx;
    traceBabylon('engine_context_created', {
      attempt,
      engineId: babylonObjectId(engine),
      sceneId: babylonObjectId(scene),
      canvasWidth: canvas?.clientWidth ?? 0,
      canvasHeight: canvas?.clientHeight ?? 0,
    });
    const compat = compatRef.current;

    const errs = {
      prosthesis: null,
      stations: null,
      cover: null,
      branding: null,
      design: null,
      ossiguard: null,
      measurementAnatomy: null,
      workshopOverlay: null,
    };
    const allLabels = [];

    // Each optional layer is isolated — failure disables only that layer.
    try {
      const p = buildProsthesis(scene, geometry);
      prosthesisRef.current = p;
      allLabels.push(...p.labels);
    } catch (e) { errs.prosthesis = msg(e); }

    if (!compat) {
      try {
        const s = buildMeasurementStations(scene, measurementStations);
        stationsRef.current = s;
        allLabels.push(...s.labels);
      } catch (e) { errs.stations = msg(e); }
      try {
        const c = buildConceptualCover(scene, geometry, designConfig);
        coverRef.current = c;
        allLabels.push(c.label);
      } catch (e) { errs.cover = msg(e); }
      try {
        const b = buildBranding(scene, designConfig || {});
        brandingRef.current = b;
        allLabels.push(b.label);
      } catch (e) { errs.branding = msg(e); }
      try {
        const d = buildDesignPreview(scene, geometry, designConfig);
        designRef.current = d;
        allLabels.push(d.label);
      } catch (e) { errs.design = msg(e); }
      try {
        if (showOssiguard && ossiguardProfile) {
          const og = buildOssiguardConnector(scene, geometry, ossiguardProfile);
          ossiguardRef.current = og;
          allLabels.push(...og.labels);
        }
      } catch (e) { errs.ossiguard = msg(e); }
    }
    try {
      const h = buildHumanReference(scene);
      humanRefRef.current = h;
    } catch (e) { /* human reference is optional */ }

    /*
     * Dedicated instructional anatomy for Measurement Studio.
     * Hidden by default inside its own builder and enabled only
     * while mode === 'measure'.
     */
    try {
      const anatomy =
        buildMeasurementAnatomy(scene);

      measurementAnatomyRef.current =
        anatomy;

      allLabels.push(
        ...(anatomy.labels || [])
      );
    } catch (e) {
      errs.measurementAnatomy = msg(e);
    }

    setLayerErrors(errs);
    setLabels(allLabels);

    try {
      selectionRef.current = createSelectionManager(
        scene,
        (meta, pickedMesh, pickedPoint) => {
          if (destroyedRef.current) return;

          if (!meta) {
            setSelectedId(null);
            selectionChangedRef.current?.(null);
            overlaySelectionRef.current?.(null);
            return;
          }

          if (
            paintModeRef.current &&
            meta.type === 'prosthesisPart' &&
            pickedPoint
          ) {
            surfacePointRef.current?.(pickedPoint);
            return;
          }

          if (
            meta.type === 'access' ||
            meta.type === 'keepout' ||
            meta.type === 'sensitive' ||
            meta.type === 'movement'
          ) {
            setSelectedId(meta.selectionId || null);
            overlaySelectionRef.current?.(meta);
            return;
          }

          setSelectedId(
            meta.partId ||
            meta.stationId ||
            null
          );

          selectionChangedRef.current?.(meta);
        }
      );
    } catch (_) { /* selection is optional */ }

    engine.runRenderLoop(() => {
      if (destroyedRef.current) return;
      try { scene.render(); } catch (_) {}
    });

    const container = containerRef.current;
    const onResize = () => {
      if (destroyedRef.current) return;
      const c = ctxRef.current;
      if (!c || !c.engine || !c.canvas || !c.canvas.isConnected) return;
      const r = container ? container.getBoundingClientRect() : null;
      const canvasRect = c.canvas?.getBoundingClientRect?.() || null;
      traceBabylon('resize_handler', {
        engineId: babylonObjectId(c.engine),
        sceneId: babylonObjectId(c.scene),
        containerWidth: r?.width ?? null,
        containerHeight: r?.height ?? null,
        canvasClientWidth: c.canvas?.clientWidth ?? null,
        canvasClientHeight: c.canvas?.clientHeight ?? null,
        canvasRectWidth: canvasRect?.width ?? null,
        canvasRectHeight: canvasRect?.height ?? null,
      });
      if (!r || r.width <= 0 || r.height <= 0) return;
      traceBabylon('engine_resize_before', {
        engineId: babylonObjectId(c.engine),
        renderWidth: c.engine.getRenderWidth?.() ?? null,
        renderHeight: c.engine.getRenderHeight?.() ?? null,
        canvasClientWidth: c.canvas?.clientWidth ?? null,
        canvasClientHeight: c.canvas?.clientHeight ?? null,
      });
      try {
        c.engine.resize();
        traceBabylon('engine_resize_after', {
          engineId: babylonObjectId(c.engine),
          renderWidth: c.engine.getRenderWidth?.() ?? null,
          renderHeight: c.engine.getRenderHeight?.() ?? null,
          canvasClientWidth: c.canvas?.clientWidth ?? null,
          canvasClientHeight: c.canvas?.clientHeight ?? null,
        });
      } catch (e) {
        traceBabylon('engine_resize_error', { message: msg(e) });
      }

      try {
        setProjectionMode(
          c.camera,
          orthographicRef.current,
          c.canvas
        );
      } catch (_) {}
    };
    if (container && typeof ResizeObserver !== 'undefined') {
      roRef.current = new ResizeObserver((entries) => {
        const entry = entries?.[0] || null;
        const observedRect = entry?.contentRect || null;
        const targetRect = entry?.target?.getBoundingClientRect?.() || null;
        traceBabylon('resize_observer_event', {
          contentWidth: observedRect?.width ?? null,
          contentHeight: observedRect?.height ?? null,
          targetWidth: targetRect?.width ?? null,
          targetHeight: targetRect?.height ?? null,
          canvasClientWidth: canvasRef.current?.clientWidth ?? null,
          canvasClientHeight: canvasRef.current?.clientHeight ?? null,
        });
        onResize();
      });
      roRef.current.observe(container);
    }
    resizeHandlerRef.current = onResize;
    window.addEventListener('resize', onResize);

    const diagTimer = setInterval(() => {
      if (destroyedRef.current) return;
      const snap = buildDiagnostics();
      if (snap) onDiagnostics && onDiagnostics(snap);
    }, 500);
    const initial = buildDiagnostics();
    if (initial) onDiagnostics && onDiagnostics(initial);

    return () => {
      traceBabylon('engine_effect_cleanup', {
        attempt,
        engineId: babylonObjectId(engine),
        sceneId: babylonObjectId(scene),
        meshCount: scene?.meshes?.length ?? null,
      });
      destroyedRef.current = true;
      clearInterval(diagTimer);
      try { engine.stopRenderLoop(); } catch (_) {}
      try { if (selectionRef.current) { selectionRef.current.dispose(); selectionRef.current = null; } } catch (_) {}
      try { if (prosthesisRef.current) { prosthesisRef.current.dispose(); prosthesisRef.current = null; } } catch (_) {}
      try { if (stationsRef.current) { stationsRef.current.dispose(); stationsRef.current = null; } } catch (_) {}
      try { if (coverRef.current) { coverRef.current.dispose(); coverRef.current = null; } } catch (_) {}
      try { if (brandingRef.current) { brandingRef.current.dispose(); brandingRef.current = null; } } catch (_) {}
      try { if (designRef.current) { designRef.current.dispose(); designRef.current = null; } } catch (_) {}
      try { if (ossiguardRef.current) { ossiguardRef.current.dispose(); ossiguardRef.current = null; } } catch (_) {}
      try { if (humanRefRef.current) { humanRefRef.current.dispose(); humanRefRef.current = null; } } catch (_) {}
      try { if (measurementAnatomyRef.current) { measurementAnatomyRef.current.dispose(); measurementAnatomyRef.current = null; } } catch (_) {}
      try { if (overlayRef.current) { overlayRef.current.dispose(); overlayRef.current = null; } } catch (_) {}
      try { if (roRef.current) { roRef.current.disconnect(); roRef.current = null; } } catch (_) {}
      try { if (resizeHandlerRef.current) { window.removeEventListener('resize', resizeHandlerRef.current); resizeHandlerRef.current = null; } } catch (_) {}
      destroyBabylonContext(ctx);
      ctxRef.current = null;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [attempt]);

  // --- View commands (reset/front/side/top) ---
  useEffect(() => {
    traceBabylon('camera_effect_entry', {
      attempt,
      preset: viewCommand?.preset ?? null,
      commandTs: viewCommand?.ts ?? null,
      engineId: babylonObjectId(ctxRef.current?.engine),
      sceneId: babylonObjectId(ctxRef.current?.scene),
    });
    if (!viewCommand || !ctxRef.current) return;
    const camera = ctxRef.current.camera;
    traceBabylon('applyViewPreset_before', {
      preset: viewCommand.preset,
      camera: cameraTraceState(camera),
    });
    applyViewPreset(camera, viewCommand.preset);
    traceBabylon('applyViewPreset_after', {
      preset: viewCommand.preset,
      camera: cameraTraceState(camera),
    });
    window.requestAnimationFrame(() => {
      traceBabylon('applyViewPreset_after_frame', {
        preset: viewCommand.preset,
        camera: cameraTraceState(camera),
      });
    });
  }, [viewCommand, attempt]);

  // --- Perspective / orthographic projection ---
  useEffect(() => {
    const ctx = ctxRef.current;
    if (!ctx) return;

    try {
      setProjectionMode(
        ctx.camera,
        orthographic,
        ctx.canvas
      );
    } catch (_) {}
  }, [orthographic, attempt]);

  // --- Real Babylon section cut ---
  useEffect(() => {
    const ctx = ctxRef.current;
    if (!ctx) return;

    try {
      ctx.scene.clipPlane =
        sectionCut && !compatibility
          ? new Plane(1, 0, 0, 0)
          : null;
    } catch (_) {}
  }, [sectionCut, compatibility, attempt]);

  // --- Mode + compatibility visibility (no engine/scene recreation) ---
  useEffect(() => {
    const ctx = ctxRef.current;
    if (!ctx) return;

    traceBabylon('visibility_effect_entry', {
      compatibility,
      mode,
      attempt,
    });
    traceRenderState('visibility_before');

    const cover = coverRef.current;
    const brand = brandingRef.current;
    const design = designRef.current;
    const ossiguard = ossiguardRef.current;
    const stations = stationsRef.current;
    const human = humanRefRef.current;
    const measurementAnatomy =
      measurementAnatomyRef.current;
    const prosthesis =
      prosthesisRef.current;
    const overlay = overlayRef.current;

    if (compatibility) {
      traceBabylon('setVisible_call', { layer: 'cover', visible: false, path: 'compatibility' });
      traceBabylon('setVisible_call', { layer: 'stations', visible: false, path: 'compatibility' });
      traceBabylon('setVisible_call', { layer: 'anatomy', visible: false, path: 'compatibility' });
      traceBabylon('setVisible_call', { layer: 'prosthesis', visible: true, path: 'compatibility' });
      cover?.setVisible(false);
      brand?.setVisible(false);
      design?.setVisible(false);
      ossiguard?.setVisible(false);
      stations?.setVisible(false);
      human?.setVisible(false);
      measurementAnatomy?.setVisible(false);

      /*
       * Compatibility mode keeps the established prosthesis
       * fallback rather than depending on the anatomy layer.
       */
      prosthesis?.setVisible?.(true);

      overlay?.setVisibility(display, true);

      ctx.hemi.intensity = 0.95;
      ctx.dir.intensity = 0.25;
    } else {
      const coverMode =
        mode === 'cover' ||
        mode === 'fit';

      const coverOn =
        coverMode &&
        display.cover !== false;

      const measurementsOn =
        display.measurements !== false &&
        (mode === 'internal' || mode === 'measure');

      traceBabylon('setVisible_call', { layer: 'cover', visible: coverOn, path: 'normal' });
      traceBabylon('setVisible_call', { layer: 'stations', visible: measurementsOn, path: 'normal' });
      cover?.setVisible(coverOn);
      design?.setVisible(coverOn);

      brand?.setVisible(
        coverOn &&
        display.logo !== false
      );

      ossiguard?.setVisible(
        showOssiguard &&
        coverOn
      );

      stations?.setVisible(measurementsOn);

      human?.setVisible(
        humanReference ||
        mode === 'fit'
      );

      const measurementAnatomyOn =
        mode === 'measure' &&
        Boolean(measurementAnatomy);

      traceBabylon('setVisible_call', { layer: 'anatomy', visible: measurementAnatomyOn, path: 'normal' });
      measurementAnatomy?.setVisible(
        measurementAnatomyOn
      );

      /*
       * Measurement Studio teaches from human anatomy.
       * Every other Workshop workflow keeps the prosthesis.
       *
       * If anatomy failed to initialise, retain the prosthesis
       * as a visual fallback instead of leaving an empty scene.
       */
      traceBabylon('setVisible_call', { layer: 'prosthesis', visible: !measurementAnatomyOn, path: 'normal' });
      prosthesis?.setVisible?.(
        !measurementAnatomyOn
      );

      overlay?.setVisibility(display, false);

      ctx.hemi.intensity = 0.95;
      ctx.dir.intensity = 0.95;
    }
  }, [
    compatibility,
    mode,
    humanReference,
    showOssiguard,
    display,
    traceRenderState('visibility_after');
    window.requestAnimationFrame(() => traceRenderState('visibility_after_frame'));
    return () => {
      traceBabylon('visibility_effect_cleanup', { compatibility, mode, attempt });
    };
    attempt,
  ]);

  // --- Workshop measurement records can arrive after engine creation. ---
  // Rebuild only the station layer; never recreate the Babylon engine/scene.
  useEffect(() => {
    const ctx = ctxRef.current;
    if (!ctx) return;

    traceBabylon('station_effect_entry', {
      measurementStationsId: babylonObjectId(measurementStations),
      measurementStationsLength: measurementStations?.length ?? 0,
    });
    traceRenderState('station_effect_before');

    try {
      if (stationsRef.current) {
        traceBabylon('station_dispose', {
          stationLayerId: babylonObjectId(stationsRef.current),
        });
        stationsRef.current.dispose();
        stationsRef.current = null;
      }

      const nextStations = buildMeasurementStations(ctx.scene, measurementStations);
      stationsRef.current = nextStations;
      traceBabylon('station_build', {
        stationLayerId: babylonObjectId(nextStations),
        guideCount: nextStations?.guides?.length ?? 0,
        labelCount: nextStations?.labels?.length ?? 0,
      });

      traceBabylon('setVisible_call', {
        layer: 'stations',
        visible:
          !compatibility &&
          display.measurements !== false &&
          (mode === 'internal' || mode === 'measure'),
        path: 'station_rebuild',
      });
      nextStations.setVisible(
        !compatibility &&
        display.measurements !== false &&
        (mode === 'internal' || mode === 'measure')
      );

      nextStations.setHighlighted?.(highlightedStation);

      setLabels((current) => [
        ...current.filter((label) => {
          const kind = label.kind || 'part';
          return kind !== 'station' && kind !== 'dim';
        }),
    traceRenderState('station_effect_after');
    window.requestAnimationFrame(() => traceRenderState('station_effect_after_frame'));
    return () => {
      traceBabylon('station_effect_cleanup', {
        measurementStationsId: babylonObjectId(measurementStations),
      });
    };
        ...nextStations.labels,
      ]);

      setLayerErrors((current) => ({ ...current, stations: null }));
    } catch (e) {
      setLayerErrors((current) => ({ ...current, stations: msg(e) }));
    }
  }, [measurementStations]);

  // --- Guided measurement station highlight ---
  useEffect(() => {
    try {
      stationsRef.current?.setHighlighted?.(
        highlightedStation
      );
    } catch (_) {}
  }, [highlightedStation, attempt]);

  // --- Workshop safety/movement overlays ---
  useEffect(() => {
    const ctx = ctxRef.current;
    if (!ctx) return;

    traceBabylon('overlay_effect_entry', {
      accessPointsLength: accessPoints?.length ?? 0,
      keepOutZonesLength: keepOutZones?.length ?? 0,
      sensitiveZonesLength: sensitiveZones?.length ?? 0,
      movementPositionsLength: movementPositions?.length ?? 0,
    });
    traceRenderState('overlay_before');

    try {
      if (overlayRef.current) {
        traceBabylon('overlay_dispose', {
          overlayId: babylonObjectId(overlayRef.current),
        });
        overlayRef.current.dispose();
        overlayRef.current = null;
      }

      const overlay = buildWorkshopOverlays(
        ctx.scene,
        {
          accessPoints,
          keepOutZones,
          sensitiveZones,
          movementPositions,
        }
      );

      overlayRef.current = overlay;
      traceBabylon('overlay_build', {
        overlayId: babylonObjectId(overlay),
        labelCount: overlay?.labels?.length ?? 0,
        missingSpatialCount: overlay?.missingSpatial?.length ?? 0,
      });

      traceBabylon('overlay_setVisibility', {
        compatibility,
        display,
      });
      overlay.setVisibility(
        display,
        compatibility
      );

      overlay.setSelected?.(selectedId);
      overlay.setSelectedAngle?.(selectedAngle);

      const missingLabels = (
        overlay.missingSpatial || []
      ).map((entry, i) => ({
        id: `safety-missing-${entry.type}-${entry.index}`,
        position: [
          0.85,
          5.85 - i * 0.17,
          0,
        ],
        text: `${entry.label}: 3D position unavailable`,
        kind: 'safety-warning',
        tone: 'amber',
      }));

      setLabels((current) => [
        ...current.filter((label) => ![
          'access',
          'keepout',
          'sensitive',
          'movement',
          'safety-warning',
        ].includes(label.kind)),
        ...overlay.labels,
        ...missingLabels,
      ]);

      setLayerErrors((current) => ({
        ...current,
        workshopOverlay: null,
      }));
    } catch (e) {
      setLayerErrors((current) => ({
        ...current,
        workshopOverlay: msg(e),
      }));
    }

    traceRenderState('overlay_after');
    window.requestAnimationFrame(() => traceRenderState('overlay_after_frame'));

    return () => {
      try {
      traceBabylon('overlay_effect_cleanup', {
        overlayId: babylonObjectId(overlayRef.current),
      });
        overlayRef.current?.dispose();
      } catch (_) {}

      overlayRef.current = null;
    };
  }, [
    accessPoints,
    keepOutZones,
    sensitiveZones,
    movementPositions,
  ]);

  useEffect(() => {
    try {
      overlayRef.current?.setSelected?.(
        selectedId
      );
    } catch (_) {}
  }, [selectedId]);

  useEffect(() => {
    try {
      overlayRef.current?.setSelectedAngle?.(
        selectedAngle
      );
    } catch (_) {}
  }, [selectedAngle]);

  // --- Workshop Cover Builder layer ---
  useEffect(() => {
    const ctx = ctxRef.current;

    if (!ctx) return;

    traceBabylon('workshop_cover_effect_entry', {
      compatibility, mode, showWorkshopCover,
      displayCover: display.cover,
      attempt,
    });
    traceRenderState('workshop_cover_before');

    try {
      if (workshopCoverRef.current) {
        traceBabylon('workshop_cover_dispose', {
          coverId: babylonObjectId(workshopCoverRef.current),
        });
        workshopCoverRef.current.dispose();
        workshopCoverRef.current = null;
      }

      setLabels(current =>
        current.filter(
          label =>
            label.kind !== 'cover-control' &&
            !(
              label.kind === 'safety-warning' &&
              String(label.id || '').startsWith(
                'workshop-cover-'
              )
            )
        )
      );

      if (
        compatibility ||
        !showWorkshopCover
      ) {
        traceBabylon('setVisible_call', {
          layer: 'genericCover',
          visible: !compatibility &&
            (mode === 'cover' || mode === 'fit') &&
            display.cover !== false,
          path: 'workshop_cover_inactive',
        });
        coverRef.current
          ?.setVisible?.(
            !compatibility &&
            (mode === 'cover' || mode === 'fit') &&
            display.cover !== false
          );

        setLayerErrors(current => ({
          ...current,
          workshopCover: null,
        }));

        traceRenderState('workshop_cover_inactive_after');
        return;
      }

      /*
       * Hide the older generic cover while the live
       * Cover Builder preview owns the cosmetic shell.
       */
      traceBabylon('setVisible_call', {
        layer: 'genericCover',
        visible: false,
        path: 'workshop_cover_active',
      });
      coverRef.current
        ?.setVisible?.(false);

      const next =
        buildWorkshopCover(
          ctx.scene,
          geometry,
          coverConfig,
          {
            exploded:
              coverExploded,
            sensitiveZones,
          }
        );

      workshopCoverRef.current =
        next;
      traceBabylon('workshop_cover_build', {
        coverId: babylonObjectId(next),
        meshCount: next?.meshes?.length ?? 0,
      });

      traceBabylon('setVisible_call', {
        layer: 'workshopCover',
        visible: display.cover !== false,
        path: 'workshop_cover_build',
      });
      next.setVisible?.(
        display.cover !== false
      );

      const numeric =
        Number(transparency);

      next.setOpacity?.(
        Number.isFinite(numeric)
          ? Math.max(
              0.1,
              Math.min(1, numeric)
            )
          : 1
      );

      setLabels(current => [
        ...current.filter(
          label =>
            label.kind !==
              'cover-control' &&
            !(
              label.kind ===
                'safety-warning' &&
              String(
                label.id || ''
              ).startsWith(
                'workshop-cover-'
              )
            )
        ),
        ...next.labels,
      ]);

      setLayerErrors(current => ({
        ...current,
        workshopCover: null,
      }));
    } catch (e) {
      setLayerErrors(current => ({
        ...current,
        workshopCover: msg(e),
      }));
    }

    traceRenderState('workshop_cover_after');
    window.requestAnimationFrame(() => traceRenderState('workshop_cover_after_frame'));

    return () => {
      try {
      traceBabylon('workshop_cover_effect_cleanup', {
        coverId: babylonObjectId(workshopCoverRef.current),
      });
        workshopCoverRef.current
          ?.dispose();
      } catch (_) {}

      workshopCoverRef.current =
        null;
    };
  }, [
    coverConfig,
    coverExploded,
    showWorkshopCover,
    geometry,
    sensitiveZones,
    compatibility,
    mode,
    display.cover,
    transparency,
    attempt,
  ]);

  useEffect(() => {
    try {
      workshopCoverRef.current
        ?.setVisible?.(
          !compatibility &&
          showWorkshopCover &&
          (mode === 'cover' || mode === 'fit') &&
          display.cover !== false
        );
    } catch (_) {}
  }, [
    display.cover,
    compatibility,
    showWorkshopCover,
    mode,
  ]);

  // --- Workshop assembly layer ---
  useEffect(() => {
    const ctx = ctxRef.current;

    if (!ctx) return;

    traceBabylon('assembly_effect_entry', {
      assemblyId: babylonObjectId(assembly),
      assemblyLength: Array.isArray(assembly) ? assembly.length : null,
      assemblyExploded,
      showAssembly,
      allowOsseointegrationAssembly,
      compatibility,
      attempt,
    });
    traceRenderState('assembly_before');

    try {
      if (assemblyRef.current) {
        traceBabylon('assembly_dispose', {
          assemblyLayerId: babylonObjectId(assemblyRef.current),
        });
        assemblyRef.current.dispose();
        assemblyRef.current = null;
      }

      setLabels(current =>
        current.filter(
          label =>
            label.kind !== 'assembly' &&
            label.kind !== 'assembly-warning'
        )
      );

      if (
        compatibility ||
        !showAssembly ||
        !Array.isArray(assembly) ||
        assembly.length === 0
      ) {
        setLayerErrors(current => ({
          ...current,
          assembly: null,
        }));

        traceBabylon('assembly_inactive', {
          compatibility,
          showAssembly,
          assemblyLength: Array.isArray(assembly) ? assembly.length : null,
        });
        traceRenderState('assembly_inactive_after');
        return;
      }

      const next =
        buildWorkshopAssembly(
          ctx.scene,
          assembly,
          {
            exploded:
              assemblyExploded,
            allowOsseointegration:
              allowOsseointegrationAssembly,
          }
        );

      assemblyRef.current = next;
      traceBabylon('assembly_build', {
        assemblyLayerId: babylonObjectId(next),
        meshCount: next?.meshes?.length ?? 0,
        labelCount: next?.labels?.length ?? 0,
        warningCount: next?.warnings?.length ?? 0,
      });

      traceBabylon('setVisible_call', {
        layer: 'assembly',
        visible: true,
        path: 'assembly_build',
      });
      next.setVisible?.(true);

      next.setSelected?.(
        externalSelectedId ||
        selectedId
      );

      setLabels(current => [
        ...current.filter(
          label =>
            label.kind !== 'assembly' &&
            label.kind !==
              'assembly-warning'
        ),
        ...next.labels,
        ...next.warnings,
      ]);

      setLayerErrors(current => ({
        ...current,
        assembly: null,
      }));
    } catch (e) {
      setLayerErrors(current => ({
        ...current,
        assembly: msg(e),
      }));
    }

    traceRenderState('assembly_after');
    window.requestAnimationFrame(() => traceRenderState('assembly_after_frame'));

    return () => {
      try {
      traceBabylon('assembly_effect_cleanup', {
        assemblyLayerId: babylonObjectId(assemblyRef.current),
      });
        assemblyRef.current?.dispose();
      } catch (_) {}

      assemblyRef.current = null;
    };
  }, [
    assembly,
    assemblyExploded,
    showAssembly,
    allowOsseointegrationAssembly,
    compatibility,
    attempt,
  ]);

  useEffect(() => {
    try {
      assemblyRef.current
        ?.setSelected?.(
          externalSelectedId ||
          selectedId
        );
    } catch (_) {}
  }, [
    externalSelectedId,
    selectedId,
  ]);

  // --- Workshop transparency updates without engine recreation. ---
  useEffect(() => {
    const cover = coverRef.current;
    const workshopCover =
      workshopCoverRef.current;
    const prosthesis = prosthesisRef.current;

    const numeric = Number(transparency);
    const opacity = Number.isFinite(numeric)
      ? Math.max(0.1, Math.min(1, numeric))
      : 1;

    const effectiveOpacity =
      compatibility ? 1 : opacity;

    try {
      cover?.setOpacity?.(
        effectiveOpacity
      );
    } catch (_) {}

    try {
      workshopCover?.setOpacity?.(
        effectiveOpacity
      );
    } catch (_) {}

    try {
      const referenceOpacity =
        showAssembly &&
        Array.isArray(assembly) &&
        assembly.length > 0 &&
        !compatibility
          ? Math.min(
              effectiveOpacity,
              0.22
            )
          : effectiveOpacity;

      prosthesis?.setOpacity?.(
        referenceOpacity
      );
    } catch (_) {}
  }, [
    transparency,
    compatibility,
    showAssembly,
    assembly,
  ]);

  // --- Design config updates (no engine/scene recreation) ---
  useEffect(() => {
    const cover = coverRef.current;
    const brand = brandingRef.current;
    const design = designRef.current;
    if (cover && cover.update) try { cover.update(designConfig || {}); } catch (_) {}
    if (brand && brand.update) try { brand.update(designConfig || {}); } catch (_) {}
    if (design && design.update) try { design.update(designConfig || {}); } catch (_) {}
  }, [designConfig]);

  // --- Ossiguard profile updates (no engine/scene recreation) ---
  useEffect(() => {
    const og = ossiguardRef.current;
    if (og && og.update) try { og.update(ossiguardProfile || {}); } catch (_) {}
  }, [ossiguardProfile]);

  const getContext = useCallback(() => ctxRef.current, []);
  const visibleLabels = useMemo(() => {
    const showStation =
      display.measurements !== false &&
      (mode === 'internal' || mode === 'measure');

    const showDim =
      display.measurements !== false &&
      mode === 'measure';

    const showWarning =
      mode === 'cover' ||
      mode === 'fit';

    const filtered = labels.filter((label) => {
      const kind = label.kind || 'part';

      if (
        compatibility &&
        [
          'warning',
          'safety-warning',
          'station',
          'dim',
          'anatomy',
          'access',
          'keepout',
          'sensitive',
          'movement',
        ].includes(kind)
      ) {
        return false;
      }

      if (kind === 'warning') {
        return showWarning;
      }

      if (kind === 'safety-warning') {
        return true;
      }

      if (kind === 'station') {
        if (!showStation) {
          return false;
        }

        /*
         * Focus Mode:
         * keep every 3D guide selectable, but remove the
         * wall of twelve overlapping DOM badges.
         */
        return (
          showAllLabels ||
          label.guideIndex ===
            highlightedStation
        );
      }

      if (kind === 'dim') {
        return showDim;
      }

      if (kind === 'anatomy') {
        return (
          mode === 'measure' &&
          !compatibility
        );
      }

      if (kind === 'access') {
        return display.access !== false &&
          (showAllLabels || label.id === selectedId);
      }

      if (kind === 'keepout') {
        return display.keepOut !== false &&
          (showAllLabels || label.id === selectedId);
      }

      if (kind === 'sensitive') {
        return display.sensitive !== false &&
          (showAllLabels || label.id === selectedId);
      }

      if (kind === 'movement') {
        return display.movement !== false &&
          (showAllLabels || label.id === selectedId);
      }

      if (showAllLabels) {
        return true;
      }

      return !!selectedId &&
        (
          label.id === selectedId ||
          label.id === `part-${selectedId}`
        );
    });

    const focused =
      filtered.map(label => {
        if (
          label.kind === 'station' &&
          label.guideIndex ===
            highlightedStation
        ) {
          const sequence =
            label.badge
              ? `${label.badge} — `
              : '';

          const safetySuffix =
            label.nonSpatial
              ? ' · REFERENCE ONLY'
              : '';

          return {
            ...label,
            badge: null,
            text:
              `${sequence}${label.text}${safetySuffix}`,
            tone:
              label.nonSpatial
                ? 'amber'
                : 'cyan',
            focus: true,
          };
        }

        return label;
      });

    const activeGuide =
      focused.find(
        label =>
          label.kind === 'station' &&
          label.focus === true
      );

    if (
      !activeGuide ||
      activeGuide.nonSpatial ||
      activeGuide.guideKind === 'ring' ||
      !Array.isArray(activeGuide.guideStart) ||
      !Array.isArray(activeGuide.guideEnd)
    ) {
      return focused;
    }

    const isLength =
      activeGuide.guideType === 'length';

    return [
      ...focused,
      {
        id:
          `${activeGuide.id}-start`,
        position:
          activeGuide.guideStart,
        text:
          isLength
            ? 'START — upper reference'
            : 'START',
        kind: 'guide-endpoint',
        tone: 'cyan',
      },
      {
        id:
          `${activeGuide.id}-end`,
        position:
          activeGuide.guideEnd,
        text:
          isLength
            ? 'END — distal end'
            : 'END',
        kind: 'guide-endpoint',
        tone: 'cyan',
      },
    ];
  }, [
    labels,
    compatibility,
    mode,
    showAllLabels,
    selectedId,
    highlightedStation,
    display,
  ]);

  const handleRetry = () => {
    canvasWaitRef.current = 0;
    setEngineError(null);
    setAttempt((a) => a + 1);
  };

  // --- Fatal engine overlay ---
  if (engineError) {
    const support = probeWebGLSupport();

    const webgl = [
      `WebGL2: ${support.webgl2 ? 'Available' : 'Unavailable'}`,
      `WebGL1: ${support.webgl1 ? 'Available' : 'Unavailable'}`,
    ].join(' · ');

    const canvas = canvasRef.current;
    return (
      <div className="flex h-full w-full items-center justify-center p-6">
        <div className="panel max-w-lg space-y-3 p-6">
          <div className="flex items-center gap-2 text-red-300"><ShieldAlert className="h-5 w-5" /><span className="text-sm font-semibold">Babylon Engine could not initialise</span></div>
          <p className="text-xs text-slate-400">The fatal viewport message is shown only when the Engine itself cannot start. Optional-layer failures never reach this state.</p>
          <dl className="divide-y divide-white/5 rounded-lg border border-white/10 bg-black/20 text-xs">
            {[
              ['Actual error', engineError],
              ['Canvas state', canvas ? (canvas.isConnected ? 'connected' : 'detached') : 'no canvas ref'],
              ['Canvas dimensions', canvas ? `${canvas.clientWidth}×${canvas.clientHeight}` : '—'],
              ['WebGL availability', webgl],
              ['Babylon version', BABYLON_VERSION],
              ['Browser renderer', typeof navigator !== 'undefined' ? navigator.userAgent : '—'],
            ].map(([k, v]) => (
              <div key={k} className="flex justify-between gap-3 px-3 py-2"><dt className="text-slate-500">{k}</dt><dd className="text-right text-slate-200">{String(v)}</dd></div>
            ))}
          </dl>
          <button onClick={handleRetry} className="btn-primary w-full"><RotateCcw className="mr-1.5 h-4 w-4" />Retry V2</button>
        </div>
      </div>
    );
  }

  const layerUnavailable = Object.entries(layerErrors).filter(([, v]) => v).map(([k]) => k);

  return (
    <div ref={containerRef} className="relative h-full w-full">
      <canvas ref={canvasRef} className="h-full w-full touch-none outline-none" />
      <DomLabelLayerV2 getContext={getContext} labels={visibleLabels} />

      {layerUnavailable.length > 0 && (
        <div className="absolute left-3 top-3 z-20 flex flex-wrap gap-1.5">
          {layerUnavailable.map((k) => (
            <span key={k} className="rounded-md border border-amber-400/40 bg-[#0b0f13]/90 px-2 py-1 text-[11px] font-medium text-amber-300">
              {labelName(k)} unavailable
            </span>
          ))}
        </div>
      )}

      <div className="pointer-events-none absolute bottom-3 left-1/2 z-20 -translate-x-1/2 rounded-lg border border-white/10 bg-[#0b0f13]/90 px-3 py-1.5 text-center text-[11px] text-slate-300 backdrop-blur">
        {mode === 'measure'
          ? 'Generic instructional residual-limb anatomy — not customer anatomy and not a clinical measurement.'
          : (
              designConfig
                ? (
                    designConfig.custom_text_enabled
                      ? 'Design concept applied — not manufacturing CAD'
                      : 'Design styling applied — not manufacturing CAD'
                  )
                : (
                    geometry && geometry.statusLabel
                      ? geometry.statusLabel
                      : 'Generic below-knee visual model — not customer geometry and not manufacturing CAD.'
                  )
            )}
      </div>
    </div>
  );
}

function labelName(k) {
return { prosthesis: 'Prosthesis', stations: 'Measurement layer', cover: 'Cover layer', branding: 'Branding layer', design: 'Design layer', ossiguard: 'Ossiguard layer', measurementAnatomy: 'Measurement anatomy', workshopOverlay: 'Workshop overlays', assembly: 'Prosthesis Mapper assembly', workshopCover: 'Cover Builder preview' }[k] || k;
}
