import { useMemo } from 'react';
import * as THREE from 'three';
import { buildLimbGeometry } from './limbGeometry';
import EdgeLines from './EdgeLines';
import { useLabels } from './useViewportLabels';

/**
 * Procedural generic right below-knee prosthetic assembly.
 * Each part is an independent, selectable scene object.
 *
 * Label: "Generic visual measurement model — dimensions must be verified before CAD."
 *
 * Only reliable native materials (meshStandardMaterial / meshBasicMaterial) and
 * native geometry (cylinder, sphere, torus, box, lathe, extrude). No shaders,
 * no custom shader materials, no Drei Html. Labels render in the DOM overlay.
 */

const C = {
  socket: '#3f474f',
  socketEdge: '#717a86',
  liner: '#717a86',
  adapter: '#9aa3ad',
  pylon: '#2a3038',
  clamp: '#c2cad2',
  ankle: '#8a929c',
  foot: '#3f474f',
  footEdge: '#7a8390',
  accent: '#22d3ee',
};

function buildFootGeometry() {
  const w = 48, L = 100, rH = 16, rT = 26;
  const s = new THREE.Shape();
  const x0 = -w / 2, x1 = w / 2, y0 = 0, y1 = L;
  s.moveTo(x0 + rH, y0);
  s.lineTo(x1 - rH, y0);
  s.absarc(x1 - rH, y0 + rH, rH, -Math.PI / 2, 0, false);
  s.lineTo(x1, y1 - rT);
  s.absarc(x1 - rT, y1 - rT, rT, 0, Math.PI / 2, false);
  s.lineTo(x0 + rT, y1);
  s.absarc(x0 + rT, y1 - rT, rT, Math.PI / 2, Math.PI, false);
  s.lineTo(x0, y0 + rH);
  s.absarc(x0 + rH, y0 + rH, rH, Math.PI, 3 * Math.PI / 2, false);
  const g = new THREE.ExtrudeGeometry(s, { depth: 16, bevelEnabled: true, bevelThickness: 2.5, bevelSize: 2.5, bevelSegments: 2, curveSegments: 16 });
  g.translate(0, 0, -8);
  g.rotateX(Math.PI / 2);
  g.computeVertexNormals();
  return g;
}

function StdMat({ color, metalness, roughness, selected, opacity, emissiveBoost = 0.28 }) {
  return (
    <meshStandardMaterial
      color={selected ? '#5a6470' : color}
      metalness={metalness}
      roughness={roughness}
      transparent={opacity < 1}
      opacity={opacity}
      emissive={selected ? C.accent : '#000000'}
      emissiveIntensity={selected ? emissiveBoost : 0}
    />
  );
}

