import { useRef, useState, forwardRef } from 'react';
import { useFrame, useThree } from '@react-three/fiber';
import { useXRInputSourceState } from '@react-three/xr';
import * as THREE from 'three';
import { Text } from '@react-three/drei';
import { XR3DButton, XR3DPanel } from './XRPanel3D';
import { useModelStore, SCALE_PRESETS } from '@/stores/useModelStore';
import { getBroadcastSource } from '@/lib/webrtc/broadcastSource';

type Tab = 'scene' | 'tools' | 'transform' | 'inspection' | 'share';

interface XRHudInWorldProps {
  freeMove: boolean;
  onToggleFreeMove: () => void;
  placementMode: boolean;
  onTogglePlacement: () => void;
  snapToPlanes: boolean;
  onToggleSnap: () => void;
  allowScale: boolean;
  onToggleAllowScale: () => void;
  liveCode?: string | null;
  liveViewers?: number;
  onStartLive?: () => void;
  onStopLive?: () => void;
}

const POS_STEP = 0.001;
const ROT_STEP = 1;
const SCALE_LABELS = ['1:50', '1:20', '1:10', '1:1'];

const WristToggle = forwardRef<THREE.Group, { open: boolean; onToggle: () => void }>(
  function WristToggle({ open, onToggle }, ref) {
    return (
      <group ref={ref}>
        <mesh position={[0, 0, -0.0005]}>
          <planeGeometry args={[0.064, 0.032]} />
          <meshBasicMaterial color="#3b82f6" transparent opacity={0.6} />
        </mesh>
        <mesh onClick={(e) => { e.stopPropagation(); onToggle(); }}>
          <planeGeometry args={[0.06, 0.028]} />
          <meshBasicMaterial color={open ? '#3b82f6' : '#1a1a1a'} transparent opacity={0.95} />
        </mesh>
        <Text position={[0, 0, 0.001]} fontSize={0.0085} color="#ffffff" anchorX="center" anchorY="middle">
          {open ? '✕ Fechar' : '☰ Menu'}
        </Text>
      </group>
    );
  },
);

export function XRHudInWorld(props: XRHudInWorldProps) {
  const { camera } = useThree();
  const leftCtrl = useXRInputSourceState('controller', 'left');
  const [open, setOpen] = useState(true);
  const [tab, setTab] = useState<Tab>('scene');
  /** When pinned, the panel stays fixed in world space and does NOT follow the head. */
  const [pinned, setPinned] = useState(true);
  /** Forces re-anchor on next frame (used by "trazer" / unpin→pin). */
  const reanchorRequested = useRef(true);

  const panelRef = useRef<THREE.Group>(null);
  const wristRef = useRef<THREE.Group>(null);
  const targetPos = useRef(new THREE.Vector3());
  const targetQuat = useRef(new THREE.Quaternion());
  const lastABtn = useRef(false);

  useFrame(() => {
    // Toggle via left A button (Quest Touch buttons[4])
    const gp = leftCtrl?.inputSource?.gamepad;
    if (gp) {
      const aBtn = gp.buttons[4];
      const pressed = !!aBtn?.pressed;
      if (pressed && !lastABtn.current) setOpen((v) => !v);
      lastABtn.current = pressed;
    }

    // Floating panel:
    //  • If pinned and already anchored once → don't move it (fixed in space).
    //  • If unpinned → continuously follow head with damping.
    //  • On (re)anchor request → snap target once and stop.
    if (panelRef.current && open) {
      const fwd = new THREE.Vector3(0, -0.05, -0.7).applyQuaternion(camera.quaternion);
      const wantPos = new THREE.Vector3().copy(camera.position).add(fwd);
      const euler = new THREE.Euler().setFromQuaternion(camera.quaternion, 'YXZ');
      const wantQuat = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, euler.y, 0, 'YXZ'));

      if (reanchorRequested.current) {
        targetPos.current.copy(wantPos);
        targetQuat.current.copy(wantQuat);
        panelRef.current.position.copy(wantPos);
        panelRef.current.quaternion.copy(wantQuat);
        reanchorRequested.current = false;
      } else if (!pinned) {
        targetPos.current.copy(wantPos);
        targetQuat.current.copy(wantQuat);
        panelRef.current.position.lerp(targetPos.current, 0.12);
        panelRef.current.quaternion.slerp(targetQuat.current, 0.18);
      }
      // pinned + already anchored → leave panel where it is.
    }

    // Wrist toggle follows left controller
    if (wristRef.current) {
      const ctrlObj = leftCtrl?.object;
      if (ctrlObj) {
        ctrlObj.updateMatrixWorld();
        const p = new THREE.Vector3().setFromMatrixPosition(ctrlObj.matrixWorld);
        const q = new THREE.Quaternion().setFromRotationMatrix(ctrlObj.matrixWorld);
        const offset = new THREE.Vector3(0, 0.06, 0.02).applyQuaternion(q);
        wristRef.current.position.copy(p).add(offset);
        wristRef.current.quaternion.copy(q);
        wristRef.current.visible = true;
      } else {
        wristRef.current.visible = false;
      }
    }
  });

  return (
    <>
      <WristToggle ref={wristRef} open={open} onToggle={() => setOpen((v) => !v)} />
      {open && (
        <group ref={panelRef}>
          <FloatingPanel
            tab={tab}
            setTab={setTab}
            pinned={pinned}
            onTogglePin={() => setPinned((v) => !v)}
            onRecenter={() => { reanchorRequested.current = true; }}
            {...props}
          />
        </group>
      )}
    </>
  );
}

