import { Grid, Environment } from '@react-three/drei';
import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import SceneCanvas from '../SceneCanvas';
import { WindArrow } from './WindArrow';
import { useCanvasTheme } from '@/lib/theme';
import type { PipeDef } from '../../lib/modules/piperack';
import FallbackDiagram from '../FallbackDiagram';

export interface Piperack3DInput {
  width: number;
  height: number;
  elevation: number;
  spacing: number;
  numFrames: number;
  pipes: PipeDef[];
  phiTotal: number;
  eta: number;
}

function PiperackModel({
  width,
  height,
  elevation,
  spacing,
  numFrames,
  pipes,
  phiTotal,
}: Piperack3DInput) {
  const theme = useCanvasTheme();
  const isDark = theme === 'dark';
  
  const halfW = width / 2;
  const rackTop = elevation + height / 2;

  const steelColor = isDark ? '#94a3b8' : '#64748b';
  const pipeColors = ['#ef4444', '#3b82f6', '#f59e0b', '#10b981', '#8b5cf6'];

  // Gera os pórticos longitudinais (as fileiras de colunas)
  const frames = [];
  const totalSpacing = spacing * (numFrames > 1 ? numFrames - 1 : 0);
  const zOffset = totalSpacing / 2;

  for (let i = 0; i < numFrames; i++) {
    const z = -zOffset + i * spacing;
    
    // Desenha apenas 2 colunas nas extremidades da largura do pórtico (conforme solicitado pelo usuário)
    const numCols = 2;
    for (let c = 0; c < numCols; c++) {
      const colX = -halfW + (c / (numCols - 1)) * width;
      frames.push(
        <mesh key={`col-${i}-${c}`} position={[colX, rackTop / 2, z]} receiveShadow castShadow>
          <boxGeometry args={[0.3, rackTop, 0.3]} />
          <meshStandardMaterial color={steelColor} metalness={0.6} roughness={0.4} />
        </mesh>
      );
    }

    // Viga Longitudinal da fileira (representando a face reticulada do pórtico)
    frames.push(
      <mesh key={`beam-${i}`} position={[0, elevation, z]} receiveShadow castShadow>
        <boxGeometry args={[width, height, 0.3]} />
        {/* Opacidade ajustada para atingir 90% quando a solidez for 1.0 */}
        <meshStandardMaterial color={steelColor} metalness={0.6} roughness={0.4} transparent opacity={Math.max(0.1, Math.min(0.9, phiTotal * 0.9))} depthWrite={false} />
      </mesh>
    );
  }


  // Gera as tubulações correndo longitudinalmente (ao longo de X)
  // Agrupa tubos pela mesma elevação para evitar colisões e distribuí-los lado a lado (ao longo de Z)
  const pipeMeshes: any[] = [];
  const groups: Record<number, {pipe: PipeDef, idx: number}[]> = {};
  
  pipes.forEach((pipe, idx) => {
    // Arredondamos a elevação para agrupar valores muito próximos
    const key = Math.round(pipe.elevationOffset * 100) / 100;
    if (!groups[key]) groups[key] = [];
    groups[key].push({pipe, idx});
  });

  Object.values(groups).forEach(group => {
    const gap = 0.2; // 20cm de espaçamento entre tubos na mesma elevação
    const totalDiam = group.reduce((sum, item) => sum + item.pipe.diameter, 0);
    const totalGroupWidth = totalDiam + gap * (group.length - 1);
    
    // Inicia a distribuição centralizada em Z=0
    let currentZ = -totalGroupWidth / 2;
    
    group.forEach((item) => {
      const { pipe, idx } = item;
      const zPos = currentZ + pipe.diameter / 2;
      currentZ += pipe.diameter + gap;
      
      const yPos = (elevation - height/2) + pipe.elevationOffset + pipe.diameter/2;
      const color = pipeColors[idx % pipeColors.length];

      pipeMeshes.push(
        <mesh key={`pipe-${pipe.id}`} position={[0, yPos, zPos]} rotation={[0, 0, Math.PI / 2]} receiveShadow castShadow>
          <cylinderGeometry args={[pipe.diameter / 2, pipe.diameter / 2, width + 1, 16]} />
          <meshStandardMaterial color={color} metalness={0.3} roughness={0.2} />
        </mesh>
      );
    });
  });

  return (
    <group>
      {frames}
      {pipeMeshes}
      
      {/* Vento batendo lateralmente (transversal ao Pipe-rack) */}
      <WindArrow
        direction={[0, 0, 1]}
        target={[0, elevation, zOffset + 2]}
        />
    </group>
  );
}

export function Piperack3D(props: Piperack3DInput) {
  const isDark = useCanvasTheme() === 'dark';

  const fallback = (
    <FallbackDiagram
      type="piperack"
      props={props}
    />
  );

  return (
    <SceneCanvas moduleId="piperack" fallback={fallback}>
      <ambientLight intensity={isDark ? 0.3 : 0.6} />
      <directionalLight position={[10, 15, 10]} intensity={isDark ? 1 : 1.5} castShadow shadow-bias={-0.001} />
      <Environment preset="city" />

      <PiperackModel {...props} />

      <Grid
        args={[40, 40]}
        position={[0, -0.01, 0]}
        cellColor={isDark ? '#334155' : '#cbd5e1'}
        sectionColor={isDark ? '#475569' : '#94a3b8'}
        fadeDistance={30}
      />
      <OrbitControls
        minPolarAngle={0}
        maxPolarAngle={Math.PI / 2 - 0.05}
        minDistance={5}
        maxDistance={80}
        target={[0, props.elevation / 2, 0]}
      />
    </SceneCanvas>
  );
}
