import React, { useMemo, useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Slider } from '@/components/ui/slider';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { useWindStore } from '@/store/appStore';
import {
  calculateShelterWind,
  calculateShelterWindAllAngles,
  type ShelterCondition,
  type OpeningPosition,
  type ShelterWindAngle,
} from '@/lib/nbr-tables/table-shelters';
import Shelter3D from '@/components/three/Shelter3D';
import { WindFlowGrid2D } from '@/components/WindFlowGrid2D';
import SceneCapturePanel from '../components/SceneCapturePanel';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { WindParametersSummary } from '@/components/WindParametersSummary';
import { SaveModuleDialog } from '@/components/SaveModuleDialog';
import { exportGenericToPDF, type GenericPDFSection } from '../lib/export-generic-pdf';
import { Eye, Box, Layers, ArrowUpRight, CheckCircle2 } from 'lucide-react';
import { cn } from '@/lib/utils';

const conditionLabels: Record<ShelterCondition, string> = {
  cond1: '1. Estanque 3 lados (Fundo + Lados)',
  cond2: '2. Fundo Fechado + Lados Abertos',
  cond3: '3. Fundo Aberto + Lados Fechados (Túnel)',
  cond4: '4. Totalmente Livre (4 lados abertos)',
};

const ShelterModule: React.FC = () => {
  const { q } = useWindStore();
  const [condition, setCondition] = useState<ShelterCondition>('cond1');
  const [windAngle, setWindAngle] = useState<ShelterWindAngle>(0);
  const [depth, setDepth] = useState(6);
  const [width, setWidth] = useState(10);
  const [height, setHeight] = useState(4.8);
  const [theta, setTheta] = useState(5);
  const [backClosure, setBackClosure] = useState(75);
  const [backRange, setBackRange] = useState<[number, number]>([0, 75]);
  const [leftClosure, setLeftClosure] = useState(100);
  const [rightClosure, setRightClosure] = useState(100);
  const [viewMode, setViewMode] = useState<'3d' | 'elevation'>('3d');

  // Determinação automática da posição da fresta/vão a partir dos cursores (base e topo)
  const bottomGap = backRange[0];
  const topGap = 100 - backRange[1];
  const openingPos: OpeningPosition =
    topGap > 2 && topGap >= bottomGap
      ? 'top'
      : bottomGap > 2 && bottomGap > topGap
      ? 'bottom'
      : 'distributed';

  const handleConditionChange = (cond: ShelterCondition) => {
    setCondition(cond);
    if (cond === 'cond1') {
      setBackRange([0, 100]);
      setBackClosure(100);
      setLeftClosure(100);
      setRightClosure(100);
    } else if (cond === 'cond2') {
      setBackRange([0, 100]);
      setBackClosure(100);
      setLeftClosure(0);
      setRightClosure(0);
    } else if (cond === 'cond3') {
      setBackRange([0, 0]);
      setBackClosure(0);
      setLeftClosure(100);
      setRightClosure(100);
    } else if (cond === 'cond4') {
      setBackRange([0, 0]);
      setBackClosure(0);
      setLeftClosure(0);
      setRightClosure(0);
    }
  };

  const { result, envelope } = useMemo(() => {
    const input = {
      condition,
      depth,
      width,
      height,
      theta,
      backClosure,
      backRange,
      leftClosure,
      rightClosure,
      openingPos,
    };
    return {
      result: calculateShelterWind({ ...input, windAngle }, q),
      envelope: calculateShelterWindAllAngles(input, q),
    };
  }, [condition, q, depth, width, height, theta, backClosure, backRange, leftClosure, rightClosure, openingPos, windAngle]);

  const effAreaRoof = depth * width;
  const effAreaBack = (width * height) * (backClosure / 100);
  const effAreaSideTotal = (depth * height) * ((leftClosure + rightClosure) / 100);

  const handleExportPDF = () => {
    const angleLabel = windAngle === 0 ? '0° (Frontal)' : windAngle === 45 ? '45° (Oblíquo)' : '90° (Lateral)';
    const sections: GenericPDFSection[] = [
      {
        title: 'Geometria, Inclinação e Fechamentos do Abrigo',
        type: 'grid',
        gridItems: [
          { label: 'Comprimento (d / balanço)', value: `${depth.toFixed(1)} m` },
          { label: 'Largura (b)', value: `${width.toFixed(1)} m` },
          { label: 'Altura do Pilar (h)', value: `${height.toFixed(1)} m` },
          { label: 'Inclinação da Cobertura (θ)', value: `${theta}°` },
          { label: 'Condição NBR 6123 (Sec. 6.3)', value: condition },
          { label: 'Fechamento Parede de Fundo', value: `${backClosure}%` },
          { label: 'Fresta Parede de Fundo', value: backRange ? `${backRange[0]}% a ${backRange[1]}%` : 'Sem fresta' },
          { label: 'Fechamento Lateral Esq / Dir', value: `${leftClosure}% / ${rightClosure}%` },
        ],
      },
      {
        title: `Coeficientes Aerodinâmicos e Pressões Líquidas - Direção ${angleLabel}`,
        type: 'grid',
        gridItems: [
          { label: 'Ce Superior (Cobertura - Tab. 24)', value: result.cpeTop },
          { label: 'Cpi Inferior (Sobrepressão sob Telhado)', value: result.cpiBottom },
          { label: 'Cnf Resultante (Ce - Cpi)', value: result.cnfVertical },
          { label: 'Cf Parede de Fundo (Tab. 23 / 6)', value: result.cfBack },
          { label: 'Cf Paredes Laterais', value: result.cfSide },
          { label: 'Alívio por Fresta Superior', value: `${result.reliefPercentage}%` },
        ],
      },
      {
        title: `Pressões Distribuídas por Área de Incidência - Direção ${angleLabel} (kN/m² e kgf/m²)`,
        type: 'grid',
        gridItems: [
          {
            label: 'Pressão na Cobertura (Fz / A_telhado)',
            value: `${(result.forces.fzUp / effAreaRoof).toFixed(2)} kN/m²`,
          },
          {
            label: 'Pressão na Parede Traseira (Fx / A_fundo)',
            value: effAreaBack > 0 ? `${(result.forces.fxBack / effAreaBack).toFixed(2)} kN/m²` : '0.00 kN/m² (0% fechado)',
          },
          {
            label: 'Pressão nas Paredes Laterais (Fy / A_lat)',
            value: effAreaSideTotal > 0 ? `${(result.forces.fySide / effAreaSideTotal).toFixed(2)} kN/m²` : '0.00 kN/m² (0% fechado)',
          },
          {
            label: 'Pressão Dinâmica Base do Vento (q)',
            value: `${q.toFixed(2)} kN/m²`,
          },
          {
            label: 'Área da Cobertura (Telhado)',
            value: `${effAreaRoof.toFixed(1)} m² (100%)`,
          },
          {
            label: 'Áreas Efetivas Parede Fundo / Laterais',
            value: `${effAreaBack.toFixed(1)} m² (${backClosure}%) / ${effAreaSideTotal.toFixed(1)} m² (Esq ${leftClosure}% + Dir ${rightClosure}%)`,
          },
        ],
      },
      {
        title: `Demonstração dos Passos Matemáticos — Pressões Distribuídas por m² (Direção ${angleLabel})`,
        type: 'math-card',
        mathSteps: [
          {
            title: '1. Pressão na Cobertura (Fz / A_telhado)',
            formula: 'p_telhado = q · |Cnf_vertical|   ou   p_telhado = Fz / (d · b)',
            calculation: `${q.toFixed(2)} kN/m² · |${result.cnfVertical}| = ${(result.forces.fzUp / effAreaRoof).toFixed(2)} kN/m²   (onde A_telhado = ${depth.toFixed(1)}m × ${width.toFixed(1)}m = ${effAreaRoof.toFixed(1)}m²)`,
            result: `${(result.forces.fzUp / effAreaRoof).toFixed(2)} kN/m²`,
            note: 'A solicitação de arrancamento atua uniformemente distribuída na projeção horizontal da cobertura.',
          },
          {
            title: '2. Pressão na Parede Traseira (Fx / A_efetiva,fundo)',
            formula: 'p_fundo = q · Cf_parede   ou   p_fundo = Fx / [ (b · h) · (φ_fundo) ]',
            calculation: effAreaBack > 0
              ? `${q.toFixed(2)} kN/m² · ${result.cfBack} = ${(result.forces.fxBack / effAreaBack).toFixed(2)} kN/m²   (área de incidência sólida = ${effAreaBack.toFixed(1)}m² para ${backClosure}% fechado)`
              : `Parede 0% fechada (Sem fechamento traseiro) -> A_efetiva = 0.0 m² e Fx = 0.00 kN`,
            result: effAreaBack > 0 ? `${(result.forces.fxBack / effAreaBack).toFixed(2)} kN/m²` : '0.00 kN/m² (0% fechado)',
            note: 'O coeficiente de força e a área são proporcionais à taxa de fechamento da parede de fundo.',
          },
          {
            title: '3. Pressão nas Paredes Laterais (Fy / A_efetiva,laterais)',
            formula: 'p_lateral = q · Cf_lateral   ou   p_lateral = Fy / [ 2 · (d · h) · (φ_médio) ]',
            calculation: effAreaSideTotal > 0
              ? `${q.toFixed(2)} kN/m² · ${result.cfSide} = ${(result.forces.fySide / effAreaSideTotal).toFixed(2)} kN/m²   (área efetiva = ${effAreaSideTotal.toFixed(1)}m²)`
              : `Sem paredes laterais selecionadas (0% esq + 0% dir) -> A_efetiva = 0.0 m² e Fy = 0.00 kN`,
            result: effAreaSideTotal > 0 ? `${(result.forces.fySide / effAreaSideTotal).toFixed(2)} kN/m²` : '0.00 kN/m² (0% fechado)',
            note: effAreaSideTotal > 0
              ? 'A solicitação lateral é distribuída sobre a área efetiva sólida existente nas paredes esq/dir.'
              : 'Como nenhuma parede lateral foi adicionada (0%), a área de incidência é nula (0,0 m²) e a pressão atuante é zero.',
          },
          {
            title: '4. Pressão Dinâmica Base do Vento (q)',
            formula: 'q = 0,613 · Vk²  [N/m²]   =   0,000613 · Vk²  [kN/m²]   (NBR 6123 Sec. 4.2)',
            calculation: `0,613 · (${Math.sqrt((q * 1000) / 0.613).toFixed(1)} m/s)² / 1000 = ${q.toFixed(2)} kN/m²`,
            result: `${q.toFixed(2)} kN/m²`,
            note: 'Pressão dinâmica de referência calculada com base na velocidade característica Vk no nível superior do pilar.',
          },
        ],
      },
      {
        title: 'Envoltória e Comparativo Normativo — As 3 Incidências de Vento (0° • 45° • 90°)',
        type: 'table',
        tableHeaders: ['Parâmetro / Força', '0° (Frontal)', '45° (Oblíquo)', '90° (Lateral)', 'Envoltória / Crítico'],
        tableRows: [
          [
            'Ce Superior (Cobertura)',
            String(envelope.res0.cpeTop),
            String(envelope.res45.cpeTop),
            String(envelope.res90.cpeTop),
            `Máx: ${Math.min(envelope.res0.cpeTop, envelope.res45.cpeTop, envelope.res90.cpeTop)} (Sucção)`
          ],
          [
            'Cpi Inferior (Sob Telhado)',
            String(envelope.res0.cpiBottom),
            String(envelope.res45.cpiBottom),
            String(envelope.res90.cpiBottom),
            `Máx: +${Math.max(envelope.res0.cpiBottom, envelope.res45.cpiBottom, envelope.res90.cpiBottom).toFixed(2)}`
          ],
          [
            'Cnf Vertical Líquido',
            String(envelope.res0.cnfVertical),
            String(envelope.res45.cnfVertical),
            String(envelope.res90.cnfVertical),
            `Crítico: ${Math.min(envelope.res0.cnfVertical, envelope.res45.cnfVertical, envelope.res90.cnfVertical)}`
          ],
          [
            'Força Vertical Telhado [Fz ↑]',
            `${envelope.res0.forces.fzUp} kN`,
            `${envelope.res45.forces.fzUp} kN`,
            `${envelope.res90.forces.fzUp} kN`,
            `${envelope.criticalUp.value} kN (${envelope.criticalUp.angle}°)`
          ],
          [
            'Empuxo Parede Traseira [Fx →]',
            `${envelope.res0.forces.fxBack} kN`,
            `${envelope.res45.forces.fxBack} kN`,
            `${envelope.res90.forces.fxBack} kN`,
            `${envelope.criticalFx.value} kN (${envelope.criticalFx.angle}°)`
          ],
          [
            'Empuxo Paredes Laterais [Fy ↗]',
            `${envelope.res0.forces.fySide} kN`,
            `${envelope.res45.forces.fySide} kN`,
            `${envelope.res90.forces.fySide} kN`,
            `${envelope.criticalFy.value} kN (${envelope.criticalFy.angle}°)`
          ],
          [
            '  ↳ Pressão Cobertura (kN/m²)',
            `${(envelope.res0.forces.fzUp / effAreaRoof).toFixed(2)} kN/m²`,
            `${(envelope.res45.forces.fzUp / effAreaRoof).toFixed(2)} kN/m²`,
            `${(envelope.res90.forces.fzUp / effAreaRoof).toFixed(2)} kN/m²`,
            `${(envelope.criticalUp.value / effAreaRoof).toFixed(2)} kN/m² (${envelope.criticalUp.angle}°)`
          ],
          [
            '  ↳ Pressão Parede Fundo (kN/m²)',
            effAreaBack > 0 ? `${(envelope.res0.forces.fxBack / effAreaBack).toFixed(2)} kN/m²` : '0.00 kN/m²',
            effAreaBack > 0 ? `${(envelope.res45.forces.fxBack / effAreaBack).toFixed(2)} kN/m²` : '0.00 kN/m²',
            effAreaBack > 0 ? `${(envelope.res90.forces.fxBack / effAreaBack).toFixed(2)} kN/m²` : '0.00 kN/m²',
            effAreaBack > 0 ? `${(envelope.criticalFx.value / effAreaBack).toFixed(2)} kN/m² (${envelope.criticalFx.angle}°)` : '0.00 kN/m²'
          ],
          [
            '  ↳ Pressão Paredes Lat. (kN/m²)',
            effAreaSideTotal > 0 ? `${(envelope.res0.forces.fySide / effAreaSideTotal).toFixed(2)} kN/m²` : '0.00 kN/m²',
            effAreaSideTotal > 0 ? `${(envelope.res45.forces.fySide / effAreaSideTotal).toFixed(2)} kN/m²` : '0.00 kN/m²',
            effAreaSideTotal > 0 ? `${(envelope.res90.forces.fySide / effAreaSideTotal).toFixed(2)} kN/m²` : '0.00 kN/m²',
            effAreaSideTotal > 0 ? `${(envelope.criticalFy.value / effAreaSideTotal).toFixed(2)} kN/m² (${envelope.criticalFy.angle}°)` : '0.00 kN/m²'
          ],
          [
            'Carga Horiz. no Pilar',
            `${envelope.res0.lineLoads.columnLoad} kN/m`,
            `${envelope.res45.lineLoads.columnLoad} kN/m`,
            `${envelope.res90.lineLoads.columnLoad} kN/m`,
            `${envelope.criticalColumnLoad.value} kN/m (${envelope.criticalColumnLoad.angle}°)`
          ],
          [
            'Carga Vert. na Viga',
            `${envelope.res0.lineLoads.beamLoad} kN/m`,
            `${envelope.res45.lineLoads.beamLoad} kN/m`,
            `${envelope.res90.lineLoads.beamLoad} kN/m`,
            `${Math.max(envelope.res0.lineLoads.beamLoad, envelope.res45.lineLoads.beamLoad, envelope.res90.lineLoads.beamLoad).toFixed(2)} kN/m`
          ],
        ],
      },
      {
        title: `Forças Resultantes no Pórtico (${angleLabel}) (kN)`,
        type: 'grid',
        gridItems: [
          { label: 'Força Vertical no Telhado [Fz ↑]', value: `${result.forces.fzUp} kN` },
          { label: 'Empuxo na Parede Traseira [Fx →]', value: `${result.forces.fxBack} kN` },
          { label: 'Empuxo nas Paredes Laterais [Fy ↗]', value: `${result.forces.fySide} kN` },
          { label: 'Força de Atrito no Telhado [F_atrito]', value: `${result.forces.fFriction} kN` },
        ],
      },
      {
        title: `Cargas Lineares para Dimensionamento (${angleLabel}) (kN/m)`,
        type: 'grid',
        gridItems: [
          { label: 'Carga Horizontal no Pilar Traseiro', value: `${result.lineLoads.columnLoad} kN/m` },
          { label: 'Carga Vertical na Viga em Balanço', value: `${result.lineLoads.beamLoad} kN/m` },
        ],
      },
      {
        title: 'Parecer Técnico do Regime Topológico e Aerodinâmico',
        type: 'text',
        content: `${result.statusText} Permeabilidade líquida da parede de fundo: ${100 - backClosure}%. Alívio de arrancamento obtido pela fresta superior: ${result.reliefPercentage}%. O relatório acima apresenta a tabela comparativa das 3 incidências de vento (0°, 45° e 90°) para garantir a verificação da envoltória mais desfavorável conforme a NBR 6123:2023. As cargas lineares calculadas (kN/m) podem ser aplicadas diretamente em softwares de pórtico plano como Ftool, SAP2000 ou CYPE 3D.`,
      },
      {
        title: 'Guia de Aplicação dos Eixos e Resultantes no Croqui',
        type: 'table',
        tableHeaders: ['Eixo / Componente', 'Símbolo', 'Sentido e Aplicação no Croqui', 'Carga Distribuída'],
        tableRows: [
          [
            'Eixo Z (Vertical)',
            'Fz (↑)',
            'Perpendicular ao telhado. Valor (+) indica sucção para cima (arrancamento); (-) indica carga descendente.',
            `${result.lineLoads.beamLoad} kN/m na viga`
          ],
          [
            'Eixo X (Longitudinal)',
            'Fx (→)',
            'Na direção do vento (frente -> fundo). Atua como empuxo horizontal contra a parede traseira.',
            `${result.lineLoads.columnLoad} kN/m no pilar`
          ],
          [
            'Eixo Y (Transversal)',
            'Fy (↗)',
            'Perpendicular ao vento. Atua horizontalmente contra o fechamento das paredes laterais.',
            '—'
          ],
        ],
      },
    ];
    exportGenericToPDF('Abrigo / Pórtico Fechado', sections);
  };

  return (
    <div className="flex flex-col lg:flex-row h-full w-full gap-4 p-4 lg:p-6 bg-muted/30">
      {/* Coluna Esquerda: Controles do Abrigo */}
      <div className="w-full lg:w-80 shrink-0 flex flex-col gap-4 overflow-y-auto pb-8 lg:pb-0">
        <Card className="shadow-sm border-border">
          <CardHeader className="pb-3 flex flex-row items-start justify-between space-y-0 pr-6">
            <div>
              <CardTitle className="text-lg flex items-center gap-2">
                <Layers className="size-5 text-primary" />
                Abrigos e Pórticos
              </CardTitle>
              <CardDescription>Pórticos em balanço (Tab. 23-25 e sec. 6.3).</CardDescription>
            </div>
            <SaveModuleDialog
              moduleType="shelter"
              inputs={{ condition, depth, width, height, theta, backClosure, leftClosure, rightClosure, openingPos, windAngle }}
            />
          </CardHeader>
          <CardContent className="space-y-5">
            <WindParametersSummary />

            <div className="space-y-2">
              <label className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                Condições Topológicas
              </label>
              <div className="flex flex-col gap-1.5">
                {(['cond1', 'cond2', 'cond3', 'cond4'] as ShelterCondition[]).map((c) => (
                  <Button
                    key={c}
                    type="button"
                    variant={condition === c ? 'default' : 'outline'}
                    size="sm"
                    className="h-auto py-2 px-2.5 text-xs text-left justify-start font-normal leading-tight w-full"
                    onClick={() => handleConditionChange(c)}
                  >
                    <CheckCircle2 className={cn("size-3.5 mr-2 shrink-0", condition === c ? "text-primary-foreground" : "text-muted-foreground")} />
                    <span className="truncate">{conditionLabels[c]}</span>
                  </Button>
                ))}
              </div>
            </div>

            <div className="space-y-2 pt-1 border-t">
              <label className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                Incidência do Vento (Direção)
              </label>
              <div className="grid grid-cols-3 gap-1.5">
                {([0, 45, 90] as ShelterWindAngle[]).map((ang) => (
                  <Button
                    key={ang}
                    type="button"
                    variant={windAngle === ang ? 'default' : 'outline'}
                    size="sm"
                    className="h-9 px-1.5 text-xs font-medium flex flex-col items-center justify-center leading-none"
                    onClick={() => setWindAngle(ang)}
                  >
                    <span className="font-bold">{ang}°</span>
                    <span className="text-[10px] opacity-80 mt-0.5">{ang === 0 ? 'Frontal' : ang === 45 ? 'Oblíquo' : 'Lateral'}</span>
                  </Button>
                ))}
              </div>
            </div>

            <div className="space-y-3 pt-1 border-t">
              <label className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                Permeabilidade / Fechamento (%)
              </label>
              <div className="space-y-1.5">
                <div className="flex justify-between items-center text-xs">
                  <span>Parede de Fundo:</span>
                  <span className="font-mono font-medium">
                    {backClosure}% {backRange[0] > 0 || backRange[1] < 100 ? `(Base ${backRange[0]}% | Topo ${100 - backRange[1]}%)` : ''}
                  </span>
                </div>
                <Slider
                  min={0}
                  max={100}
                  step={5}
                  value={backRange}
                  onValueChange={(val) => {
                    if (Array.isArray(val) && val.length === 2) {
                      const [start, end] = val;
                      if (end >= start) {
                        setBackRange([start, end]);
                        setBackClosure(end - start);
                      }
                    }
                  }}
                />
              </div>
              <div className="grid grid-cols-2 gap-3 pt-1">
                <div className="space-y-1">
                  <div className="flex justify-between text-[11px]">
                    <span>Lateral Esq:</span>
                    <span className="font-mono">{leftClosure}%</span>
                  </div>
                  <Slider min={0} max={100} step={10} value={[leftClosure]} onValueChange={(v) => setLeftClosure(v[0])} />
                </div>
                <div className="space-y-1">
                  <div className="flex justify-between text-[11px]">
                    <span>Lateral Dir:</span>
                    <span className="font-mono">{rightClosure}%</span>
                  </div>
                  <Slider min={0} max={100} step={10} value={[rightClosure]} onValueChange={(v) => setRightClosure(v[0])} />
                </div>
              </div>
            </div>

            <div className="space-y-3 pt-1 border-t">
              <label className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                Dimensões e Inclinação
              </label>
              <div className="space-y-2">
                <div className="flex justify-between text-xs">
                  <span>Vão do Balanço (d):</span>
                  <span className="font-mono font-medium">{depth.toFixed(1)} m</span>
                </div>
                <Slider min={2} max={15} step={0.1} value={[depth]} onValueChange={(v) => setDepth(v[0])} />
              </div>
              <div className="space-y-2">
                <div className="flex justify-between text-xs">
                  <span>Altura do Pilar (h):</span>
                  <span className="font-mono font-medium">{height.toFixed(1)} m</span>
                </div>
                <Slider min={2.5} max={12} step={0.2} value={[height]} onValueChange={(v) => setHeight(v[0])} />
              </div>
              <div className="space-y-2">
                <div className="flex justify-between text-xs">
                  <span>Largura do Abrigo (b):</span>
                  <span className="font-mono font-medium">{width.toFixed(1)} m</span>
                </div>
                <Slider min={4} max={40} step={0.2} value={[width]} onValueChange={(v) => setWidth(v[0])} />
              </div>
              <div className="space-y-2">
                <div className="flex justify-between text-xs">
                  <span>Inclinação Cobertura (θ):</span>
                  <span className="font-mono font-medium">{theta}°</span>
                </div>
                <Slider min={0} max={30} step={1} value={[theta]} onValueChange={(v) => setTheta(v[0])} />
              </div>
            </div>
          </CardContent>
        </Card>
      </div>

      <div className="flex-1 flex flex-col min-h-[500px] lg:min-h-0 bg-background rounded-xl border border-border shadow-sm overflow-hidden relative">
        <div className="absolute top-4 left-4 z-10 flex flex-wrap items-center gap-2">
          <Badge variant="secondary" className="bg-primary/10 text-primary border border-primary/20 backdrop-blur-sm font-mono font-bold">
            Vento: {windAngle}° ({windAngle === 0 ? 'Frontal' : windAngle === 45 ? 'Oblíquo' : 'Lateral'})
          </Badge>
          <Badge variant="secondary" className="bg-background/85 text-foreground border border-border backdrop-blur-sm font-mono">
            θ = {theta}°
          </Badge>
          <Badge variant="secondary" className="bg-background/85 text-foreground border border-border backdrop-blur-sm">
            Fundo: {backClosure}% ({openingPos === 'top' ? 'Fresta Topo' : openingPos === 'bottom' ? 'Vão Base' : 'Distrib.'})
          </Badge>
          {result.reliefPercentage > 0 && (
            <Badge className="bg-emerald-600/90 hover:bg-emerald-600 text-white border-none shadow-sm flex items-center gap-1">
              <ArrowUpRight className="size-3.5" />
              Alívio Arrancamento: -{result.reliefPercentage}%
            </Badge>
          )}
          <div className="bg-background/90 border border-border rounded-full p-0.5 shadow-sm flex items-center ml-1">
            <Button size="sm" variant={viewMode === '3d' ? 'default' : 'ghost'} className="h-6 px-2.5 text-xs rounded-full" onClick={() => setViewMode('3d')}>
              <Box className="size-3 mr-1" /> Vista 3D
            </Button>
            <Button size="sm" variant={viewMode === 'elevation' ? 'default' : 'ghost'} className="h-6 px-2.5 text-xs rounded-full" onClick={() => setViewMode('elevation')}>
              <Eye className="size-3 mr-1" /> Corte A-A
            </Button>
          </div>
        </div>

        <div className="absolute top-4 right-4 z-10">
          <EducationalManual type="shelter" params={{ condition, backClosure, openingPos, theta, windAngle }} />
        </div>

        {viewMode === '3d' ? (
          <Shelter3D
            condition={condition}
            depth={depth}
            width={width}
            height={height}
            theta={theta}
            backClosure={backClosure}
            backRange={backRange}
            leftClosure={leftClosure}
            rightClosure={rightClosure}
            openingPos={openingPos}
            windAngle={windAngle}
            viewMode={viewMode}
          />
        ) : (
          <div className="w-full h-full flex items-center justify-center p-6 bg-slate-950 overflow-auto">
            <div className="max-w-4xl w-full">
              <WindFlowGrid2D type="shelter" params={{ condition, backClosure, openingPos, theta, windAngle }} />
            </div>
          </div>
        )}
      </div>

      <div className="w-full lg:w-96 shrink-0 flex flex-col gap-4 overflow-y-auto pb-8 lg:pb-0">
        <Card className="shadow-sm border-border">
          <CardHeader className="pb-4">
            <CardTitle className="text-base flex items-center justify-between">
              Forças ({windAngle}°)
              <Badge variant="secondary" className="font-mono">{result.forces.fzUp.toFixed(1)} kN (Arrancamento)</Badge>
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4 text-sm">
            <div className="space-y-2 border-b pb-3">
              <div className="flex justify-between items-center">
                <span className="text-muted-foreground">F. Vertical [Fz ↑ - Cobertura]</span>
                <span className="font-mono font-bold text-foreground">{result.forces.fzUp.toFixed(2)} kN</span>
              </div>
              <div className="flex justify-between items-center text-xs text-muted-foreground">
                <span>Coeficiente Cnf</span>
                <span className="font-mono">{result.cnfVertical}</span>
              </div>
              <div className="flex justify-between items-center text-[11px] text-muted-foreground/80">
                <span>Pressão (/m²)</span>
                <span className="font-mono">{(result.forces.fzUp / effAreaRoof).toFixed(2)} kN/m² ({(result.forces.fzUp / effAreaRoof * 101.97).toFixed(1)} kgf/m²)</span>
              </div>
            </div>
            <div className="space-y-2 border-b pb-3">
              <div className="flex justify-between items-center">
                <span className="text-muted-foreground">Empuxo Traseiro [Fx → - Parede]</span>
                <span className="font-mono font-bold text-foreground">{result.forces.fxBack.toFixed(2)} kN</span>
              </div>
              <div className="flex justify-between items-center text-xs text-muted-foreground">
                <span>Cf / Estanqueidade</span>
                <span className="font-mono">Cf = {result.cfBack} ({backClosure}%)</span>
              </div>
              <div className="flex justify-between items-center text-[11px] text-muted-foreground/80">
                <span>Pressão (/m²)</span>
                <span className="font-mono">
                  {effAreaBack > 0
                    ? `${(result.forces.fxBack / effAreaBack).toFixed(2)} kN/m² (${(result.forces.fxBack / effAreaBack * 101.97).toFixed(1)} kgf/m²)`
                    : '0.00 kN/m² (0% fechado)'}
                </span>
              </div>
            </div>
            <div className="space-y-1 border-b pb-2">
              <div className="flex justify-between items-center">
                <span className="text-muted-foreground">Empuxo Lateral [Fy ↗ - Paredes]</span>
                <span className="font-mono font-bold text-foreground">{result.forces.fySide.toFixed(2)} kN</span>
              </div>
              <div className="flex justify-between items-center text-[11px] text-muted-foreground/80">
                <span>Pressão (/m²)</span>
                <span className="font-mono">
                  {effAreaSideTotal > 0
                    ? `${(result.forces.fySide / effAreaSideTotal).toFixed(2)} kN/m² (${(result.forces.fySide / effAreaSideTotal * 101.97).toFixed(1)} kgf/m²)`
                    : '0.00 kN/m² (0% fechado)'}
                </span>
              </div>
            </div>
            <div className="flex justify-between items-center pb-2 border-b">
              <span className="text-primary font-medium">Carga no Pilar (Pórtico)</span>
              <span className="font-mono font-bold text-emerald-600 dark:text-emerald-400">{result.lineLoads.columnLoad.toFixed(2)} kN/m</span>
            </div>
            <div className="flex justify-between items-center pb-3 border-b">
              <span className="text-primary font-medium">Carga na Viga (Balanço)</span>
              <span className="font-mono font-bold text-sky-600 dark:text-sky-400">{result.lineLoads.beamLoad.toFixed(2)} kN/m</span>
            </div>

            <div className="pt-1 space-y-2">
              <div className="font-bold text-xs text-primary flex items-center justify-between">
                <span>Envoltória — 3 Incidências (0° • 45° • 90°)</span>
                <Badge variant="outline" className="text-[10px] font-mono">Crítico: {envelope.criticalUp.angle}°</Badge>
              </div>
              <div className="grid grid-cols-4 gap-1 text-[11px] bg-muted/40 p-2.5 rounded-md border">
                <div className="font-semibold text-muted-foreground">Direção</div>
                <div className="font-semibold text-right">Fz (↑)</div>
                <div className="font-semibold text-right">Fx (→)</div>
                <div className="font-semibold text-right">Fy (↗)</div>

                <div className={cn("font-mono", windAngle === 0 && "font-bold text-primary")}>0° Frontal</div>
                <div className="font-mono text-right">{envelope.res0.forces.fzUp.toFixed(1)}</div>
                <div className="font-mono text-right">{envelope.res0.forces.fxBack.toFixed(1)}</div>
                <div className="font-mono text-right">{envelope.res0.forces.fySide.toFixed(1)}</div>

                <div className={cn("font-mono", windAngle === 45 && "font-bold text-primary")}>45° Oblíquo</div>
                <div className="font-mono text-right">{envelope.res45.forces.fzUp.toFixed(1)}</div>
                <div className="font-mono text-right">{envelope.res45.forces.fxBack.toFixed(1)}</div>
                <div className="font-mono text-right">{envelope.res45.forces.fySide.toFixed(1)}</div>

                <div className={cn("font-mono", windAngle === 90 && "font-bold text-primary")}>90° Lateral</div>
                <div className="font-mono text-right">{envelope.res90.forces.fzUp.toFixed(1)}</div>
                <div className="font-mono text-right">{envelope.res90.forces.fxBack.toFixed(1)}</div>
                <div className="font-mono text-right">{envelope.res90.forces.fySide.toFixed(1)}</div>
              </div>
            </div>

            <div className="pt-2 space-y-2">
              <div className="font-bold text-sm text-primary">Parâmetros Adicionais (NBR 6123)</div>
              <div className="grid grid-cols-1 gap-2 bg-muted/30 p-3 rounded-md border text-xs">
                <div className="flex justify-between text-muted-foreground">
                  <span>Permeabilidade (μ):</span>
                  <span className="font-mono font-medium text-foreground">{100 - backClosure}%</span>
                </div>
                <div className="flex justify-between text-muted-foreground">
                  <span>Alívio por Fresta Superior:</span>
                  <span className="font-mono font-medium text-emerald-600 dark:text-emerald-400">{result.reliefPercentage}%</span>
                </div>
                <div className="flex justify-between text-muted-foreground">
                  <span>Força de Atrito (Ff):</span>
                  <span className="font-mono font-medium text-foreground">{result.forces.fFriction.toFixed(2)} kN</span>
                </div>
              </div>
              <p className="text-[11px] text-muted-foreground leading-tight">
                * Para a visualização didática dos esquemas aerodinâmicos e linhas de corrente, utilize a aba <strong>Corte A-A</strong> no painel central.
              </p>
            </div>
          </CardContent>
        </Card>
        <div className="flex justify-center bg-background rounded-xl border border-border shadow-sm p-4">
          <div className="flex flex-col items-end gap-2">
            <ExportMenu onExportPDF={handleExportPDF} />
          </div>
        </div>
        <SceneCapturePanel />
      </div>
    </div>
  );
};

export default ShelterModule;
