import React, { useRef } from 'react';
import * as THREE from 'three';
import { useFrame } from '@react-three/fiber';
import { Text, Grid, Environment } from '@react-three/drei';
import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import SceneCanvas from '../SceneCanvas';
import { useCanvasTheme } from '@/lib/theme';
import type { ShelterCondition, OpeningPosition, ShelterWindAngle } from '@/lib/nbr-tables/table-shelters';

export interface Shelter3DProps {
  condition: ShelterCondition;
  depth: number;
  width: number;
  height: number;
  theta: number;
  backClosure: number;
  leftClosure: number;
  rightClosure: number;
  openingPos: OpeningPosition;
  backRange?: [number, number];
  windAngle?: ShelterWindAngle;
  viewMode: '3d' | 'elevation';
}

const WindArrow: React.FC<{
  start: [number, number, number];
  end: [number, number, number];
  color?: string;
  speed?: number;
}> = ({ start, end, color = '#38bdf8', speed = 1.5 }) => {
  const arrowRef = useRef<THREE.Group>(null);

  const quaternion = React.useMemo(() => {
    const dir = new THREE.Vector3(...end).sub(new THREE.Vector3(...start)).normalize();
    return new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir);
  }, [start, end]);

  useFrame(({ clock, invalidate }) => {
    if (arrowRef.current) {
      const t = (clock.getElapsedTime() * speed) % 1;
      const x = start[0] + (end[0] - start[0]) * t;
      const y = start[1] + (end[1] - start[1]) * t;
      const z = start[2] + (end[2] - start[2]) * t;
      arrowRef.current.position.set(x, y, z);
      invalidate();
    }
  });

  return (
    <group ref={arrowRef} quaternion={quaternion}>
      <mesh>
        <coneGeometry args={[0.25, 0.6, 8]} />
        <meshStandardMaterial color={color} emissive={color} emissiveIntensity={0.6} />
      </mesh>
    </group>
  );
};

