import { useMemo } from 'react';
import { Grid, Environment, Text } from '@react-three/drei';
import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
import { WindArrow } from './WindArrow';
import { useCanvasTheme } from '@/lib/theme';

export interface Bridge3DInput {
  /** Maior vão Lₚ (m) */
  lp: number;
  /** Largura do tabuleiro B (m) */
  width: number;
  /** Altura do tabuleiro z (m) */
  deckHeight: number;
  /** Altura equivalente H_eq (m) — soma de áreas expostas por metro */
  heg: number;
  /** Coeficiente de arrasto Cx (adimensional) */
  cx: number;
  /** Coeficiente de sustentação Cz (adimensional) */
  cz: number;
  /** Força de arrasto por unidade de comprimento Fx (kN/m) */
  fxPerLength: number;
  /** Força de sustentação por unidade de comprimento Fz (kN/m) */
  fzPerLength: number;
  /** Ângulo de ataque do vento (graus) */
  alpha: number;
}

function BridgeModel({
  lp,
  width,
  deckHeight,
  heg,
  cx,
  alpha,
}: Bridge3DInput) {
  const theme = useCanvasTheme();
  const isDark = theme === 'dark';
  
  const halfL = lp / 2;
  const halfW = width / 2;
  const deckThickness = Math.max(heg, 0.8);
  const deckY = deckHeight;

  // Cor do tabuleiro baseada em Cx
  const deckColor = useMemo(() => {
    const intensity = Math.min(1, Math.abs(cx) / 3);
    const hue = 200 - intensity * 60;
    const l = isDark ? (60 - intensity * 8) : (50 - intensity * 8);
    return new THREE.Color(`hsl(${hue}, ${55 + intensity * 30}%, ${l}%)`);
  }, [cx, isDark]);

  // Pilar heights: posicionar 3 pilares ao longo do vão
  const pillarHeights = useMemo(() => [deckY - 0.5, deckY - 0.5, deckY - 0.5], [deckY]);
  const barrierColor = isDark ? '#cbd5e1' : '#94a3b8';
  const pillarColor = isDark ? '#94a3b8' : '#64748b';

  return (
    <group>
      {/* Tabuleiro (deck) */}
      <mesh position={[0, deckY, 0]} castShadow receiveShadow>
        <boxGeometry args={[lp, deckThickness, width]} />
        <meshStandardMaterial color={deckColor} roughness={0.5} />
      </mesh>

      {/* Guarda-rodas/barreira lateral */}
      <mesh position={[0, deckY + deckThickness / 2 + 0.3, halfW - 0.15]} castShadow>
        <boxGeometry args={[lp, 0.5, 0.1]} />
        <meshStandardMaterial color={barrierColor} roughness={0.7} />
      </mesh>
      <mesh position={[0, deckY + deckThickness / 2 + 0.3, -halfW + 0.15]} castShadow>
        <boxGeometry args={[lp, 0.5, 0.1]} />
        <meshStandardMaterial color={barrierColor} roughness={0.7} />
      </mesh>

      {/* Pilares (3 ao longo do comprimento) */}
      {pillarHeights.map((h, i) => {
        const x = i === 0 ? -halfL + halfL * 0.3 : i === 1 ? 0 : halfL - halfL * 0.3;
        return (
          <mesh key={`pillar-${i}`} position={[x, h / 2, 0]} castShadow receiveShadow>
            <boxGeometry args={[1.5, h, 1.5]} />
            <meshStandardMaterial color={pillarColor} roughness={0.7} />
          </mesh>
        );
      })}

      {/* Solo / água */}
      <mesh position={[0, -0.5, 0]} rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
        <planeGeometry args={[lp * 1.6, width * 3]} />
        <meshStandardMaterial color="#60a5fa" opacity={0.4} transparent roughness={0.3} />
      </mesh>

      {/* Seta de Vento (bate no meio do tabuleiro) */}
      <WindArrow
        target={[0, deckY + deckThickness / 2, 0]}
        direction={[0, Math.sin((alpha * Math.PI) / 180), Math.cos((alpha * Math.PI) / 180)]}
        scale={4}
      />
      <Text
        position={[0, deckY + deckThickness + 1.5, 0]}
        fontSize={1.2}
        color={isDark ? "#93c5fd" : "#1e40af"}
        anchorX="center"
        anchorY="bottom"
      >
        Lp={lp}m | B={width}m | Cx={cx.toFixed(2)}
      </Text>
    </group>
  );
}

export default function Bridge3DViewer(input: Bridge3DInput) {
  const theme = useCanvasTheme();
  const isDark = theme === 'dark';
  const { lp, deckHeight, width } = input;
  const dist = Math.max(lp * 0.6, deckHeight * 2);

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

  return (
    <SceneCanvas moduleId="ponte"
      shadows
      gl={{ preserveDrawingBuffer: true, antialias: true }}
      camera={{ position: [dist * 0.8, deckHeight + width, dist], fov: 45 }}
      fallback={fallback}
    >
      <ambientLight intensity={0.6} />
      <directionalLight position={[lp, deckHeight * 3, width * 3]} intensity={1.2} castShadow shadow-mapSize-width={1024} shadow-mapSize-height={1024} />
      <BridgeModel {...input} />
      <Grid 
        infiniteGrid 
        fadeDistance={lp * 0.5} 
        sectionColor={isDark ? "#475569" : "#94a3b8"} 
        cellColor={isDark ? "#1e293b" : "#cbd5e1"} 
        position={[0, -0.01, 0]} 
      />
      <OrbitControls makeDefault minPolarAngle={0} maxPolarAngle={Math.PI / 2 - 0.05} />
      <Environment preset="city" />
    </SceneCanvas>
  );
}