/**
 * Stage 5: Brace Fitting Inspection
 * Shows both braces overlaid on the body scan to visualize fit
 * LEFT panel: Position, Rotation, Scale controls
 * RIGHT panel: Deformation sliders (Cobb angle, apex, etc.) from Stage 4
 */
import { useEffect, useRef, useState, useCallback } from 'react';
import BraceInlineEditor, { 
  type BraceTransformParams, 
  DEFAULT_TRANSFORM_PARAMS 
} from './BraceInlineEditor';

// Three.js is loaded dynamically
let THREE: any = null;
let STLLoader: any = null;
let GLTFLoader: any = null;
let OrbitControls: any = null;

type BraceFittingStageProps = {
  caseId: string;
  bodyScanUrl: string | null;
  regularBraceUrl: string | null;
  vaseBraceUrl: string | null;
  braceData: any;
};

export default function BraceFittingStage({
  caseId,
  bodyScanUrl,
  regularBraceUrl,
  vaseBraceUrl,
  braceData,
}: BraceFittingStageProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const rendererRef = useRef<any>(null);
  const sceneRef = useRef<any>(null);
  const cameraRef = useRef<any>(null);
  const controlsRef = useRef<any>(null);
  const animationFrameRef = useRef<number>(0);
  
  // Mesh references
  const bodyMeshRef = useRef<any>(null);
  const regularBraceMeshRef = useRef<any>(null);
  const vaseBraceMeshRef = useRef<any>(null);
  const regularBaseGeomRef = useRef<any>(null);
  const vaseBaseGeomRef = useRef<any>(null);
  
  // Store base transforms for relative positioning
  const baseScaleRef = useRef<number>(1);
  
  const [threeLoaded, setThreeLoaded] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  
  // Visibility controls
  const [showBody, setShowBody] = useState(true);
  const [showRegularBrace, setShowRegularBrace] = useState(true);
  const [showVaseBrace, setShowVaseBrace] = useState(false);
  const [bodyOpacity, setBodyOpacity] = useState(0.3);
  const [autoRotate, setAutoRotate] = useState(false);
  
  // Position/Rotation/Scale controls (for moving meshes)
  const [bracePositionX, setBracePositionX] = useState(0);
  const [bracePositionY, setBracePositionY] = useState(0);
  const [bracePositionZ, setBracePositionZ] = useState(0);
  const [braceRotationX, setBraceRotationX] = useState(0);
  const [braceRotationY, setBraceRotationY] = useState(0);
  const [braceRotationZ, setBraceRotationZ] = useState(0);
  const [braceScaleX, setBraceScaleX] = useState(1.0);
  const [braceScaleY, setBraceScaleY] = useState(1.0);
  const [braceScaleZ, setBraceScaleZ] = useState(1.0);
  
  // Body position/rotation/scale
  const [bodyPositionX, setBodyPositionX] = useState(0);
  const [bodyPositionY, setBodyPositionY] = useState(0);
  const [bodyPositionZ, setBodyPositionZ] = useState(0);
  const [bodyRotationX, setBodyRotationX] = useState(0);
  const [bodyRotationY, setBodyRotationY] = useState(0);
  const [bodyRotationZ, setBodyRotationZ] = useState(0);
  const [bodyScale, setBodyScale] = useState(1.0);
  
  // Which brace is being edited
  const [activeBrace, setActiveBrace] = useState<'regular' | 'vase'>('regular');
  
  // Transform params for each brace (deformation sliders)
  const [regularParams, setRegularParams] = useState<BraceTransformParams>(() => ({
    ...DEFAULT_TRANSFORM_PARAMS,
    cobbDeg: braceData?.cobb_angles?.MT || braceData?.cobb_angles?.TL || 25,
  }));
  const [vaseParams, setVaseParams] = useState<BraceTransformParams>(() => ({
    ...DEFAULT_TRANSFORM_PARAMS,
    cobbDeg: braceData?.cobb_angles?.MT || braceData?.cobb_angles?.TL || 25,
  }));
  
  // Colors
  const BODY_COLOR = 0xf5d0c5;
  const REGULAR_BRACE_COLOR = 0x4a90d9;
  const VASE_BRACE_COLOR = 0x50c878;

  // Load Three.js
  useEffect(() => {
    const loadThree = async () => {
      try {
        const threeModule = await import('three');
        THREE = threeModule;
        const { STLLoader: STL } = await import('three/examples/jsm/loaders/STLLoader.js');
        STLLoader = STL;
        const { GLTFLoader: GLTF } = await import('three/examples/jsm/loaders/GLTFLoader.js');
        GLTFLoader = GLTF;
        const { OrbitControls: Controls } = await import('three/examples/jsm/controls/OrbitControls.js');
        OrbitControls = Controls;
        setThreeLoaded(true);
      } catch (e) {
        console.error('Failed to load Three.js:', e);
        setError('Failed to load 3D viewer');
      }
    };
    loadThree();
    return () => {
      if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current);
      if (rendererRef.current) rendererRef.current.dispose();
    };
  }, []);

  // Initialize scene
  useEffect(() => {
    if (!threeLoaded || !containerRef.current || rendererRef.current) return;
    
    const container = containerRef.current;
    const width = container.clientWidth;
    const height = container.clientHeight;
    
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0x1a1a2e);
    sceneRef.current = scene;
    
    const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
    // For Z-up meshes (medical/scanner convention), view from front (Y axis)
    // Camera at Y=-800 looking at torso level (Z~300)
    camera.position.set(0, -800, 300);
    camera.lookAt(0, 0, 300);
    camera.up.set(0, 0, 1);  // Z is up
    cameraRef.current = camera;
    
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setSize(width, height);
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.shadowMap.enabled = true;
    renderer.sortObjects = true;
    container.appendChild(renderer.domElement);
    rendererRef.current = renderer;
    
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;
    controls.target.set(0, 0, 300);  // Look at torso level
    controlsRef.current = controls;
    
    // Lighting (adjusted for Z-up)
    scene.add(new THREE.AmbientLight(0xffffff, 0.6));
    const keyLight = new THREE.DirectionalLight(0xffffff, 0.8);
    keyLight.position.set(200, -300, 500);  // Front-top-right
    scene.add(keyLight);
    const fillLight = new THREE.DirectionalLight(0x88ccff, 0.5);
    fillLight.position.set(-200, -100, 400);  // Front-left
    scene.add(fillLight);
    const backLight = new THREE.DirectionalLight(0xffffcc, 0.4);
    backLight.position.set(0, 300, 300);  // Back
    scene.add(backLight);
    
    // Grid on XY plane (floor for Z-up world)
    const gridHelper = new THREE.GridHelper(400, 20, 0x444444, 0x333333);
    gridHelper.rotation.x = Math.PI / 2;  // Rotate to XY plane
    gridHelper.position.z = 0;  // At Z=0 (floor level)
    scene.add(gridHelper);
    
    const animate = () => {
      animationFrameRef.current = requestAnimationFrame(animate);
      controls.update();
      renderer.render(scene, camera);
    };
    animate();
    
    const handleResize = () => {
      if (!container || !renderer || !camera) return;
      camera.aspect = container.clientWidth / container.clientHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(container.clientWidth, container.clientHeight);
    };
    const resizeObserver = new ResizeObserver(handleResize);
    resizeObserver.observe(container);
    return () => resizeObserver.disconnect();
  }, [threeLoaded]);

  useEffect(() => {
    if (controlsRef.current) controlsRef.current.autoRotate = autoRotate;
  }, [autoRotate]);

  // Deformation algorithm
  const applyDeformation = useCallback((geometry: any, params: BraceTransformParams) => {
    if (!THREE || !geometry) return geometry;
    const deformed = geometry.clone();
    const positions = deformed.getAttribute('position');
    if (!positions) return deformed;

    deformed.computeBoundingBox();
    const bbox = deformed.boundingBox;
    // For Z-up convention (medical/scanner), Z is vertical (height)
    const minZ = bbox?.min?.z || 0, maxZ = bbox?.max?.z || 1;
    const minX = bbox?.min?.x || -0.5, maxX = bbox?.max?.x || 0.5;
    const minY = bbox?.min?.y || -0.5, maxY = bbox?.max?.y || 0.5;
    const centerX = (minX + maxX) / 2, centerY = (minY + maxY) / 2;
    const bboxHeight = maxZ - minZ, bboxWidth = maxX - minX, bboxDepth = maxY - minY;

    const pelvis = { x: centerX, y: centerY, z: minZ };
    const braceHeight = bboxHeight || 1;
    const unitsPerMm = braceHeight / Math.max(1e-6, params.expectedBraceHeightMm);
    const sev = Math.max(0, Math.min(1, (params.cobbDeg - 15) / 40));
    const padDepthMm = (8 + 12 * sev) * params.strengthMult;
    const bayClearMm = padDepthMm * 1.2;
    const padDepth = padDepthMm * unitsPerMm;
    const bayClear = bayClearMm * unitsPerMm;
    const sizeScale = 0.9 + 0.5 * sev;

    // For Z-up convention: Z is height, Y is front-back depth, X is left-right width
    const features: Array<{ center: {x:number,y:number,z:number}; radii: {x:number,y:number,z:number}; depth: number; direction: 1|-1; falloffPower: number }> = [];
    
    // Thoracic pad & bay (z is now height, y is depth)
    features.push({ center: { x: centerX + bboxWidth * 0.35, y: centerY - bboxDepth * 0.1, z: minZ + bboxHeight * params.apexNorm }, radii: { x: 45*unitsPerMm*sizeScale, y: 35*unitsPerMm*sizeScale, z: 90*unitsPerMm*sizeScale }, depth: padDepth, direction: -1, falloffPower: 2.0 });
    features.push({ center: { x: centerX - bboxWidth * 0.35, y: centerY - bboxDepth * 0.1, z: minZ + bboxHeight * params.apexNorm }, radii: { x: 60*unitsPerMm*sizeScale, y: 55*unitsPerMm*sizeScale, z: 110*unitsPerMm*sizeScale }, depth: bayClear, direction: 1, falloffPower: 1.6 });
    // Lumbar pad & bay
    features.push({ center: { x: centerX - bboxWidth * 0.3, y: centerY, z: minZ + bboxHeight * params.lumbarApexNorm }, radii: { x: 50*unitsPerMm*sizeScale, y: 40*unitsPerMm*sizeScale, z: 80*unitsPerMm*sizeScale }, depth: padDepth*0.9, direction: -1, falloffPower: 2.0 });
    features.push({ center: { x: centerX + bboxWidth * 0.3, y: centerY, z: minZ + bboxHeight * params.lumbarApexNorm }, radii: { x: 65*unitsPerMm*sizeScale, y: 55*unitsPerMm*sizeScale, z: 95*unitsPerMm*sizeScale }, depth: bayClear*0.9, direction: 1, falloffPower: 1.6 });
    // Hip anchors
    const hipDepth = params.hipAnchorStrengthMm * unitsPerMm * params.strengthMult;
    if (hipDepth > 0) {
      features.push({ center: { x: centerX - bboxWidth * 0.4, y: centerY, z: minZ + bboxHeight * 0.1 }, radii: { x: 35*unitsPerMm, y: 35*unitsPerMm, z: 55*unitsPerMm }, depth: hipDepth, direction: -1, falloffPower: 2.2 });
      features.push({ center: { x: centerX + bboxWidth * 0.4, y: centerY, z: minZ + bboxHeight * 0.1 }, radii: { x: 35*unitsPerMm, y: 35*unitsPerMm, z: 55*unitsPerMm }, depth: hipDepth, direction: -1, falloffPower: 2.2 });
    }

    for (let i = 0; i < positions.count; i++) {
      let x = positions.getX(i), y = positions.getY(i), z = positions.getZ(i);
      if (params.mirrorX) x = -x;
      // For Z-up: height is along Z axis
      const heightNorm = Math.max(0, Math.min(1, (z - pelvis.z) / braceHeight));
      x += params.trunkShiftMm * unitsPerMm * heightNorm * 0.8;
      for (const f of features) {
        const dx = (x - f.center.x) / f.radii.x, dy = (y - f.center.y) / f.radii.y, dz = (z - f.center.z) / f.radii.z;
        const d2 = dx*dx + dy*dy + dz*dz;
        if (d2 >= 1) continue;
        const t = Math.pow(1 - d2, f.falloffPower);
        const disp = f.depth * t * f.direction;
        // For Z-up: radial direction is in XY plane
        const axisX = x - pelvis.x, axisY = y - pelvis.y;
        const len = Math.sqrt(axisX*axisX + axisY*axisY) || 1;
        x += (axisX/len) * disp;
        y += (axisY/len) * disp;
      }
      positions.setXYZ(i, x, y, z);
    }
    positions.needsUpdate = true;
    deformed.computeVertexNormals();
    return deformed;
  }, []);

  // Load mesh
  const loadMesh = useCallback(async (url: string, color: number, opacity: number, isBody: boolean = false): Promise<{ mesh: any; baseGeometry: any }> => {
    return new Promise((resolve, reject) => {
      const ext = url.toLowerCase().split('.').pop() || '';
      const createMaterial = () => new THREE.MeshStandardMaterial({
        color, roughness: 0.6, metalness: 0.1, transparent: true, opacity,
        side: THREE.DoubleSide, depthWrite: !isBody, depthTest: true,
      });
      
      if (ext === 'stl') {
        new STLLoader().load(url, (geometry: any) => {
          geometry.center();
          geometry.computeVertexNormals();
          const baseGeometry = geometry.clone();
          const mesh = new THREE.Mesh(geometry, createMaterial());
          // Don't apply fixed rotation - let user adjust with controls
          // mesh.rotation.x = -Math.PI / 2;
          mesh.renderOrder = isBody ? 10 : 1;
          resolve({ mesh, baseGeometry });
        }, undefined, reject);
      } else if (ext === 'glb' || ext === 'gltf') {
        new GLTFLoader().load(url, (gltf: any) => {
          const mesh = gltf.scene;
          let baseGeometry: any = null;
          mesh.traverse((child: any) => {
            if (child.isMesh) {
              child.material = createMaterial();
              child.renderOrder = isBody ? 10 : 1;
              if (!baseGeometry) baseGeometry = child.geometry.clone();
            }
          });
          resolve({ mesh, baseGeometry });
        }, undefined, reject);
      } else reject(new Error(`Unsupported: ${ext}`));
    });
  }, []);

  // Load all meshes
  useEffect(() => {
    if (!threeLoaded || !sceneRef.current) return;
    const scene = sceneRef.current;
    setLoading(true);
    setError(null);
    
    [bodyMeshRef, regularBraceMeshRef, vaseBraceMeshRef].forEach(ref => {
      if (ref.current) { scene.remove(ref.current); ref.current = null; }
    });
    regularBaseGeomRef.current = null;
    vaseBaseGeomRef.current = null;
    
    const loadAll = async () => {
      try {
        const meshes: any[] = [];
        
        if (regularBraceUrl) {
          const { mesh, baseGeometry } = await loadMesh(regularBraceUrl, REGULAR_BRACE_COLOR, 0.9, false);
          regularBraceMeshRef.current = mesh;
          regularBaseGeomRef.current = baseGeometry;
          scene.add(mesh);
          meshes.push(mesh);
        }
        if (vaseBraceUrl) {
          const { mesh, baseGeometry } = await loadMesh(vaseBraceUrl, VASE_BRACE_COLOR, 0.9, false);
          mesh.visible = showVaseBrace;
          vaseBraceMeshRef.current = mesh;
          vaseBaseGeomRef.current = baseGeometry;
          scene.add(mesh);
          meshes.push(mesh);
        }
        if (bodyScanUrl) {
          const { mesh } = await loadMesh(bodyScanUrl, BODY_COLOR, bodyOpacity, true);
          bodyMeshRef.current = mesh;
          scene.add(mesh);
          meshes.push(mesh);
        }
        
        if (meshes.length > 0) {
          const combinedBox = new THREE.Box3();
          meshes.forEach(m => combinedBox.union(new THREE.Box3().setFromObject(m)));
          const size = combinedBox.getSize(new THREE.Vector3());
          const maxDim = Math.max(size.x, size.y, size.z);
          const scale = 350 / maxDim;
          baseScaleRef.current = scale;
          meshes.forEach(m => m.scale.multiplyScalar(scale));
          
          const newBox = new THREE.Box3();
          meshes.forEach(m => newBox.union(new THREE.Box3().setFromObject(m)));
          const center = newBox.getCenter(new THREE.Vector3());
          meshes.forEach(m => m.position.sub(center));
          
          cameraRef.current.position.set(0, 50, 500);
          cameraRef.current.lookAt(0, 0, 0);
        }
        setLoading(false);
      } catch (err) {
        console.error('Failed to load:', err);
        setError('Failed to load 3D models');
        setLoading(false);
      }
    };
    loadAll();
  }, [threeLoaded, bodyScanUrl, regularBraceUrl, vaseBraceUrl, loadMesh, bodyOpacity, showVaseBrace]);

  // Visibility updates
  useEffect(() => { if (bodyMeshRef.current) bodyMeshRef.current.visible = showBody; }, [showBody]);
  useEffect(() => { if (regularBraceMeshRef.current) regularBraceMeshRef.current.visible = showRegularBrace; }, [showRegularBrace]);
  useEffect(() => { if (vaseBraceMeshRef.current) vaseBraceMeshRef.current.visible = showVaseBrace; }, [showVaseBrace]);

  // Body opacity
  useEffect(() => {
    if (!bodyMeshRef.current) return;
    const update = (mat: any) => { mat.opacity = bodyOpacity; mat.needsUpdate = true; };
    bodyMeshRef.current.traverse((c: any) => { if (c.isMesh && c.material) update(c.material); });
    if (bodyMeshRef.current.material) update(bodyMeshRef.current.material);
  }, [bodyOpacity]);

  // Apply position/rotation/scale to braces
  useEffect(() => {
    const applyToBrace = (mesh: any) => {
      if (!mesh) return;
      mesh.position.x = bracePositionX;
      mesh.position.y = bracePositionY;
      mesh.position.z = bracePositionZ;
      // Convert degrees to radians, no fixed offset
      mesh.rotation.x = braceRotationX * Math.PI / 180;
      mesh.rotation.y = braceRotationY * Math.PI / 180;
      mesh.rotation.z = braceRotationZ * Math.PI / 180;
      const base = baseScaleRef.current;
      mesh.scale.set(base * braceScaleX, base * braceScaleY, base * braceScaleZ);
    };
    applyToBrace(regularBraceMeshRef.current);
    applyToBrace(vaseBraceMeshRef.current);
  }, [bracePositionX, bracePositionY, bracePositionZ, braceRotationX, braceRotationY, braceRotationZ, braceScaleX, braceScaleY, braceScaleZ]);

  // Apply position/rotation/scale to body
  useEffect(() => {
    if (!bodyMeshRef.current) return;
    bodyMeshRef.current.position.x = bodyPositionX;
    bodyMeshRef.current.position.y = bodyPositionY;
    bodyMeshRef.current.position.z = bodyPositionZ;
    // Convert degrees to radians, no fixed offset
    bodyMeshRef.current.rotation.x = bodyRotationX * Math.PI / 180;
    bodyMeshRef.current.rotation.y = bodyRotationY * Math.PI / 180;
    bodyMeshRef.current.rotation.z = bodyRotationZ * Math.PI / 180;
    const base = baseScaleRef.current;
    bodyMeshRef.current.scale.set(base * bodyScale, base * bodyScale, base * bodyScale);
  }, [bodyPositionX, bodyPositionY, bodyPositionZ, bodyRotationX, bodyRotationY, bodyRotationZ, bodyScale]);

  // Apply deformation to braces
  useEffect(() => {
    if (!regularBraceMeshRef.current || !regularBaseGeomRef.current) return;
    const deformed = applyDeformation(regularBaseGeomRef.current.clone(), regularParams);
    regularBraceMeshRef.current.traverse((c: any) => { if (c.isMesh) { c.geometry.dispose(); c.geometry = deformed; }});
    if (regularBraceMeshRef.current.geometry) { regularBraceMeshRef.current.geometry.dispose(); regularBraceMeshRef.current.geometry = deformed; }
  }, [regularParams, applyDeformation]);

  useEffect(() => {
    if (!vaseBraceMeshRef.current || !vaseBaseGeomRef.current) return;
    const deformed = applyDeformation(vaseBaseGeomRef.current.clone(), vaseParams);
    vaseBraceMeshRef.current.traverse((c: any) => { if (c.isMesh) { c.geometry.dispose(); c.geometry = deformed; }});
    if (vaseBraceMeshRef.current.geometry) { vaseBraceMeshRef.current.geometry.dispose(); vaseBraceMeshRef.current.geometry = deformed; }
  }, [vaseParams, applyDeformation]);

  // Handlers
  const handleParamsChange = useCallback((params: BraceTransformParams) => {
    if (activeBrace === 'regular') setRegularParams(params);
    else setVaseParams(params);
  }, [activeBrace]);

  const handleSave = useCallback(async () => { console.log('Save not implemented'); }, []);
  
  const handleReset = useCallback(() => {
    const reset = { ...DEFAULT_TRANSFORM_PARAMS, cobbDeg: braceData?.cobb_angles?.MT || braceData?.cobb_angles?.TL || 25 };
    if (activeBrace === 'regular') setRegularParams(reset);
    else setVaseParams(reset);
  }, [activeBrace, braceData?.cobb_angles]);

  const handleResetTransforms = () => {
    setBracePositionX(0); setBracePositionY(0); setBracePositionZ(0);
    setBraceRotationX(0); setBraceRotationY(0); setBraceRotationZ(0);
    setBraceScaleX(1); setBraceScaleY(1); setBraceScaleZ(1);
    setBodyPositionX(0); setBodyPositionY(0); setBodyPositionZ(0);
    setBodyRotationX(0); setBodyRotationY(0); setBodyRotationZ(0);
    setBodyScale(1);
  };

  const hasBodyScan = !!bodyScanUrl;
  const hasBraces = regularBraceUrl || vaseBraceUrl;

  if (!hasBodyScan && !hasBraces) {
    return (
      <div className="pipeline-stage fitting-stage">
        <div className="stage-header">
          <h2>Stage 5: Brace Fitting Inspection</h2>
          <div className="stage-status"><span className="status-badge status-pending">Pending</span></div>
        </div>
        <div className="stage-content">
          <div className="fitting-empty">
            <p>Body scan and braces are required to inspect fitting.</p>
            <p className="hint">Complete Stage 3 (Body Scan) and Stage 4 (Brace Generation) first.</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="pipeline-stage fitting-stage">
      <div className="stage-header">
        <h2>Stage 5: Brace Fitting Inspection</h2>
        <div className="stage-status"><span className="status-badge status-complete">Ready</span></div>
      </div>

      <div className="fitting-layout-3col">
        {/* LEFT PANEL: Position, Rotation, Scale */}
        <div className="fitting-panel left-panel">
          <h3>Transform Controls</h3>
          
          {/* Visibility */}
          <div className="panel-section">
            <h4>Visibility</h4>
            <label className="checkbox-row">
              <input type="checkbox" checked={showBody} onChange={e => setShowBody(e.target.checked)} />
              <span className="color-dot" style={{background:'#f5d0c5'}} />
              <span>Body</span>
            </label>
            <label className="checkbox-row">
              <input type="checkbox" checked={showRegularBrace} onChange={e => setShowRegularBrace(e.target.checked)} disabled={!regularBraceUrl} />
              <span className="color-dot" style={{background:'#4a90d9'}} />
              <span>Regular Brace</span>
            </label>
            <label className="checkbox-row">
              <input type="checkbox" checked={showVaseBrace} onChange={e => setShowVaseBrace(e.target.checked)} disabled={!vaseBraceUrl} />
              <span className="color-dot" style={{background:'#50c878'}} />
              <span>Vase Brace</span>
            </label>
          </div>

          {/* Body Opacity */}
          <div className="panel-section">
            <h4>Body Opacity: {Math.round(bodyOpacity*100)}%</h4>
            <input type="range" min="0" max="100" value={bodyOpacity*100} onChange={e => setBodyOpacity(Number(e.target.value)/100)} />
          </div>

          {/* Brace Position */}
          <div className="panel-section">
            <h4>Brace Position</h4>
            <div className="slider-compact"><span>X</span><input type="range" min="-100" max="100" value={bracePositionX} onChange={e => setBracePositionX(Number(e.target.value))} /><span>{bracePositionX}</span></div>
            <div className="slider-compact"><span>Y</span><input type="range" min="-100" max="100" value={bracePositionY} onChange={e => setBracePositionY(Number(e.target.value))} /><span>{bracePositionY}</span></div>
            <div className="slider-compact"><span>Z</span><input type="range" min="-100" max="100" value={bracePositionZ} onChange={e => setBracePositionZ(Number(e.target.value))} /><span>{bracePositionZ}</span></div>
          </div>

          {/* Brace Rotation */}
          <div className="panel-section">
            <h4>Brace Rotation</h4>
            <div className="slider-compact"><span>X</span><input type="range" min="-180" max="180" value={braceRotationX} onChange={e => setBraceRotationX(Number(e.target.value))} /><span>{braceRotationX}°</span></div>
            <div className="slider-compact"><span>Y</span><input type="range" min="-180" max="180" value={braceRotationY} onChange={e => setBraceRotationY(Number(e.target.value))} /><span>{braceRotationY}°</span></div>
            <div className="slider-compact"><span>Z</span><input type="range" min="-180" max="180" value={braceRotationZ} onChange={e => setBraceRotationZ(Number(e.target.value))} /><span>{braceRotationZ}°</span></div>
          </div>

          {/* Brace Scale */}
          <div className="panel-section">
            <h4>Brace Scale</h4>
            <div className="slider-compact"><span>X</span><input type="range" min="50" max="150" value={braceScaleX*100} onChange={e => setBraceScaleX(Number(e.target.value)/100)} /><span>{braceScaleX.toFixed(2)}</span></div>
            <div className="slider-compact"><span>Y</span><input type="range" min="50" max="150" value={braceScaleY*100} onChange={e => setBraceScaleY(Number(e.target.value)/100)} /><span>{braceScaleY.toFixed(2)}</span></div>
            <div className="slider-compact"><span>Z</span><input type="range" min="50" max="150" value={braceScaleZ*100} onChange={e => setBraceScaleZ(Number(e.target.value)/100)} /><span>{braceScaleZ.toFixed(2)}</span></div>
          </div>

          {/* Body Transform */}
          <div className="panel-section">
            <h4>Body Position</h4>
            <div className="slider-compact"><span>X</span><input type="range" min="-100" max="100" value={bodyPositionX} onChange={e => setBodyPositionX(Number(e.target.value))} /><span>{bodyPositionX}</span></div>
            <div className="slider-compact"><span>Y</span><input type="range" min="-100" max="100" value={bodyPositionY} onChange={e => setBodyPositionY(Number(e.target.value))} /><span>{bodyPositionY}</span></div>
            <div className="slider-compact"><span>Z</span><input type="range" min="-100" max="100" value={bodyPositionZ} onChange={e => setBodyPositionZ(Number(e.target.value))} /><span>{bodyPositionZ}</span></div>
          </div>

          <div className="panel-section">
            <h4>Body Rotation</h4>
            <div className="slider-compact"><span>X</span><input type="range" min="-180" max="180" value={bodyRotationX} onChange={e => setBodyRotationX(Number(e.target.value))} /><span>{bodyRotationX}°</span></div>
            <div className="slider-compact"><span>Y</span><input type="range" min="-180" max="180" value={bodyRotationY} onChange={e => setBodyRotationY(Number(e.target.value))} /><span>{bodyRotationY}°</span></div>
            <div className="slider-compact"><span>Z</span><input type="range" min="-180" max="180" value={bodyRotationZ} onChange={e => setBodyRotationZ(Number(e.target.value))} /><span>{bodyRotationZ}°</span></div>
          </div>

          <div className="panel-section">
            <h4>Body Scale: {bodyScale.toFixed(2)}</h4>
            <input type="range" min="50" max="150" value={bodyScale*100} onChange={e => setBodyScale(Number(e.target.value)/100)} />
          </div>

          <button className="btn-reset-all" onClick={handleResetTransforms}>Reset All Transforms</button>

          {/* View Options */}
          <div className="panel-section">
            <label className="checkbox-row">
              <input type="checkbox" checked={autoRotate} onChange={e => setAutoRotate(e.target.checked)} />
              <span>Auto Rotate</span>
            </label>
          </div>
        </div>

        {/* CENTER: 3D Viewer */}
        <div className="fitting-viewer-container">
          {!threeLoaded ? (
            <div className="fitting-viewer-loading"><div className="spinner"></div><p>Loading 3D viewer...</p></div>
          ) : (
            <>
              <div ref={containerRef} className="fitting-viewer-canvas" />
              {loading && <div className="fitting-viewer-overlay"><div className="spinner"></div><p>Loading models...</p></div>}
              {error && <div className="fitting-viewer-overlay error"><p>{error}</p></div>}
            </>
          )}
        </div>

        {/* RIGHT PANEL: Deformation Sliders (Stage 4 Editor) */}
        <div className="fitting-panel right-panel">
          <h3>Deformation Controls</h3>
          
          {/* Brace Selector */}
          <div className="panel-section">
            <h4>Edit Brace</h4>
            <div className="brace-selector">
              <button className={`brace-select-btn ${activeBrace === 'regular' ? 'active' : ''}`} onClick={() => setActiveBrace('regular')} disabled={!regularBraceUrl}>
                Regular (Blue)
              </button>
              <button className={`brace-select-btn ${activeBrace === 'vase' ? 'active' : ''}`} onClick={() => setActiveBrace('vase')} disabled={!vaseBraceUrl}>
                Vase (Green)
              </button>
            </div>
          </div>

          {/* The Stage 4 Editor */}
          <BraceInlineEditor
            braceType={activeBrace}
            initialParams={activeBrace === 'regular' ? regularParams : vaseParams}
            cobbAngles={braceData?.cobb_angles}
            onParamsChange={handleParamsChange}
            onSave={handleSave}
            onReset={handleReset}
            isModified={false}
            className="fitting-inline-editor"
          />

          {/* Tips */}
          <div className="panel-section tips">
            <h4>Tips</h4>
            <ul>
              <li>Blue areas = brace pushing INTO body</li>
              <li>Increase Cobb angle for more pressure</li>
              <li>Adjust apex to move correction zone</li>
              <li>Use transforms on left to align meshes</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  );
}
