import { useEffect, useRef, useState } from 'react';
import cx from '@src/cx.mjs';
import { useSettings } from '@src/settings.mjs';
import { ActionButton } from '../button/action-button.jsx';

// Pestaña KISUM: "musik al reves". Arrastras un audio o video, se lo manda al
// mini-servidor local de KISUM (Python), y devuelve el codigo Strudel listo
// para cargar en el editor. El servidor lo arranca strudel-launcher.sh.
const KISUM_URL = 'http://127.0.0.1:3010';

export function KisumTab({ context }) {
  const { fontFamily } = useSettings();
  const [file, setFile] = useState(null);
  const [bars, setBars] = useState(4);
  const [bass, setBass] = useState(false);
  const [code, setCode] = useState('');
  const [status, setStatus] = useState('idle'); // idle | loading | done | error
  const [error, setError] = useState('');
  const [serverUp, setServerUp] = useState(null); // null=comprobando, true, false
  const [copied, setCopied] = useState(false);
  const [drag, setDrag] = useState(false);
  const inputRef = useRef(null);

  const editor = () => context.editorRef?.current;

  // comprobar si el servidor KISUM responde (y reintentar cada pocos segundos)
  useEffect(() => {
    let alive = true;
    const check = () =>
      fetch(`${KISUM_URL}/health`)
        .then((r) => r.ok)
        .then((ok) => alive && setServerUp(ok))
        .catch(() => alive && setServerUp(false));
    check();
    const id = setInterval(check, 4000);
    return () => {
      alive = false;
      clearInterval(id);
    };
  }, []);

  const analyze = async () => {
    if (!file) return;
    setStatus('loading');
    setError('');
    setCode('');
    try {
      const q = `?bars=${bars}&bass=${bass ? 1 : 0}`;
      const res = await fetch(`${KISUM_URL}/analyze${q}`, {
        method: 'POST',
        headers: { 'X-Filename': file.name, 'Content-Type': 'application/octet-stream' },
        body: file,
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || `error ${res.status}`);
      setCode(data.code);
      setStatus('done');
    } catch (e) {
      setError(String(e.message || e));
      setStatus('error');
    }
  };

  const loadInEditor = () => {
    const ed = editor();
    if (!ed || !code) return;
    ed.setCode(code);
  };

  const copy = () => {
    navigator.clipboard?.writeText?.(code);
    setCopied(true);
    setTimeout(() => setCopied(false), 1200);
  };

  const onDrop = (e) => {
    e.preventDefault();
    setDrag(false);
    const f = e.dataTransfer.files?.[0];
    if (f) setFile(f);
  };

  return (
    <div className="w-full h-full text-foreground flex flex-col overflow-hidden" style={{ fontFamily }}>
      {/* estado del servidor */}
      <div className="flex items-center gap-2 px-2 py-1.5 border-b border-muted shrink-0 text-xs">
        <span
          className={cx(
            'w-2 h-2 rounded-full',
            serverUp === true ? 'bg-green-400' : serverUp === false ? 'bg-red-400' : 'bg-yellow-400',
          )}
        />
        <span className="opacity-70">
          {serverUp === true
            ? 'servidor KISUM conectado'
            : serverUp === false
              ? 'servidor KISUM apagado — reabre Strudel con el icono, o arráncalo a mano'
              : 'buscando servidor KISUM…'}
        </span>
      </div>

      {/* zona de soltar archivo */}
      <div className="px-2 py-2 shrink-0">
        <div
          onClick={() => inputRef.current?.click()}
          onDragOver={(e) => {
            e.preventDefault();
            setDrag(true);
          }}
          onDragLeave={() => setDrag(false)}
          onDrop={onDrop}
          className={cx(
            'border-2 border-dashed rounded-lg px-3 py-6 text-center cursor-pointer transition-colors',
            drag ? 'border-cyan-400 bg-cyan-400/10' : 'border-muted hover:border-cyan-400/60',
          )}
        >
          {file ? (
            <span className="text-sm">
              <b>{file.name}</b>
            </span>
          ) : (
            <span className="text-sm opacity-70">arrastra aquí un audio o vídeo (mp3, wav, mp4, mkv…) o haz clic</span>
          )}
          <input
            ref={inputRef}
            type="file"
            accept="audio/*,video/*"
            className="hidden"
            onChange={(e) => setFile(e.target.files?.[0] || null)}
          />
        </div>
      </div>

      {/* opciones */}
      <div className="flex items-center gap-4 px-2 pb-2 shrink-0 text-sm flex-wrap">
        <label className="flex items-center gap-1.5">
          <span className="opacity-70">compases</span>
          <input
            type="number"
            min="1"
            max="32"
            value={bars}
            onChange={(e) => setBars(Math.max(1, Number(e.target.value) || 1))}
            className="w-16 bg-lineHighlight border border-muted rounded px-1.5 py-0.5 outline-none focus:border-cyan-400"
          />
        </label>
        <label className="flex items-center gap-1.5 cursor-pointer">
          <input type="checkbox" checked={bass} onChange={(e) => setBass(e.target.checked)} className="accent-cyan-400" />
          <span className="opacity-70">línea de bajo (experimental)</span>
        </label>
        <ActionButton
          label={status === 'loading' ? 'analizando…' : 'Analizar'}
          onClick={analyze}
          className={cx(
            'ml-auto px-3 py-1 border rounded font-bold',
            !file || status === 'loading' || serverUp !== true
              ? 'border-muted opacity-40 pointer-events-none'
              : 'border-cyan-400/70 text-cyan-300 hover:bg-cyan-400/10',
          )}
        />
      </div>

      {/* resultado */}
      <div className="grow overflow-auto px-2 py-2 min-h-0 border-t border-muted">
        {status === 'error' && <p className="text-red-400 text-sm whitespace-pre-wrap">{error}</p>}
        {status === 'loading' && <p className="opacity-60 text-sm">escuchando la canción y sacando el ritmo…</p>}
        {status === 'done' && code && (
          <>
            <div className="flex items-center gap-2 mb-2">
              <ActionButton
                label="Cargar en editor"
                onClick={loadInEditor}
                className="text-cyan-300 border border-cyan-400/60 rounded px-2 py-0.5 text-sm hover:bg-cyan-400/10"
              />
              <ActionButton
                label={copied ? 'copiado' : 'copiar'}
                onClick={copy}
                className={cx(
                  'border rounded px-2 py-0.5 text-sm',
                  copied ? 'border-green-400 text-green-400' : 'border-muted hover:border-cyan-400/60',
                )}
              />
            </div>
            <pre className="font-mono text-xs whitespace-pre-wrap leading-snug opacity-90 select-text">{code}</pre>
          </>
        )}
        {status === 'idle' && (
          <p className="opacity-50 text-xs">
            KISUM escucha la canción, detecta el tempo y los golpes (bombo/caja/hats) y te lo devuelve como código
            Strudel. Sube un archivo y pulsa Analizar.
          </p>
        )}
      </div>
    </div>
  );
}