function FloatingPanel({ tab, setTab, ...p }: { tab: Tab; setTab: (t: Tab) => void } & XRHudInWorldProps) {
  const tabs: { id: Tab; label: string; icon: string }[] = [
    { id: 'scene', label: 'Cena', icon: '🧩' },
    { id: 'tools', label: 'Ferram.', icon: '🛠' },
    { id: 'transform', label: 'Mover', icon: '↔' },
    { id: 'inspection', label: 'Inspeção', icon: '✓' },
    { id: 'share', label: 'Compart.', icon: '📡' },
  ];
  const W = 0.5, H = 0.36;
  return (
    <XR3DPanel size={[W, H]}>
      <Text position={[-W / 2 + 0.012, H / 2 - 0.018, 0.002]} fontSize={0.011} color="#3b82f6"
            anchorX="left" anchorY="middle">
        TrackSteelXR · HUD AR
      </Text>
      <Text position={[W / 2 - 0.012, H / 2 - 0.018, 0.002]} fontSize={0.008} color="#94a3b8"
            anchorX="right" anchorY="middle">
        Botão A (esq) abre/fecha
      </Text>

      <group position={[0, H / 2 - 0.045, 0.001]}>
        {tabs.map((t, i) => (
          <XR3DButton key={t.id}
            position={[-W / 2 + 0.045 + i * 0.092, 0, 0]} size={[0.085, 0.022]}
            label={t.label} icon={t.icon} active={tab === t.id}
            onClick={() => setTab(t.id)} fontSize={0.0075} />
        ))}
      </group>

      <group position={[0, -0.012, 0.001]}>
        {tab === 'scene' && <SceneTab />}
        {tab === 'tools' && <ToolsTab {...p} />}
        {tab === 'transform' && <TransformTab />}
        {tab === 'inspection' && <InspectionTab />}
        {tab === 'share' && <ShareTab {...p} />}
      </group>
    </XR3DPanel>
  );
}