function ShelterModel({
  condition: _condition,
  depth,
  width,
  height,
  theta,
  backClosure,
  leftClosure,
  rightClosure,
  openingPos,
  backRange,
  windAngle = 0,
  viewMode,
}: Shelter3DProps) {
  const isElevation = viewMode === 'elevation';

  // Geometria básica
  const halfW = width / 2;
  const halfD = depth / 2;
  const thetaRad = (theta * Math.PI) / 180;
  const slopeRise = depth * Math.tan(thetaRad);

  // Paredes com abertura no topo ou na base (sem caixas/linhas brancas deslocadas)
  const renderWallWithGap = (
    w: number,
    h: number,
    closure: number,
    pos: OpeningPosition,
    rotY = 0,
    position: [number, number, number] = [0, 0, 0],
    customRange?: [number, number]
  ) => {
    if (closure <= 0) return null;

    let op = closure / 100;
    let wallH = h * op;
    let yPos = position[1] + wallH / 2;

    if (customRange && closure < 100) {
      const bottomPct = Math.max(0, Math.min(100, customRange[0])) / 100;
      const topPct = Math.max(0, Math.min(100, customRange[1])) / 100;
      op = Math.max(0.01, topPct - bottomPct);
      wallH = h * op;
      yPos = position[1] + h * bottomPct + wallH / 2;
    } else if (pos === 'top' && closure < 100) {
      // Parede na parte de baixo, fresta no topo
      yPos = position[1] + wallH / 2;
    } else if (pos === 'bottom' && closure < 100) {
      // Parede suspensa na parte superior, vão na base
      yPos = position[1] + h - wallH / 2;
    }

    return (
      <group position={position} rotation={[0, rotY, 0]}>
        <mesh position={[0, yPos - position[1], 0]}>
          <boxGeometry args={[w, wallH, 0.15]} />
          <meshStandardMaterial
            color="#64748b"
            transparent={op < 1}
            opacity={Math.max(0.3, op)}
            roughness={0.4}
          />
        </mesh>
      </group>
    );
  };

  return (
    <group position={[0, -height / 2, 0]}>
      {/* 1. Estrutura Metálica Principal (Pilares e Vigas em Balanço - Tubos Quadrados) */}
      {[-halfW + 0.6, halfW - 0.6].map((xPos, idx) => (
        <group key={`frame-${idx}`} position={[xPos, 0, 0]}>
          {/* Pilar traseiro (lado direito na elevação) */}
          <mesh position={[0, height / 2, halfD - 0.25]}>
            <boxGeometry args={[0.35, height, 0.35]} />
            <meshStandardMaterial color="#cbd5e1" metalness={0.7} roughness={0.3} />
          </mesh>
          {/* Viga horizontal em balanço (TUBO QUAD. 150x150) */}
          <group position={[0, height, 0]} rotation={[thetaRad, 0, 0]}>
            <mesh position={[0, 0, 0]}>
              <boxGeometry args={[0.25, 0.3, depth]} />
              <meshStandardMaterial color="#cbd5e1" metalness={0.7} roughness={0.3} />
            </mesh>
          </group>
        </group>
      ))}

      {/* 2. Cobertura / Marquise */}
      <group position={[0, height, 0]} rotation={[thetaRad, 0, 0]}>
        <mesh position={[0, 0.15, 0]}>
          <boxGeometry args={[width + 0.6, 0.15, depth + 0.4]} />
          <meshStandardMaterial color="#3b82f6" roughness={0.3} metalness={0.4} />
        </mesh>
      </group>

      {/* 3. Fechamentos de Fundo e Laterais (com suporte a fresta/abertura) */}
      {/* Parede de Fundo (Traseira Z = +halfD) */}
      {renderWallWithGap(width, height, backClosure, openingPos, 0, [0, 0, halfD], backRange)}

      {/* Parede Lateral Esquerda (X = -halfW) */}
      {renderWallWithGap(depth, height, leftClosure, 'distributed', Math.PI / 2, [-halfW, 0, 0])}

      {/* Parede Lateral Direita (X = +halfW) */}
      {renderWallWithGap(depth, height, rightClosure, 'distributed', Math.PI / 2, [halfW, 0, 0])}

      {/* 4. Linhas de Corrente e Vetores de Vento (Ilustrativo e Didático) */}
      <group position={[0, 0, 0]} rotation={[0, -((windAngle || 0) * Math.PI) / 180, 0]}>
        {/* Vento de entrada (Barlavento) entrando em direção ao abrigo */}
        <WindArrow start={[0, height * 0.5, -halfD - 4]} end={[0, height * 0.5, -halfD + 1]} color="#38bdf8" speed={1.2} />
        <WindArrow start={[-halfW * 0.5, height * 0.7, -halfD - 4]} end={[-halfW * 0.5, height * 0.7, -halfD + 1]} color="#38bdf8" speed={1.4} />
        <WindArrow start={[halfW * 0.5, height * 0.4, -halfD - 4]} end={[halfW * 0.5, height * 0.4, -halfD + 1]} color="#38bdf8" speed={1.3} />

        {/* Linhas de corrente sobre o telhado */}
        <WindArrow start={[0, height + 1, -halfD - 3]} end={[0, height + slopeRise + 1.5, halfD + 2]} color="#60a5fa" speed={1.6} />

        {/* Fresta na parede de fundo: se houver abertura no topo, mostrar vento escapando pela fresta superior */}
        {backClosure > 0 && backClosure < 100 && (openingPos === 'top' || (backRange && backRange[1] < 98)) && (
          <>
            <WindArrow start={[0, height * 0.85, 0]} end={[0, height * 0.95, halfD + 2.5]} color="#34d399" speed={1.8} />
            <Text position={[0, height + 0.35, halfD]} rotation={[0, Math.PI, 0]} fontSize={0.4} color="#34d399">
              Alívio (Fresta Topo)
            </Text>
          </>
        )}

        {/* Fresta na base */}
        {backClosure > 0 && backClosure < 100 && (openingPos === 'bottom' || (backRange && backRange[0] > 2)) && (
          <>
            <WindArrow start={[0, 0.4, 0]} end={[0, 0.4, halfD + 2.5]} color="#facc15" speed={1.8} />
            <Text position={[0, 1.2, halfD]} rotation={[0, Math.PI, 0]} fontSize={0.4} color="#facc15">
              Vão Livre Inferior
            </Text>
          </>
        )}
      </group>

      {/* Textos Informativos 3D - Virados para quem olha da frente (-Z) */}
      <Text position={[0, height + slopeRise + 0.8, 0]} rotation={[0, Math.PI, 0]} fontSize={0.45} color="#e2e8f0">
        {isElevation ? 'CORTE A-A (Elevação)' : 'Abrigo / Pórtico (NBR 6123)'}
      </Text>
      <Text position={[0, 0.3, -halfD - 1.2]} rotation={[0, Math.PI, 0]} fontSize={0.35} color="#38bdf8">
        {`VENTO ${windAngle === 0 ? 'FRONTAL (0°)' : windAngle === 45 ? 'OBLÍQUO (45°)' : 'LATERAL (90°)'}`}
      </Text>
      <Text position={[0, height + slopeRise + 0.25, 0]} rotation={[0, Math.PI, 0]} fontSize={0.32} color="#f43f5e">
        Arrancamento [+Fz ↑]
      </Text>
      <Text position={[0, height * 0.5, halfD + 1.2]} rotation={[0, Math.PI, 0]} fontSize={0.32} color="#fb923c">
        Empuxo no Fundo [+Fx →]
      </Text>
    </group>
  );
}

export function Shelter3D(props: Shelter3DProps) {
  const theme = useCanvasTheme();
  const isDark = theme === 'dark';
  const { width, depth, height } = props;
  const dist = Math.max(width, depth) * 1.8 + 8;

  return (
    <SceneCanvas
      moduleId="shelter"
      shadows
      gl={{ preserveDrawingBuffer: true, antialias: true }}
      camera={{ position: [dist * 0.75, height * 1.1, -dist * 0.85], fov: 45 }}
      fallback={<div className="flex items-center justify-center h-full text-muted-foreground">3D indisponível</div>}
    >
      <ambientLight intensity={isDark ? 0.4 : 0.7} />
      <directionalLight position={[10, 20, 15]} intensity={isDark ? 1.0 : 1.3} castShadow />
      <ShelterModel {...props} />
      <Grid
        infiniteGrid
        fadeDistance={Math.max(width, depth) * 3}
        sectionColor={isDark ? '#475569' : '#94a3b8'}
        cellColor={isDark ? '#1e293b' : '#cbd5e1'}
        position={[0, -height / 2 - 0.01, 0]}
      />
      <OrbitControls makeDefault minPolarAngle={0} maxPolarAngle={Math.PI / 2 - 0.05} target={[0, 0, 0]} />
      <Environment preset="city" />
    </SceneCanvas>
  );
}

export default Shelter3D;
