import { useEffect, useMemo, useRef, useState } from 'react';
import { X, RefreshCw, Scissors } from 'lucide-react';
import * as THREE from 'three';
import { Button } from '@/components/ui/button';
import { Slider } from '@/components/ui/slider';
import { Switch } from '@/components/ui/switch';
import { useModelStore } from '@/stores/useModelStore';
import { getAllModelLocalGroups } from '@/lib/modelTransforms';

type Axis = 'x' | 'y' | 'z';

interface AxisRange { min: number; max: number; }

function computeBoundsByAxis(): Record<Axis, AxisRange> | null {
  const groups = getAllModelLocalGroups();
  if (groups.length === 0) return null;
  const box = new THREE.Box3();
  let has = false;
  for (const g of groups) {
    g.updateWorldMatrix(true, true);
    const b = new THREE.Box3().setFromObject(g);
    if (Number.isFinite(b.min.x) && Number.isFinite(b.max.x)) {
      if (!has) { box.copy(b); has = true; } else box.union(b);
    }
  }
  if (!has) return null;
  return {
    x: { min: box.min.x, max: box.max.x },
    y: { min: box.min.y, max: box.max.y },
    z: { min: box.min.z, max: box.max.z },
  };
}

const AXIS_COLOR: Record<Axis, string> = {
  x: 'text-red-400',
  y: 'text-emerald-400',
  z: 'text-sky-400',
};

const AXIS_LABEL: Record<Axis, string> = { x: 'X', y: 'Y', z: 'Z' };

