import * as THREE from 'three';

// Example measurement stations for the generic visual model.
// Values are fictional visual test data — never manufacturing geometry.
const DEFAULT_STATIONS = [
  { height: 0, width: 26, depth: 24, name: 'Bottom Boundary' },
  { height: 50, width: 30, depth: 28, name: 'Pylon Diameter' },
  { height: 110, width: 84, depth: 72, name: 'Socket Distal Station' },
  { height: 180, width: 92, depth: 80, name: 'Socket Mid Station' },
  { height: 240, width: 78, depth: 68, name: 'Socket Upper Station' },
  { height: 300, width: 62, depth: 56, name: 'Top Boundary' },
];

export function normalizeStations(stations) {
  if (!stations || stations.length === 0) {
    return DEFAULT_STATIONS.map(s => ({ ...s, fictional: true, hasValue: true }));
  }
  return [...stations]
    .sort((a, b) => (a.height_from_origin_mm ?? a.height ?? 0) - (b.height_from_origin_mm ?? b.height ?? 0))
    .map(s => {
      const w = s.total_width_mm || ((s.max_medial_mm || 0) + (s.max_lateral_mm || 0));
      const d = s.total_depth_mm || ((s.max_anterior_mm || 0) + (s.max_posterior_mm || 0));
      const hasValue = !!(w && w > 0) && !!(d && d > 0);
      return {
        height: s.height_from_origin_mm ?? s.height ?? 0,
        width: hasValue ? w : (w || 60),
        depth: hasValue ? d : (d || 60),
        name: s.station_name || '',
        uuid: s.uuid,
        fictional: false,
        hasValue,
      };
    });
}

export function buildLimbGeometry(stations, segments = 48) {
  const sorted = normalizeStations(stations);
  if (sorted.length < 2) return new THREE.CylinderGeometry(40, 55, 300, segments);

  const positions = [];
  const indices = [];

  for (const s of sorted) {
    for (let i = 0; i <= segments; i++) {
      const angle = (i / segments) * Math.PI * 2;
      positions.push((s.width / 2) * Math.cos(angle), s.height, (s.depth / 2) * Math.sin(angle));
    }
  }

  for (let r = 0; r < sorted.length - 1; r++) {
    for (let i = 0; i < segments; i++) {
      const a = r * (segments + 1) + i;
      const b = a + 1;
      const c = (r + 1) * (segments + 1) + i;
      const d = c + 1;
      indices.push(a, c, b, b, c, d);
    }
  }

  const bottomCenter = positions.length / 3;
  positions.push(0, sorted[0].height, 0);
  for (let i = 0; i < segments; i++) indices.push(bottomCenter, i + 1, i);

  const topCenter = positions.length / 3;
  positions.push(0, sorted[sorted.length - 1].height, 0);
  const topRingStart = (sorted.length - 1) * (segments + 1);
  for (let i = 0; i < segments; i++) indices.push(topCenter, topRingStart + i, topRingStart + i + 1);

  const geometry = new THREE.BufferGeometry();
  geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
  geometry.setIndex(indices);
  geometry.computeVertexNormals();

  const minHeight = sorted[0].height;
  const maxHeight = sorted[sorted.length - 1].height;
  geometry.translate(0, -(minHeight + maxHeight) / 2, 0);

  return geometry;
}

export function modelHeight(stations) {
  const sorted = normalizeStations(stations);
  return sorted[sorted.length - 1].height - sorted[0].height || 300;
}