export default function ProstheticAssembly({ stations, selectedId, onSelect, opacity = 1, onPaint }) {
  const socketGeom = useMemo(() => buildLimbGeometry(stations), [stations]);
  const footGeom = useMemo(() => buildFootGeometry(), []);

  const socketBottom = -150;
  const adapterY = socketBottom - 8;
  const pylonTop = adapterY - 9;
  const pylonBottom = pylonTop - 70;
  const clampY = pylonBottom - 7;
  const ankleY = clampY - 9;
  const footY = -267;

  const is = (id) => selectedId === `part-${id}`;
  const pick = (id, label) => (e) => {
    if (onPaint) { e.stopPropagation(); onPaint(e.point); return; }
    e.stopPropagation(); onSelect?.('part', id, { partId: id, label });
  };

  const socketSel = is('socket');
  const residualSel = is('residual');
  const adapterSel = is('adapter');
  const pylonSel = is('pylon');
  const clampSel = is('clamp');
  const ankleSel = is('ankle');
  const footSel = is('foot');

  useLabels([
    { id: 'asm-disclaimer', position: [0, 224, 0], title: 'Generic visual measurement model', subtitle: 'dimensions must be verified before CAD', tone: 'amber' },
  ]);

  return (
    <group>
      {/* Residual limb / liner */}
      <group onClick={pick('residual', 'Residual Limb / Liner')}>
        <mesh position={[0, 172, 0]}>
          <cylinderGeometry args={[25, 34, 52, 32]} />
          <StdMat color={C.liner} metalness={0} roughness={0.92} selected={residualSel} opacity={opacity} />
        </mesh>
        <mesh position={[0, 200, 0]}>
          <sphereGeometry args={[26, 24, 20]} />
          <StdMat color={C.liner} metalness={0} roughness={0.92} selected={residualSel} opacity={opacity} />
        </mesh>
      </group>

      {/* Socket */}
      <mesh
        geometry={socketGeom}
        onClick={pick('socket', 'Socket')}
        onPointerDown={onPaint ? (e) => { e.stopPropagation(); onPaint(e.point); } : undefined}
      >
        <meshStandardMaterial
          color={socketSel ? '#525c68' : C.socket}
          metalness={0.18}
          roughness={0.62}
          transparent={opacity < 1}
          opacity={opacity}
          emissive={socketSel ? C.accent : '#000000'}
          emissiveIntensity={socketSel ? 0.22 : 0}
        />
        <EdgeLines geometry={socketGeom} color={socketSel ? C.accent : C.socketEdge} opacity={opacity * 0.95} />
      </mesh>
      <mesh position={[0, 150, 0]} rotation={[Math.PI / 2, 0, 0]} onClick={pick('socket', 'Socket')} raycast={() => null}>
        <torusGeometry args={[52, 3.2, 14, 56]} />
        <meshStandardMaterial color={socketSel ? C.accent : '#5b6470'} metalness={0.25} roughness={0.5} transparent={opacity < 1} opacity={opacity} emissive={socketSel ? C.accent : '#000000'} emissiveIntensity={socketSel ? 0.3 : 0} />
      </mesh>

      {/* Distal socket adapter */}
      <mesh position={[0, adapterY, 0]} onClick={pick('adapter', 'Distal Socket Adapter')}>
        <cylinderGeometry args={[24, 28, 16, 32]} />
        <StdMat color={C.adapter} metalness={0.85} roughness={0.4} selected={adapterSel} opacity={opacity} />
      </mesh>
      <mesh position={[0, adapterY, 0]} rotation={[Math.PI / 2, 0, 0]} raycast={() => null}>
        <torusGeometry args={[28, 2, 8, 36]} />
        <meshStandardMaterial color={C.accent} emissive={C.accent} emissiveIntensity={0.3} transparent={opacity < 1} opacity={opacity} />
      </mesh>

      {/* Pylon */}
      <mesh position={[0, (pylonTop + pylonBottom) / 2, 0]} onClick={pick('pylon', 'Pylon')}>
        <cylinderGeometry args={[13, 13, 70, 28]} />
        <StdMat color={C.pylon} metalness={0.9} roughness={0.22} selected={pylonSel} opacity={opacity} emissiveBoost={0.3} />
      </mesh>

      {/* Tube clamp */}
      <mesh position={[0, clampY, 0]} onClick={pick('clamp', 'Tube Clamp')}>
        <cylinderGeometry args={[20, 20, 14, 28]} />
        <StdMat color={C.clamp} metalness={0.9} roughness={0.28} selected={clampSel} opacity={opacity} />
      </mesh>
      <mesh position={[19, clampY, 0]} rotation={[0, 0, Math.PI / 2]} raycast={() => null}>
        <cylinderGeometry args={[4, 4, 10, 12]} />
        <meshStandardMaterial color={C.adapter} metalness={0.85} roughness={0.35} transparent={opacity < 1} opacity={opacity} />
      </mesh>
      <mesh position={[-19, clampY, 0]} rotation={[0, 0, Math.PI / 2]} raycast={() => null}>
        <cylinderGeometry args={[4, 4, 10, 12]} />
        <meshStandardMaterial color={C.adapter} metalness={0.85} roughness={0.35} transparent={opacity < 1} opacity={opacity} />
      </mesh>

      {/* Ankle adapter */}
      <mesh position={[0, ankleY, 0]} onClick={pick('ankle', 'Ankle Adapter')}>
        <cylinderGeometry args={[22, 17, 12, 28]} />
        <StdMat color={C.ankle} metalness={0.85} roughness={0.35} selected={ankleSel} opacity={opacity} />
      </mesh>

      {/* Foot */}
      <group position={[0, footY, 0]} onClick={pick('foot', 'Foot')}>
        <mesh geometry={footGeom}>
          <meshStandardMaterial
            color={footSel ? '#525c68' : C.foot}
            metalness={0.2}
            roughness={0.6}
            transparent={opacity < 1}
            opacity={opacity}
            emissive={footSel ? C.accent : '#000000'}
            emissiveIntensity={footSel ? 0.22 : 0}
          />
          <EdgeLines geometry={footGeom} color={footSel ? C.accent : C.footEdge} opacity={opacity * 0.95} />
        </mesh>
      </group>
    </group>
  );
}