export function SectionCutPanel() {
  const open = useModelStore((s) => s.sectionPanelOpen);
  const opacity = useModelStore((s) => s.sectionPanelOpacity);
  const setOpen = useModelStore((s) => s.setSectionPanelOpen);
  const setOpacity = useModelStore((s) => s.setSectionPanelOpacity);

  const enabled = useModelStore((s) => s.sectionEnabled);
  const invert = useModelStore((s) => s.sectionInvert);
  const level = useModelStore((s) => s.sectionLevel);
  const setSectionEnabled = useModelStore((s) => s.setSectionEnabled);
  const setSectionInvert = useModelStore((s) => s.setSectionInvert);
  const setSectionLevel = useModelStore((s) => s.setSectionLevel);

  const activeModelId = useModelStore((s) => s.activeModelId);

  const [bounds, setBounds] = useState<Record<Axis, AxisRange> | null>(null);

  // Compute bounds when the panel opens or active model changes.
  useEffect(() => {
    if (!open) return;
    // Defer one tick to let scene finish updating world matrices.
    const id = setTimeout(() => setBounds(computeBoundsByAxis()), 50);
    return () => clearTimeout(id);
  }, [open, activeModelId]);

  // Drag-to-move logic.
  const [pos, setPos] = useState<{ x: number; y: number }>({ x: 16, y: 16 });
  const dragRef = useRef<{ ox: number; oy: number; sx: number; sy: number } | null>(null);
  useEffect(() => {
    const onMove = (e: PointerEvent) => {
      if (!dragRef.current) return;
      setPos({
        x: Math.max(8, dragRef.current.sx + (e.clientX - dragRef.current.ox)),
        y: Math.max(8, dragRef.current.sy + (e.clientY - dragRef.current.oy)),
      });
    };
    const onUp = () => { dragRef.current = null; };
    window.addEventListener('pointermove', onMove);
    window.addEventListener('pointerup', onUp);
    return () => {
      window.removeEventListener('pointermove', onMove);
      window.removeEventListener('pointerup', onUp);
    };
  }, []);

  const recompute = () => setBounds(computeBoundsByAxis());

  if (!open) return null;

  return (
    <div
      className="absolute z-30 w-[320px] rounded-lg border bg-card shadow-2xl backdrop-blur-md"
      style={{ right: pos.x, top: pos.y, opacity }}
    >
      {/* Header (drag handle) */}
      <div
        className="flex cursor-move items-center justify-between gap-2 border-b px-3 py-2 select-none"
        onPointerDown={(e) => {
          dragRef.current = { ox: e.clientX, oy: e.clientY, sx: pos.x, sy: pos.y };
        }}
      >
        <div className="flex items-center gap-2">
          <Scissors className="h-3.5 w-3.5 text-primary" />
          <span className="font-mono text-xs font-semibold uppercase tracking-widest text-foreground">
            Cortes de Seção
          </span>
        </div>
        <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setOpen(false)}>
          <X className="h-3.5 w-3.5" />
        </Button>
      </div>

      {/* Window opacity */}
      <div className="border-b px-3 py-2">
        <div className="mb-1 flex items-center justify-between">
          <span className="font-mono text-[10px] uppercase tracking-widest text-muted-foreground">
            Opacidade da janela
          </span>
          <span className="font-mono text-[10px] text-foreground">{Math.round(opacity * 100)}%</span>
        </div>
        <Slider
          value={[Math.round(opacity * 100)]}
          min={20}
          max={100}
          step={5}
          onValueChange={([v]) => setOpacity(v / 100)}
        />
      </div>

      {/* Per-axis controls */}
      <div className="space-y-3 px-3 py-3">
        {(['x', 'y', 'z'] as Axis[]).map((axis) => {
          const range = bounds?.[axis];
          const minMM = range ? range.min * 1000 : 0;
          const maxMM = range ? range.max * 1000 : 100;
          const valMM = level[axis] * 1000;
          const disabled = !range;
          return (
            <div key={axis} className="rounded-md border bg-muted/30 p-2.5">
              <div className="mb-2 flex items-center justify-between">
                <div className="flex items-center gap-2">
                  <span className={`font-mono text-sm font-bold ${AXIS_COLOR[axis]}`}>
                    {AXIS_LABEL[axis]}
                  </span>
                  <Switch
                    checked={enabled[axis]}
                    onCheckedChange={(c) => setSectionEnabled(axis, c)}
                    disabled={disabled}
                  />
                </div>
                <label className="flex items-center gap-1.5">
                  <span className="font-mono text-[10px] text-muted-foreground">Inverter</span>
                  <Switch
                    checked={invert[axis]}
                    onCheckedChange={(c) => setSectionInvert(axis, c)}
                    disabled={disabled || !enabled[axis]}
                  />
                </label>
              </div>

              <div className="mb-1 flex items-center justify-between">
                <span className="font-mono text-[10px] text-muted-foreground">
                  {disabled ? '— sem peça' : `${minMM.toFixed(0)} … ${maxMM.toFixed(0)} mm`}
                </span>
                <span className="font-mono text-[10px] text-foreground">
                  {disabled ? '—' : `${valMM.toFixed(1)} mm`}
                </span>
              </div>

              <Slider
                value={[range ? Math.min(maxMM, Math.max(minMM, valMM)) : 0]}
                min={minMM}
                max={maxMM}
                step={Math.max(0.1, (maxMM - minMM) / 1000)}
                onValueChange={([v]) => setSectionLevel(axis, v / 1000)}
                disabled={disabled || !enabled[axis]}
              />

              <div className="mt-2 grid grid-cols-3 gap-1">
                <Button
                  variant="ghost"
                  size="sm"
                  className="h-6 font-mono text-[10px]"
                  disabled={disabled || !enabled[axis]}
                  onClick={() => range && setSectionLevel(axis, range.min)}
                >
                  Min
                </Button>
                <Button
                  variant="ghost"
                  size="sm"
                  className="h-6 font-mono text-[10px]"
                  disabled={disabled || !enabled[axis]}
                  onClick={() => range && setSectionLevel(axis, (range.min + range.max) / 2)}
                >
                  Centro
                </Button>
                <Button
                  variant="ghost"
                  size="sm"
                  className="h-6 font-mono text-[10px]"
                  disabled={disabled || !enabled[axis]}
                  onClick={() => range && setSectionLevel(axis, range.max)}
                >
                  Max
                </Button>
              </div>
            </div>
          );
        })}
      </div>

      <div className="border-t px-3 py-2">
        <Button variant="outline" size="sm" className="w-full gap-2 h-8" onClick={recompute}>
          <RefreshCw className="h-3.5 w-3.5" />
          <span className="font-mono text-[11px]">Recalcular limites</span>
        </Button>
      </div>
    </div>
  );
}
