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 { getSupportedExtension, convertToGLB, ACCEPTED_EXTENSIONS } from '@/lib/convertToGLB';
import { convertIFCtoGLB } from '@/lib/convertIFC';
import { CloudLoader } from '@/components/CloudLoader';

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

  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;
    }

    if (ext === 'glb') {
      const url = URL.createObjectURL(file);
      setModel({ fileName: file.name, fileSize: file.size, url });
      toast.success(`Modelo "${file.name}" carregado com sucesso!`);
      return;
    }

    // Convert OBJ/STL/IFC to GLB
    setConverting(true);
    try {
      const buffer = await file.arrayBuffer();
      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);
      setModel({ fileName: result.fileName, fileSize: result.fileSize, url });
      toast.success(`"${file.name}" convertido para GLB e carregado!`);
    } catch (err) {
      console.error(err);
      toast.error(`Falha ao converter "${file.name}"`);
    } finally {
      setConverting(false);
    }
  }, [setModel]);

  const handleLoadCloud = useCallback(async () => {
    const DEFAULT_URL = 'https://store.tracksteel.com.br/demo.ifc';
    const raw = window.prompt(
      'URL do modelo (GLB · OBJ · STL · IFC).\nDica: Dropbox use ?dl=1 · OneDrive ?download=1 · FileBrowser /api/raw/<arquivo>',
      DEFAULT_URL,
    );
    if (!raw) return;
    setLoadingCloud(true);
    try {
      // Normalizações automáticas para hosts comuns
      const url = normalizeCloudUrl(raw.trim());
      const fileName = url.split('/').pop()?.split('?')[0] || 'modelo-cloud';
      const ext = getSupportedExtension(fileName);
      if (!ext) {
        toast.error('URL deve apontar para .GLB, .OBJ, .STL ou .IFC');
        return;
      }

      let response = await fetch(url, { mode: 'cors' });
      if (!response.ok) throw new Error(`HTTP ${response.status}`);

      // Detecta servidores que retornam HTML em vez do binário (ex.: FileBrowser SPA)
      let ct = response.headers.get('content-type') || '';
      if (ct.includes('text/html')) {
        // Fallback: tenta endpoint /api/raw/ do FileBrowser
        try {
          const u = new URL(url);
          if (!u.pathname.startsWith('/api/raw/')) {
            const fbUrl = `${u.origin}/api/raw${u.pathname}${u.search}`;
            const r2 = await fetch(fbUrl, { mode: 'cors' });
            if (r2.ok) {
              response = r2;
              ct = r2.headers.get('content-type') || '';
            }
          }
        } catch {}
      }
      if (ct.includes('text/html')) {
        toast.error('O servidor devolveu uma página HTML, não o arquivo. Use o link DIRETO do arquivo (ex.: FileBrowser → /api/raw/arquivo.ifc).');
        return;
      }

      const buffer = await response.arrayBuffer();

      let blob: Blob;
      let outName = fileName;
      let outSize = buffer.byteLength;
      if (ext === 'glb') {
        blob = new Blob([buffer], { type: 'model/gltf-binary' });
      } else if (ext === 'ifc') {
        const r = await convertIFCtoGLB(buffer, fileName);
        blob = r.blob; outName = r.fileName; outSize = r.fileSize;
      } else {
        const r = await convertToGLB(buffer, ext, fileName);
        blob = r.blob; outName = r.fileName; outSize = r.fileSize;
      }
      const blobUrl = URL.createObjectURL(blob);
      setModel({ fileName: outName, fileSize: outSize, url: blobUrl });
      toast.success(`"${outName}" carregado da nuvem (RAM)`);
    } catch (err) {
      console.error(err);
      toast.error('Falha ao carregar da nuvem (verifique URL/CORS)');
    } finally {
      setLoadingCloud(false);
    }
  }, [setModel]);

  const handleLoadDemoIFC = useCallback(async () => {
    setLoadingDemoIFC(true);
    try {
      const response = await fetch('/models/demo250hp.ifc');
      const buffer = await response.arrayBuffer();
      const result = await convertIFCtoGLB(buffer, 'demo250hp.ifc');
      const url = URL.createObjectURL(result.blob);
      setModel({ fileName: result.fileName, fileSize: result.fileSize, url });
      toast.success('Modelo demo "250 HP" (IFC) carregado!');
    } catch (err) {
      console.error(err);
      toast.error('Falha ao converter modelo demo IFC');
    } finally {
      setLoadingDemoIFC(false);
    }
  }, [setModel]);

  const handleLoadDemoCotovelo = useCallback(async () => {
    setLoadingDemoCotovelo(true);
    try {
      const response = await fetch('/models/B126-COTOVELO.ifc');
      const buffer = await response.arrayBuffer();
      const result = await convertIFCtoGLB(buffer, 'B126-COTOVELO.ifc');
      const url = URL.createObjectURL(result.blob);
      setModel({ fileName: result.fileName, fileSize: result.fileSize, url });
      toast.success('Modelo demo "B126 Cotovelo" (IFC) carregado!');
    } catch (err) {
      console.error(err);
      toast.error('Falha ao converter modelo demo Cotovelo');
    } finally {
      setLoadingDemoCotovelo(false);
    }
  }, [setModel]);

  const handleEnterViewer = () => {
    if (!model) {
      toast.error('Importe um modelo GLB 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 ? 'Convertendo modelo…' : 'Importar Modelo 3D'}</p>
            <p className="text-xs text-muted-foreground">GLB · OBJ · STL · IFC — Escala 1:1</p>
          </div>
        </Button>

        {/* Demo buttons */}
        <div className="grid grid-cols-3 gap-2">
          <Button
            variant="outline"
            className="h-12 w-full gap-2 border-primary/40 text-primary hover:border-primary hover:bg-primary/10 transition-all text-xs"
            onClick={handleLoadCloud}
            disabled={loadingCloud}>
            {loadingCloud ? <Loader2 className="h-4 w-4 animate-spin" /> : <Cloud className="h-4 w-4" />}
            {loadingCloud ? 'Baixando…' : 'Carregar da Nuvem'}
          </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={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>


        {model &&
        <div className="rounded-lg border border-primary/30 bg-primary/5 p-4 glow-primary">
            <div className="flex items-center gap-3">
              <Box className="h-5 w-5 text-primary" />
              <div className="min-w-0 flex-1">
                <p className="truncate font-mono text-sm font-medium text-foreground">{model.fileName}</p>
                <p className="text-xs text-muted-foreground">
                  {(model.fileSize / (1024 * 1024)).toFixed(2)} MB
                </p>
              </div>
              <CheckCircle className="h-5 w-5 text-success shrink-0" />
            </div>
          </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.0 — Q.C. Inspection
      </p>
    </div>);

};

export default Index;