import { Eye, Grid3X3, Ruler, Trash2, Camera, LayoutGrid, Palette, Box, Move3D, Undo2, MousePointerClick, EyeOff, Focus, Download, Square, Scissors } from 'lucide-react';
import { Slider } from '@/components/ui/slider';
import { Button } from '@/components/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { useModelStore } from '@/stores/useModelStore';
import { ScaleSelector } from '@/components/ScaleSelector';
import { useCallback } from 'react';
import { toast } from 'sonner';
import { exportObjectsAsGLB } from '@/lib/exportSelectionGLB';
import * as THREE from 'three';
import { elementKey, sceneRef } from '@/components/three/ModelViewer';

const WIRE_COLORS = [
  { label: 'Ciano (radiante)', value: '#00f3ff' },
  { label: 'Vermelho', value: '#ef4444' },
  { label: 'Verde', value: '#22c55e' },
  { label: 'Azul', value: '#3b82f6' },
  { label: 'Amarelo', value: '#eab308' },
  { label: 'Laranja', value: '#f97316' },
  { label: 'Branco', value: '#e2e8f0' },
  { label: 'Cinza', value: '#8899aa' },
];

export function ViewerControls() {
  const {
    opacity, setOpacity, renderMode, setRenderMode,
    measureMode, setMeasureMode, measurements, clearMeasurements, undoLastMeasurement,
    measurePoints, addScreenshot,
    showGrid, setShowGrid,
    wireframeColor, setWireframeColor,
    wireframeThickness, setWireframeThickness,
    edgeThresholdAngle, setEdgeThresholdAngle,
    positionMode, setPositionMode,
    activeModelId, models,
    selectionMode, setSelectionMode,
    selectedElementKeys, hiddenElementKeys, isolatedElementKeys,
    hideSelectedElements, isolateSelectedElements, showAllElements, clearElementSelection,
    cameraMode, setCameraMode,
    gridCalibMode, setGridCalibMode, setGridAutoFollow,
    sectionPanelOpen, setSectionPanelOpen, sectionEnabled, resetSection,
  } = useModelStore();
  const sectionActive = sectionEnabled.x || sectionEnabled.y || sectionEnabled.z;
  const activeModel = models.find(m => m.id === activeModelId);
  const hasSelection = selectedElementKeys.size > 0;
  const hasHiddenOrIsolated = hiddenElementKeys.size > 0 || isolatedElementKeys !== null;

  const handleExportSelection = useCallback(async () => {
    if (!activeModel || selectedElementKeys.size === 0) return;
    const scene = sceneRef.current;
    if (!scene) { toast.error('Cena 3D não disponível'); return; }
    const objects: THREE.Object3D[] = [];
    const collect = (root: THREE.Object3D) => {
      const modelId = root.userData?.modelId as string | undefined;
      if (!modelId) { root.children.forEach(collect); return; }
      root.traverse((el) => {
        if (!el.userData?.ifcElement) return;
        if (selectedElementKeys.has(elementKey(modelId, el))) objects.push(el);
      });
    };
    collect(scene);
    if (objects.length === 0) {
      toast.error('Não foi possível localizar elementos selecionados. Use IFC para seleção persistente.');
      return;
    }
    const base = activeModel.fileName.replace(/\.(glb|gltf|ifc|obj|stl)$/i, '');
    await exportObjectsAsGLB(objects, `${base}_selecao_${objects.length}elem.glb`);
    toast.success(`GLB exportado com ${objects.length} elemento(s)`);
  }, [activeModel, selectedElementKeys]);

  const handleScreenshot = useCallback(() => {
    const canvas = document.querySelector('canvas');
    if (!canvas) {
      toast.error('Canvas não encontrado');
      return;
    }
    const dataUrl = canvas.toDataURL('image/png');
    addScreenshot(dataUrl);
    toast.success('Screenshot capturado!');
  }, [addScreenshot]);

  return (
    <div className="absolute bottom-4 left-4 z-10 flex items-end gap-3 flex-wrap">
      {/* Opacity slider */}
      <div className="rounded-lg border bg-card/90 backdrop-blur-sm p-3 shadow-lg w-56">
        <div className="flex items-center justify-between mb-2">
          <div className="flex items-center gap-2">
            <Eye className="h-3.5 w-3.5 text-primary" />
            <span className="font-mono text-xs text-muted-foreground">Opacidade</span>
          </div>
          <span className="font-mono text-xs text-foreground">{Math.round(opacity * 100)}%</span>
        </div>
        <Slider
          value={[opacity * 100]}
          min={0}
          max={100}
          step={1}
          onValueChange={([v]) => setOpacity(v / 100)}
        />
      </div>

      {/* Grid toggle */}
      <Button
        variant={showGrid ? 'default' : 'outline'}
        size="sm"
        className="gap-2 h-9"
        onClick={() => setShowGrid(!showGrid)}
      >
        <LayoutGrid className="h-3.5 w-3.5" />
        <span className="font-mono text-xs">Grid</span>
      </Button>

      {/* Grid calibration: click a face on the piece to anchor the grid there */}
      <Button
        variant={gridCalibMode ? 'default' : 'outline'}
        size="sm"
        className="gap-2 h-9"
        disabled={!activeModelId}
        onClick={() => {
          const next = !gridCalibMode;
          setGridCalibMode(next);
          if (next) {
            setGridAutoFollow(false);
            toast.info('Calibrar Grid: clique numa face da peça');
          } else {
            toast.dismiss();
          }
        }}
        title="Posiciona o grid na altura de uma face da peça"
      >
        <LayoutGrid className="h-3.5 w-3.5" />
        <span className="font-mono text-xs">
          {gridCalibMode ? 'Clique na face…' : 'Calibrar Grid'}
        </span>
      </Button>

      {/* Section cuts (X/Y/Z clipping planes) */}
      <div className="flex items-end gap-1.5">
        <Button
          variant={sectionPanelOpen || sectionActive ? 'default' : 'outline'}
          size="sm"
          className="gap-2 h-9"
          onClick={() => setSectionPanelOpen(!sectionPanelOpen)}
          disabled={!activeModelId}
          title="Cortes de seção em X / Y / Z"
        >
          <Scissors className="h-3.5 w-3.5" />
          <span className="font-mono text-xs">
            Cortes{sectionActive ? ' •' : ''}
          </span>
        </Button>
        {sectionActive && (
          <Button
            variant="ghost"
            size="icon"
            className="h-9 w-9"
            onClick={() => { resetSection(); toast.success('Cortes resetados'); }}
            title="Resetar todos os cortes"
          >
            <Trash2 className="h-3.5 w-3.5 text-destructive" />
          </Button>
        )}
      </div>

      {/* Scale presets */}
      <ScaleSelector />


      <Button
        variant={renderMode === 'edges' ? 'default' : 'outline'}
        size="sm"
        className="gap-2 h-9"
        onClick={() => setRenderMode(renderMode === 'edges' ? 'solid' : 'edges')}
      >
        <Box className="h-3.5 w-3.5" />
        <span className="font-mono text-xs">
          {renderMode === 'edges' ? 'Bordas' : 'Sólido'}
        </span>
      </Button>

      {/* Camera projection toggle (Ortho ⇄ Persp) */}
      <Button
        variant="outline"
        size="sm"
        className="gap-2 h-9"
        onClick={() => setCameraMode(cameraMode === 'ortho' ? 'persp' : 'ortho')}
        title={cameraMode === 'ortho'
          ? 'Vista ortogonal (CAD) — clique para perspectiva'
          : 'Vista em perspectiva — clique para ortogonal'}
      >
        {cameraMode === 'ortho'
          ? <Square className="h-3.5 w-3.5" />
          : <Box className="h-3.5 w-3.5" />}
        <span className="font-mono text-xs">
          {cameraMode === 'ortho' ? 'Ortogonal' : 'Perspectiva'}
        </span>
      </Button>


      {/* Edges color/thickness/threshold popover */}
      {renderMode === 'edges' && (
        <Popover>
          <PopoverTrigger asChild>
            <Button variant="outline" size="sm" className="gap-2 h-9">
              <Palette className="h-3.5 w-3.5" />
              <div className="h-3 w-3 rounded-full border border-muted-foreground/30" style={{ backgroundColor: wireframeColor }} />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-56 space-y-3" side="top" align="start">
            <div>
              <span className="font-mono text-xs text-muted-foreground">Cor das Linhas</span>
              <div className="mt-2 flex flex-wrap gap-2">
                {WIRE_COLORS.map((c) => (
                  <button
                    key={c.value}
                    className={`h-6 w-6 rounded-full border-2 transition-all ${wireframeColor === c.value ? 'border-primary scale-110' : 'border-muted-foreground/30'}`}
                    style={{ backgroundColor: c.value }}
                    onClick={() => setWireframeColor(c.value)}
                    title={c.label}
                  />
                ))}
              </div>
            </div>
            <div>
              <div className="flex items-center justify-between mb-1">
                <span className="font-mono text-xs text-muted-foreground">Espessura</span>
                <span className="font-mono text-xs text-foreground">{wireframeThickness.toFixed(1)}</span>
              </div>
              <Slider
                value={[wireframeThickness]}
                min={0.5}
                max={5}
                step={0.5}
                onValueChange={([v]) => setWireframeThickness(v)}
              />
            </div>
            {renderMode === 'edges' && (
              <div>
                <div className="flex items-center justify-between mb-1">
                  <span className="font-mono text-xs text-muted-foreground">Ângulo Limite</span>
                  <span className="font-mono text-xs text-foreground">{edgeThresholdAngle}°</span>
                </div>
                <Slider
                  value={[edgeThresholdAngle]}
                  min={1}
                  max={45}
                  step={1}
                  onValueChange={([v]) => setEdgeThresholdAngle(v)}
                />
              </div>
            )}
          </PopoverContent>
        </Popover>
      )}
      {/* Posicionar (manual mouse placement) */}
      <Button
        variant={positionMode ? 'default' : 'outline'}
        size="sm"
        className="gap-2 h-9"
        onClick={() => setPositionMode(!positionMode)}
        disabled={!activeModelId}
        title="Esquerdo: mover · Shift+Esq: profundidade · Meio (roda): girar no próprio eixo · Direito: rotação livre · Shift+Dir: rotZ"
      >
        <Move3D className="h-3.5 w-3.5" />
        <span className="font-mono text-xs">
          {positionMode
            ? `Posicionando${activeModel ? ` · ${activeModel.fileName.slice(0, 14)}` : ''}`
            : 'Posicionar'}
        </span>
      </Button>

      {/* Measure tool */}
      <div className="flex items-end gap-1.5">
        <Button
          variant={measureMode ? 'default' : 'outline'}
          size="sm"
          className="gap-2 h-9"
          onClick={() => setMeasureMode(!measureMode)}
          title="Clique para marcar pontos · Esc desfaz ponto pendente · Z desfaz última medição"
        >
          <Ruler className="h-3.5 w-3.5" />
          <span className="font-mono text-xs">
            {measureMode
              ? measurePoints.length === 0
                ? 'Ponto A…'
                : 'Ponto B…'
              : 'Medir'}
          </span>
        </Button>

        {(measurePoints.length > 0 || measurements.length > 0) && (
          <Button
            variant="ghost"
            size="icon"
            className="h-9 w-9"
            onClick={undoLastMeasurement}
            title="Desfazer (Z)"
          >
            <Undo2 className="h-3.5 w-3.5 text-muted-foreground" />
          </Button>
        )}

        {measurements.length > 0 && (
          <Button
            variant="ghost"
            size="icon"
            className="h-9 w-9"
            onClick={clearMeasurements}
            title="Limpar medições"
          >
            <Trash2 className="h-3.5 w-3.5 text-destructive" />
          </Button>
        )}
      </div>

      {/* Selection cluster */}
      <div className="flex items-end gap-1.5">
        <Button
          variant={selectionMode ? 'default' : 'outline'}
          size="sm"
          className="gap-2 h-9"
          onClick={() => setSelectionMode(!selectionMode)}
          disabled={!activeModelId}
          title="Clique nos elementos do modelo para selecionar (viga, chapa…)"
        >
          <MousePointerClick className="h-3.5 w-3.5" />
          <span className="font-mono text-xs">
            {selectionMode
              ? hasSelection ? `${selectedElementKeys.size} sel.` : 'Selecionar…'
              : 'Selecionar'}
          </span>
        </Button>

        {hasSelection && (
          <>
            <Button variant="ghost" size="icon" className="h-9 w-9" onClick={hideSelectedElements} title="Esconder selecionados">
              <EyeOff className="h-3.5 w-3.5 text-muted-foreground" />
            </Button>
            <Button variant="ghost" size="icon" className="h-9 w-9" onClick={isolateSelectedElements} title="Isolar selecionados (esconder o resto)">
              <Focus className="h-3.5 w-3.5 text-primary" />
            </Button>
            <Button variant="ghost" size="icon" className="h-9 w-9" onClick={handleExportSelection} title="Exportar selecionados como GLB">
              <Download className="h-3.5 w-3.5 text-primary" />
            </Button>
            <Button variant="ghost" size="icon" className="h-9 w-9" onClick={clearElementSelection} title="Limpar seleção">
              <Undo2 className="h-3.5 w-3.5 text-muted-foreground" />
            </Button>
          </>
        )}

        {hasHiddenOrIsolated && (
          <Button variant="ghost" size="sm" className="h-9 gap-1.5" onClick={showAllElements} title="Mostrar todos os elementos">
            <Eye className="h-3.5 w-3.5" />
            <span className="font-mono text-xs">Mostrar tudo</span>
          </Button>
        )}
      </div>


      {/* Screenshot */}
      <Button
        variant="outline"
        size="sm"
        className="gap-2 h-9"
        onClick={handleScreenshot}
      >
        <Camera className="h-3.5 w-3.5" />
        <span className="font-mono text-xs">Capturar</span>
      </Button>
    </div>
  );
}
