import { useEffect, useRef, useCallback, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Upload, Glasses, CheckCircle, XCircle, Loader2, Box, Package } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useModelStore } from '@/stores/useModelStore';
import { toast } from 'sonner';
import { supabase } from '@/integrations/supabase/client';
import { getSupportedExtension, convertToGLB, ACCEPTED_EXTENSIONS } from '@/lib/convertToGLB';
import { convertIFCtoGLB } from '@/lib/convertIFC';
import { validateModelFile } from '@/lib/validateModelFile';
import { CloudLoader } from '@/components/CloudLoader';
import { SceneModelList } from '@/components/SceneModelList';
import { RecentFilesList } from '@/components/RecentFilesList';
import { addRecentFile } from '@/lib/recentFiles';
import { Switch } from '@/components/ui/switch';
import { Label } from '@/components/ui/label';

const Index = () => {
  const navigate = useNavigate();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [loadingDemoIFC, setLoadingDemoIFC] = useState(false);
  const [loadingDemoCotovelo, setLoadingDemoCotovelo] = useState(false);
  
  const [converting, setConverting] = useState(false);
  const { model, addModel, models, maxModels, xrSupported, setXrSupported } = useModelStore();

  // --- Painel de Logs Remotos em Tempo Real ---
  const [debugLogs, setDebugLogs] = useState<{ level: 'info' | 'warn' | 'error'; message: string; timestamp: string; data?: any }[]>([]);
  const [showLogs, setShowLogs] = useState(() => new URLSearchParams(window.location.search).get('viewlogs') === 'true');

  useEffect(() => {
    if (!showLogs) return;
    const logChannel = supabase.channel('global-app-logs-viewer');
    logChannel.on('broadcast', { event: 'log' }, ({ payload }) => {
      setDebugLogs(prev => [payload, ...prev].slice(0, 100));
    }).subscribe();

    return () => {
      logChannel.unsubscribe();
    };
  }, [showLogs]);

  const [ifcConvert, setIfcConvert] = useState(() => {
    const saved = localStorage.getItem('tsxr_ifc_convert');
    return saved !== 'false';
  });

  const handleToggleIfcConvert = (checked: boolean) => {
    setIfcConvert(checked);
    localStorage.setItem('tsxr_ifc_convert', checked ? 'true' : 'false');
  };

  useEffect(() => {
    if (navigator.xr) {
      navigator.xr.isSessionSupported('immersive-ar').then(setXrSupported).catch(() => setXrSupported(false));
    } else {
      setXrSupported(false);
    }
  }, [setXrSupported]);

  const handleFileUpload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const ext = getSupportedExtension(file.name);
    if (!ext) {
      toast.error('Formato inválido. Selecione um arquivo .GLB, .OBJ, .STL ou .IFC');
      return;
    }

    // Pré-validação rápida (tamanho) antes de ler o arquivo inteiro na memória
    const sizeCheck = validateModelFile(file.name, file.size, ext);
    if (!sizeCheck.ok) {
      toast.error(sizeCheck.reason!);
      return;
    }

    if (ext === 'glb') {
      // Para GLB, valida assinatura "glTF" antes de criar o objectURL
      try {
        const head = await file.slice(0, 16).arrayBuffer();
        const sigCheck = validateModelFile(file.name, file.size, ext, head);
        if (!sigCheck.ok) {
          toast.error(sigCheck.reason!);
          if (sigCheck.detail) console.warn('[validateModelFile]', sigCheck.detail);
          return;
        }
      } catch (err) {
        console.error('[upload] header read failed', err);
      }
      const url = URL.createObjectURL(file);
      addModel({ fileName: file.name, fileSize: file.size, url });
      addRecentFile(file.name, file).catch(() => {});
      toast.success(`Modelo "${file.name}" carregado com sucesso!`);
      return;
    }

    // Convert OBJ/STL/IFC to GLB
    setConverting(true);
    try {
      const buffer = await file.arrayBuffer();
      const sigCheck = validateModelFile(file.name, file.size, ext, buffer);
      if (!sigCheck.ok) {
        toast.error(sigCheck.reason!);
        if (sigCheck.detail) console.warn('[validateModelFile]', sigCheck.detail);
        setConverting(false);
        return;
      }

      if (ext === 'ifc' && !ifcConvert) {
        const url = URL.createObjectURL(file);
        addModel({ fileName: file.name, fileSize: file.size, url });
        addRecentFile(file.name, file).catch(() => {});
        toast.success(`Modelo "${file.name}" carregado de forma nativa!`);
        setConverting(false);
        return;
      }

      let result;
      if (ext === 'ifc') {
        result = await convertIFCtoGLB(buffer, file.name);
      } else {
        result = await convertToGLB(buffer, ext, file.name);
      }
      const url = URL.createObjectURL(result.blob);
      addModel({ fileName: result.fileName, fileSize: result.fileSize, url });
      addRecentFile(result.fileName, result.blob).catch(() => {});
      toast.success(`"${file.name}" convertido para GLB e carregado!`);
    } catch (err) {
      console.error('[upload] conversion failed', err);
      const msg = err instanceof Error ? err.message : 'erro desconhecido';
      toast.error(`Falha ao converter "${file.name}": ${msg}`);
    } finally {
      setConverting(false);
    }
  }, [addModel, ifcConvert]);

  // Carregar da Nuvem agora é encapsulado em <CloudLoader />

  const handleLoadDemoIFC = useCallback(async () => {
    setLoadingDemoIFC(true);
    try {
      const response = await fetch('/models/demo250hp.ifc');
      const buffer = await response.arrayBuffer();
      if (!ifcConvert) {
        const blob = new Blob([buffer], { type: 'application/octet-stream' });
        const url = URL.createObjectURL(blob);
        addModel({ fileName: 'demo250hp.ifc', fileSize: blob.size, url });
        addRecentFile('demo250hp.ifc', blob).catch(() => {});
        toast.success('Modelo demo "250 HP" (IFC nativo) carregado!');
        return;
      }
      const result = await convertIFCtoGLB(buffer, 'demo250hp.ifc');
      const url = URL.createObjectURL(result.blob);
      addModel({ fileName: result.fileName, fileSize: result.fileSize, url });
      addRecentFile(result.fileName, result.blob).catch(() => {});
      toast.success('Modelo demo "250 HP" (IFC) carregado!');
    } catch (err) {
      console.error(err);
      toast.error('Falha ao processar modelo demo IFC');
    } finally {
      setLoadingDemoIFC(false);
    }
  }, [addModel, ifcConvert]);

  const handleLoadDemoCotovelo = useCallback(async () => {
    setLoadingDemoCotovelo(true);
    try {
      const response = await fetch('/models/B126-COTOVELO.ifc');
      const buffer = await response.arrayBuffer();
      if (!ifcConvert) {
        const blob = new Blob([buffer], { type: 'application/octet-stream' });
        const url = URL.createObjectURL(blob);
        addModel({ fileName: 'B126-COTOVELO.ifc', fileSize: blob.size, url });
        addRecentFile('B126-COTOVELO.ifc', blob).catch(() => {});
        toast.success('Modelo demo "B126 Cotovelo" (IFC nativo) carregado!');
        return;
      }
      const result = await convertIFCtoGLB(buffer, 'B126-COTOVELO.ifc');
      const url = URL.createObjectURL(result.blob);
      addModel({ fileName: result.fileName, fileSize: result.fileSize, url });
      addRecentFile(result.fileName, result.blob).catch(() => {});
      toast.success('Modelo demo "B126 Cotovelo" (IFC) carregado!');
    } catch (err) {
      console.error(err);
      toast.error('Falha ao processar modelo demo Cotovelo');
    } finally {
      setLoadingDemoCotovelo(false);
    }
  }, [addModel, ifcConvert]);

  const handleEnterViewer = () => {
    if (!model) {
      toast.error('Importe um modelo 3D primeiro');
      return;
    }
    navigate('/viewer');
  };

  return (
    <div className="flex min-h-screen flex-col items-center justify-center bg-background grid-industrial p-6">
      <input
        ref={fileInputRef}
        type="file"
        accept={ACCEPTED_EXTENSIONS}
        className="hidden"
        onChange={handleFileUpload} />


      {/* Logo area */}
      <div className="mb-12 text-center">
        <div className="mb-4 flex items-center justify-center gap-3">
          <Box className="h-10 w-10 text-primary" />
          <h1 className="text-3xl font-bold tracking-tight text-foreground md:text-4xl">
            TrackSteel<span className="text-primary">XR</span>
          </h1>
        </div>
        <p className="font-mono text-sm uppercase tracking-widest text-muted-foreground">
          Inspeção de Qualidade Industrial
        </p>
      </div>

      {/* Main card */}
      <div className="w-full max-w-md space-y-4">
        {/* Import button */}
        <Button
          variant="outline"
          className="h-28 w-full flex-col gap-3 border-dashed border-2 text-muted-foreground hover:border-primary hover:text-primary transition-all"
          onClick={() => fileInputRef.current?.click()}
          disabled={converting}>

          {converting ? <Loader2 className="h-8 w-8 animate-spin" /> : <Upload className="h-8 w-8" />}
          <div className="text-center">
            <p className="text-sm font-semibold">{converting ? 'Carregando modelo…' : 'Importar Modelo 3D'}</p>
            <p className="text-xs text-muted-foreground">GLB · OBJ · STL · IFC — Escala 1:1</p>
          </div>
        </Button>

        {/* Toggle IFC Conversion */}
        <div className="flex items-center justify-between rounded-lg border border-border bg-card/50 p-3.5">
          <div className="flex flex-col gap-0.5">
            <Label htmlFor="ifc-convert-toggle" className="text-xs font-semibold cursor-pointer text-foreground">
              Conversão IFC ➔ GLB
            </Label>
            <p className="text-[10px] text-muted-foreground">
              {ifcConvert ? 'Otimizado para AR (conversão automática)' : 'Modo nativo (carregamento bruto IFC)'}
            </p>
          </div>
          <Switch
            id="ifc-convert-toggle"
            checked={ifcConvert}
            onCheckedChange={handleToggleIfcConvert}
          />
        </div>

        {/* Demo buttons */}
        <div className="grid grid-cols-3 gap-2">
          <CloudLoader />

          <Button
            variant="outline"
            className="h-12 w-full gap-2 border-muted-foreground/30 text-muted-foreground hover:border-primary hover:text-primary transition-all text-xs"
            onClick={handleLoadDemoIFC}
            disabled={loadingDemoIFC}>
            {loadingDemoIFC ? <Loader2 className="h-4 w-4 animate-spin" /> : <Package className="h-4 w-4" />}
            {loadingDemoIFC ? 'Convertendo…' : 'Demo — 250 HP (IFC)'}
          </Button>

          <Button
            variant="outline"
            className="h-12 w-full gap-2 border-muted-foreground/30 text-muted-foreground hover:border-primary hover:text-primary transition-all text-xs"
            onClick={handleLoadDemoCotovelo}
            disabled={loadingDemoCotovelo}>
            {loadingDemoCotovelo ? <Loader2 className="h-4 w-4 animate-spin" /> : <Package className="h-4 w-4" />}
            {loadingDemoCotovelo ? 'Convertendo…' : 'Demo — B126 Cotovelo (IFC)'}
          </Button>
        </div>


        {models.length > 0 && (
          <div className="rounded-lg border border-primary/30 bg-primary/5 p-3 glow-primary">
            <SceneModelList />
            <p className="mt-2 text-center font-mono text-[10px] text-muted-foreground">
              {models.length < maxModels
                ? `Você pode adicionar mais ${maxModels - models.length} peça(s) à cena`
                : `Limite de ${maxModels} peças simultâneas atingido`}
            </p>
          </div>
        )}

        {/* Recent files card — últimos 6 modelos abertos (cache local) */}
        <div className="rounded-lg border border-border bg-card/50 p-3">
          <RecentFilesList />
        </div>


        {/* Enter viewer */}
        <Button
          className="h-14 w-full gap-3 text-base font-semibold glow-primary"
          disabled={!model}
          onClick={handleEnterViewer}>

          <Glasses className="h-5 w-5" />
          Visualizar Modelo 3D
        </Button>

        {/* XR Status */}
        <div className="flex items-center justify-center gap-2 pt-2">
          {xrSupported === null ?
          <>
              <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
              <span className="text-xs text-muted-foreground">Verificando suporte WebXR…</span>
            </> :
          xrSupported ?
          <>
              <CheckCircle className="h-4 w-4 text-success" />
              <span className="text-xs text-success">WebXR Compatível — Passthrough disponível</span>
            </> :

          <>
              <XCircle className="h-4 w-4 text-destructive" />
              <span className="text-xs text-destructive">WebXR não disponível neste navegador</span>
            </>
          }
        </div>
      </div>

      {/* Footer */}
      <p className="mt-16 text-center font-mono text-xs text-muted-foreground/50">
        TrackSteelXR v1.05 — Q.C. Inspection
      </p>

      {showLogs && (
        <div className="fixed bottom-4 right-4 z-50 flex h-[400px] w-[500px] flex-col rounded-lg border border-border bg-slate-950/95 p-4 shadow-2xl backdrop-blur font-mono text-xs text-slate-200">
          <div className="flex items-center justify-between border-b border-border pb-2 mb-2">
            <span className="font-bold text-primary flex items-center gap-2">
              <span className="h-2 w-2 rounded-full bg-emerald-500 animate-ping" />
              Console de Logs Remotos (Quest 3)
            </span>
            <div className="flex gap-2">
              <Button size="sm" variant="outline" className="h-6 px-2 text-[10px]" onClick={() => setDebugLogs([])}>
                Limpar
              </Button>
              <Button size="sm" variant="outline" className="h-6 px-2 text-[10px] text-destructive" onClick={() => setShowLogs(false)}>
                Fechar
              </Button>
            </div>
          </div>
          <div className="flex-1 overflow-y-auto space-y-2 pr-1">
            {debugLogs.length === 0 ? (
              <p className="text-slate-500 text-center mt-12">Aguardando logs do headset Quest 3...</p>
            ) : (
              debugLogs.map((log, i) => (
                <div key={i} className={`p-2 rounded border ${
                  log.level === 'error' ? 'bg-red-950/40 border-red-500/30 text-red-300' :
                  log.level === 'warn' ? 'bg-amber-950/40 border-amber-500/30 text-amber-300' :
                  'bg-slate-900/60 border-slate-700/30 text-slate-300'
                }`}>
                  <div className="flex justify-between text-[9px] text-slate-400 mb-1">
                    <span>{new Date(log.timestamp).toLocaleTimeString()}</span>
                    <span className="uppercase font-bold">{log.level}</span>
                  </div>
                  <p className="break-all whitespace-pre-wrap">{log.message}</p>
                  {log.data && (
                    <pre className="mt-1 text-[10px] bg-black/40 p-1 rounded overflow-x-auto max-h-24 text-slate-400">
                      {JSON.stringify(log.data, null, 2)}
                    </pre>
                  )}
                </div>
              ))
            )}
          </div>
        </div>
      )}
    </div>);

};

export default Index;