function SceneTab() {
  const models = useModelStore((s) => s.models);
  const activeId = useModelStore((s) => s.activeModelId);
  const setActive = useModelStore((s) => s.setActiveModel);
  const toggleVisible = useModelStore((s) => s.toggleModelVisible);
  const toggleLocked = useModelStore((s) => s.toggleModelLocked);
  const remove = useModelStore((s) => s.removeModel);
  const duplicate = useModelStore((s) => s.duplicateModel);

  if (models.length === 0) {
    return (
      <Text fontSize={0.011} color="#94a3b8" anchorX="center" anchorY="middle" maxWidth={0.45}>
        Nenhuma peça na cena. Saia do AR para carregar arquivos no Viewer.
      </Text>
    );
  }

  return (
    <group>
      <Text position={[-0.24, 0.11, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
        Toque no nome para tornar a peça ativa
      </Text>
      {models.slice(0, 5).map((m, i) => {
        const y = 0.085 - i * 0.04;
        const isActive = m.id === activeId;
        return (
          <group key={m.id} position={[0, y, 0]}>
            <mesh position={[-0.235, 0, 0.001]}>
              <circleGeometry args={[0.005, 16]} />
              <meshBasicMaterial color={m.color} />
            </mesh>
            <group onClick={(e) => { e.stopPropagation(); setActive(m.id); }}>
              <mesh position={[-0.11, 0, 0]}>
                <planeGeometry args={[0.22, 0.026]} />
                <meshBasicMaterial color={isActive ? '#1e3a8a' : '#1a1a1a'} transparent opacity={0.85} />
              </mesh>
              <Text position={[-0.215, 0, 0.001]} fontSize={0.0085}
                    color={isActive ? '#ffffff' : '#cbd5e1'} anchorX="left" anchorY="middle"
                    maxWidth={0.2}>
                {m.fileName}
              </Text>
            </group>
            <XR3DButton position={[0.04, 0, 0]} size={[0.04, 0.024]}
              label={m.visible ? '👁' : '⊘'} fontSize={0.012}
              onClick={() => toggleVisible(m.id)} />
            <XR3DButton position={[0.085, 0, 0]} size={[0.04, 0.024]}
              label={m.locked ? '🔒' : '🔓'} fontSize={0.012}
              onClick={() => toggleLocked(m.id)} />
            <XR3DButton position={[0.13, 0, 0]} size={[0.04, 0.024]}
              label="⎘" fontSize={0.012}
              onClick={() => duplicate(m.id)} />
            <XR3DButton position={[0.175, 0, 0]} size={[0.04, 0.024]}
              label="✕" fontSize={0.012} color="#dc2626"
              onClick={() => remove(m.id)} />
          </group>
        );
      })}
    </group>
  );
}

function ToolsTab(p: XRHudInWorldProps) {
  const opacity = useModelStore((s) => s.opacity);
  const setOpacity = useModelStore((s) => s.setOpacity);
  const renderMode = useModelStore((s) => s.renderMode);
  const setRenderMode = useModelStore((s) => s.setRenderMode);
  const showGrid = useModelStore((s) => s.showGrid);
  const setShowGrid = useModelStore((s) => s.setShowGrid);
  const measureMode = useModelStore((s) => s.measureMode);
  const setMeasureMode = useModelStore((s) => s.setMeasureMode);
  const scaleRatio = useModelStore((s) => s.scaleRatio);
  const setScaleRatio = useModelStore((s) => s.setScaleRatio);

  return (
    <group>
      <Text position={[-0.24, 0.11, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Render</Text>
      <XR3DButton position={[-0.16, 0.085, 0]} size={[0.075, 0.022]} label="Sólido"
        active={renderMode === 'solid'} onClick={() => setRenderMode('solid')} />
      <XR3DButton position={[-0.08, 0.085, 0]} size={[0.075, 0.022]} label="Wire"
        active={renderMode === 'wireframe'} onClick={() => setRenderMode('wireframe')} />
      <XR3DButton position={[0.0, 0.085, 0]} size={[0.075, 0.022]} label="Bordas"
        active={renderMode === 'edges'} onClick={() => setRenderMode('edges')} />

      <Text position={[-0.24, 0.05, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">Toggles</Text>
      <XR3DButton position={[-0.16, 0.025, 0]} size={[0.075, 0.022]} label={`Grid ${showGrid ? 'ON' : 'OFF'}`}
        active={showGrid} onClick={() => setShowGrid(!showGrid)} />
      <XR3DButton position={[-0.08, 0.025, 0]} size={[0.075, 0.022]} label={`Medir ${measureMode ? 'ON' : 'OFF'}`}
        active={measureMode} onClick={() => setMeasureMode(!measureMode)} />
      <XR3DButton position={[0.0, 0.025, 0]} size={[0.075, 0.022]} label={`Snap ${p.snapToPlanes ? 'ON' : 'OFF'}`}
        active={p.snapToPlanes} onClick={p.onToggleSnap} />
      <XR3DButton position={[0.08, 0.025, 0]} size={[0.075, 0.022]} label={`Escala ${p.allowScale ? 'ON' : 'OFF'}`}
        active={p.allowScale} onClick={p.onToggleAllowScale} />
      <XR3DButton position={[0.16, 0.025, 0]} size={[0.075, 0.022]}
        label={p.placementMode ? 'Posic…' : 'Reposic.'}
        active={p.placementMode} onClick={p.onTogglePlacement} />

      <Text position={[-0.24, -0.02, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
        Opacidade {Math.round(opacity * 100)}%
      </Text>
      <XR3DButton position={[-0.16, -0.045, 0]} size={[0.05, 0.022]} label="−25%"
        onClick={() => setOpacity(Math.max(0, opacity - 0.25))} />
      <XR3DButton position={[-0.105, -0.045, 0]} size={[0.05, 0.022]} label="−5%"
        onClick={() => setOpacity(Math.max(0, opacity - 0.05))} />
      <XR3DButton position={[-0.05, -0.045, 0]} size={[0.05, 0.022]} label="+5%"
        onClick={() => setOpacity(Math.min(1, opacity + 0.05))} />
      <XR3DButton position={[0.005, -0.045, 0]} size={[0.05, 0.022]} label="+25%"
        onClick={() => setOpacity(Math.min(1, opacity + 0.25))} />
      <XR3DButton position={[0.06, -0.045, 0]} size={[0.05, 0.022]} label="100%"
        onClick={() => setOpacity(1)} />

      <Text position={[-0.24, -0.085, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
        Escala {scaleRatio.label}
      </Text>
      {SCALE_LABELS.map((lbl, i) => {
        const preset = SCALE_PRESETS.find((sp) => sp.label === lbl)!;
        return (
          <XR3DButton key={lbl}
            position={[-0.16 + i * 0.06, -0.11, 0]} size={[0.055, 0.022]} label={lbl}
            active={scaleRatio.label === lbl}
            onClick={() => setScaleRatio(preset)} />
        );
      })}
    </group>
  );
}

function TransformTab() {
  const fineTuning = useModelStore((s) => s.fineTuning);
  const setFineTuning = useModelStore((s) => s.setFineTuning);
  const reset = useModelStore((s) => s.resetFineTuning);

  const Row = ({
    label, axis, isRot, y,
  }: { label: string; axis: 'posX'|'posY'|'posZ'|'rotX'|'rotY'|'rotZ'; isRot: boolean; y: number }) => {
    const step = isRot ? ROT_STEP : POS_STEP;
    const val = fineTuning[axis];
    const display = isRot ? `${val.toFixed(1)}°` : `${(val * 1000).toFixed(1)}mm`;
    return (
      <group position={[0, y, 0]}>
        <Text position={[-0.235, 0, 0]} fontSize={0.009} color="#cbd5e1" anchorX="left" anchorY="middle">
          {label}
        </Text>
        <XR3DButton position={[-0.10, 0, 0]} size={[0.04, 0.024]} label="−−"
          onClick={() => setFineTuning({ [axis]: val - step * 10 })} />
        <XR3DButton position={[-0.05, 0, 0]} size={[0.04, 0.024]} label="−"
          onClick={() => setFineTuning({ [axis]: val - step })} />
        <Text position={[0.0, 0, 0]} fontSize={0.009} color="#3b82f6" anchorX="center" anchorY="middle">
          {display}
        </Text>
        <XR3DButton position={[0.05, 0, 0]} size={[0.04, 0.024]} label="+"
          onClick={() => setFineTuning({ [axis]: val + step })} />
        <XR3DButton position={[0.10, 0, 0]} size={[0.04, 0.024]} label="++"
          onClick={() => setFineTuning({ [axis]: val + step * 10 })} />
      </group>
    );
  };

  return (
    <group>
      <Row label="Pos X" axis="posX" isRot={false} y={0.105} />
      <Row label="Pos Y" axis="posY" isRot={false} y={0.075} />
      <Row label="Pos Z" axis="posZ" isRot={false} y={0.045} />
      <Row label="Rot X" axis="rotX" isRot={true} y={0.005} />
      <Row label="Rot Y" axis="rotY" isRot={true} y={-0.025} />
      <Row label="Rot Z" axis="rotZ" isRot={true} y={-0.055} />
      <XR3DButton position={[0, -0.105, 0]} size={[0.12, 0.026]} label="↺ Reset" onClick={reset} />
    </group>
  );
}

function InspectionTab() {
  const checklist = useModelStore((s) => s.checklist);
  const setStatus = useModelStore((s) => s.setChecklistItemStatus);
  return (
    <group>
      <Text position={[-0.24, 0.11, 0]} fontSize={0.008} color="#94a3b8" anchorX="left">
        Checklist de inspeção
      </Text>
      {checklist.map((item, i) => {
        const y = 0.075 - i * 0.045;
        const color = item.status === 'approved' ? '#22c55e'
          : item.status === 'rejected' ? '#dc2626' : '#94a3b8';
        return (
          <group key={item.id} position={[0, y, 0]}>
            <mesh position={[-0.235, 0, 0]}>
              <circleGeometry args={[0.005, 16]} />
              <meshBasicMaterial color={color} />
            </mesh>
            <Text position={[-0.22, 0, 0]} fontSize={0.009} color="#e5e7eb"
                  anchorX="left" anchorY="middle" maxWidth={0.18}>
              {item.label}
            </Text>
            <XR3DButton position={[0.06, 0, 0]} size={[0.05, 0.024]} label="✓ OK" color="#16a34a"
              active={item.status === 'approved'} onClick={() => setStatus(item.id, 'approved')} />
            <XR3DButton position={[0.115, 0, 0]} size={[0.05, 0.024]} label="✗ NOK" color="#dc2626"
              active={item.status === 'rejected'} onClick={() => setStatus(item.id, 'rejected')} />
          </group>
        );
      })}
    </group>
  );
}

function ShareTab(p: XRHudInWorldProps) {
  const isLive = !!p.liveCode;
  return (
    <group>
      <Text position={[0, 0.105, 0]} fontSize={0.012} color={isLive ? '#22c55e' : '#94a3b8'}
            anchorX="center" anchorY="middle">
        {isLive ? '● TRANSMITINDO AO VIVO' : '○ Transmissão desligada'}
      </Text>
      {isLive ? (
        <>
          <Text position={[0, 0.07, 0]} fontSize={0.010} color="#94a3b8" anchorX="center" anchorY="middle">
            Código da sala
          </Text>
          <Text position={[0, 0.04, 0]} fontSize={0.024} color="#3b82f6" anchorX="center" anchorY="middle">
            {p.liveCode}
          </Text>
          <Text position={[0, -0.005, 0]} fontSize={0.010} color="#cbd5e1" anchorX="center" anchorY="middle">
            {p.liveViewers ?? 0} espectador(es) conectado(s)
          </Text>
          <Text position={[0, -0.04, 0]} fontSize={0.008} color="#64748b" anchorX="center" anchorY="middle"
                maxWidth={0.45}>
            Os espectadores veem o ponto de vista 3D do operador, sem a câmera real (privacidade).
          </Text>
          <XR3DButton position={[0, -0.09, 0]} size={[0.18, 0.028]}
            label="✕ Encerrar transmissão" color="#dc2626"
            onClick={() => p.onStopLive?.()} />
        </>
      ) : (
        <>
          <Text position={[0, 0.04, 0]} fontSize={0.010} color="#cbd5e1" anchorX="center" anchorY="middle"
                maxWidth={0.45}>
            Inicie uma transmissão WebRTC para que cliente/supervisor acompanhem ao vivo (até 5 viewers, link público).
          </Text>
          <XR3DButton position={[0, -0.04, 0]} size={[0.22, 0.03]}
            label="📡 Iniciar transmissão" color="#3b82f6"
            onClick={() => p.onStartLive?.()} />
          <Text position={[0, -0.09, 0]} fontSize={0.008} color="#64748b" anchorX="center" anchorY="middle"
                maxWidth={0.45}>
            {getBroadcastSource() ? '✓ Mirror opaco ativo' : 'Mirror será criado ao iniciar'}
          </Text>
        </>
      )}
    </group>
  );
}
