/* global React, Icon, MicButton, SOPAI, SOPStore */
/* SimpleEditor — single-input mode. User dictates or types whatever
   they want and AI does the whole structuring. */

const { useState: useStateSE, useRef: useRefSE, useEffect: useEffectSE } = React;

const EXAMPLE_PROMPTS = [
  {
    label: "Onboarding cliente nuevo",
    text: "Necesito un SOP para el onboarding de un cliente nuevo de Ads&Law. Incluye reunión kickoff, recolección de credenciales (Meta Business, GHL, dominio), setup del píxel, configuración de eventos, briefing de mercado y aprobación de creatividades antes del lanzamiento.",
  },
  {
    label: "Lanzamiento de campaña Meta",
    text: "SOP para lanzar una campaña nueva de Meta Ads de un despacho. Quiero: validación del brief, creación de adsets, subida de creatividades, configuración del budget, pruebas de tracking y revisión por el líder antes de poner en LIVE.",
  },
  {
    label: "Reporte semanal de cliente",
    text: "SOP del reporte semanal a clientes: descarga de datos de Meta + GHL, cálculo de CPL y leads cualificados, redacción del análisis, generación del PDF con la plantilla, envío por email los lunes antes de las 10:00.",
  },
  {
    label: "Optimización diaria de adsets",
    text: "SOP de la rutina diaria de optimización: revisar adsets, identificar los que están sobre el CPL objetivo, pausar los muertos, escalar los ganadores, documentar cambios en Slack del cliente.",
  },
];

function SimpleEditor({ doc, onChange, onToast }) {
  const [text, setText] = useStateSE("");
  const [interim, setInterim] = useStateSE("");
  const [busy, setBusy] = useStateSE(false);
  const [error, setError] = useStateSE("");
  // images: array de { id, name, dataUrl, size }. dataUrl es lo que mandamos al backend.
  const [images, setImages] = useStateSE([]);
  const taRef = useRefSE(null);
  const fileInputRef = useRefSE(null);

  const hasContent = !!(doc && (doc.title || (doc.phases && doc.phases.length)));

  // Append voice transcript to the existing text
  const onVoice = (t) => {
    setText(prev => {
      const sep = prev && !/\s$/.test(prev) ? " " : "";
      return (prev + sep + t).trim() + " ";
    });
    setInterim("");
  };

  // ---- imágenes ----
  // Lee el archivo como data URL base64 y devuelve un descriptor para state.
  const readFileAsDataUrl = (file) => new Promise((resolve, reject) => {
    const r = new FileReader();
    r.onload = () => resolve({
      id: crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`,
      name: file.name,
      size: file.size,
      dataUrl: r.result,
    });
    r.onerror = () => reject(new Error("No pude leer la imagen"));
    r.readAsDataURL(file);
  });
  const MAX_IMG_BYTES = 8 * 1024 * 1024;  // 8 MB por imagen
  const MAX_IMGS = 6;
  const addFiles = async (filesLike) => {
    if (!filesLike || !filesLike.length) return;
    const files = Array.from(filesLike).filter(f => f.type && f.type.startsWith("image/"));
    if (!files.length) { setError("Solo se aceptan imágenes (PNG, JPG, etc)."); return; }
    const oversized = files.find(f => f.size > MAX_IMG_BYTES);
    if (oversized) { setError(`"${oversized.name}" pesa más de 8 MB. Reducila antes de subirla.`); return; }
    if (images.length + files.length > MAX_IMGS) {
      setError(`Máximo ${MAX_IMGS} imágenes por prompt.`); return;
    }
    try {
      const descriptors = await Promise.all(files.map(readFileAsDataUrl));
      setImages(prev => [...prev, ...descriptors]);
      setError("");
    } catch (e) {
      setError(e.message || "Error leyendo imagen");
    }
  };
  const removeImage = (id) => setImages(prev => prev.filter(im => im.id !== id));
  // Drag & drop sobre el textarea
  const onDrop = (e) => {
    e.preventDefault();
    if (e.dataTransfer && e.dataTransfer.files) addFiles(e.dataTransfer.files);
  };
  // Paste: si pegás una imagen (Cmd+V de captura), la sumamos
  const onPaste = (e) => {
    const items = e.clipboardData && e.clipboardData.items;
    if (!items) return;
    const imgs = [];
    for (const it of items) {
      if (it.kind === "file" && it.type.startsWith("image/")) {
        const f = it.getAsFile();
        if (f) imgs.push(f);
      }
    }
    if (imgs.length) {
      e.preventDefault();
      addFiles(imgs);
    }
  };

  const run = async (mode) => {
    setError("");
    if (!text.trim() && images.length === 0) {
      setError("Cuéntame qué SOP necesitas — habla, escribe o adjuntá capturas."); return;
    }
    // Si hay imágenes pero el provider es Ollama → no se procesan. Aviso.
    if (images.length > 0 && (window.__SOP_PROVIDER || "codex") !== "codex") {
      setError("Para procesar imágenes cambiá a Codex en el toggle del header.");
      return;
    }
    // Pedimos confirmación antes de reemplazar un SOP con contenido.
    if (mode === "create" && hasContent) {
      const ok = window.confirm(
        "Esto va a reemplazar el SOP actual por uno nuevo basado en tu texto.\n" +
        "Si querías solo modificarlo, pulsa Cancelar y usa \"Refinar SOP actual\".\n\n" +
        "El SOP anterior queda en el historial — podrás recuperarlo desde el botón Historial."
      );
      if (!ok) return;
    }
    setBusy(true);
    try {
      const imgUrls = images.map(im => im.dataUrl);
      let next;
      if (mode === "refine" && hasContent) {
        next = await window.SOPAI.refine(text, doc, imgUrls);
        onToast && onToast("SOP actualizado ✓");
      } else {
        next = await window.SOPAI.structure(text || "Genera un SOP a partir de las capturas adjuntas.", doc, imgUrls);
        onToast && onToast("SOP generado ✓");
      }
      onChange(next);
      setText("");
      setImages([]);
    } catch (e) {
      setError(e.message || "Algo salió mal.");
    } finally {
      setBusy(false);
    }
  };

  const useExample = (ex) => {
    setText(ex.text);
    setTimeout(() => { taRef.current && taRef.current.focus(); }, 0);
  };

  return (
    <div className="simple-editor">
      <div className="simple-editor__inner">
        {/* ----- Header ----- */}
        <div className="simple-editor__head">
          <h2 className="simple-editor__title">
            <Icon name="sparkles" size={18} /> Cuéntame qué SOP necesitas
          </h2>
          <p className="simple-editor__sub">
            Habla o escribe libremente — la IA detectará título, fases, pasos, roles, herramientas y todo lo demás.
            No tienes que organizarlo, ni decidir dónde va cada cosa.
          </p>
        </div>

        {/* ----- Big input ----- */}
        <div
          className="simple-input"
          onDragOver={(e) => { e.preventDefault(); }}
          onDrop={onDrop}
        >
          <textarea
            ref={taRef}
            className="simple-input__ta"
            value={text}
            onChange={(e) => setText(e.target.value)}
            onPaste={onPaste}
            placeholder={hasContent
              ? "Ej: 'Añade una fase 4 de seguimiento post-launch con dos pasos' …"
              : "Ej: 'Necesito un SOP para preparar el reporte mensual de un cliente — descargar datos, calcular CPL, redactar análisis, generar PDF y enviarlo' …\n\nTambién podés arrastrar capturas acá."}
            disabled={busy}
          />
          {interim && (
            <div className="simple-input__interim">
              <Icon name="mic" size={11} /> {interim}
            </div>
          )}

          {/* Thumbnails de imágenes adjuntas */}
          {images.length > 0 && (
            <div className="simple-images">
              {images.map(im => (
                <div key={im.id} className="simple-images__thumb" title={`${im.name} · ${(im.size/1024).toFixed(0)} KB`}>
                  <img src={im.dataUrl} alt={im.name} />
                  <button
                    className="simple-images__remove"
                    onClick={() => removeImage(im.id)}
                    title="Quitar"
                    disabled={busy}
                  >
                    <Icon name="x" size={11} />
                  </button>
                </div>
              ))}
            </div>
          )}

          <input
            ref={fileInputRef}
            type="file"
            accept="image/*"
            multiple
            style={{ display: "none" }}
            onChange={(e) => { addFiles(e.target.files); e.target.value = ""; }}
          />

          <div className="simple-input__toolbar">
            <MicButton onTranscript={onVoice} onInterim={setInterim} lang="es-ES" size={40} />
            <button
              className="btn simple-input__attach"
              onClick={() => fileInputRef.current && fileInputRef.current.click()}
              disabled={busy || images.length >= MAX_IMGS}
              title="Adjuntar capturas (máx. 6, hasta 8 MB cada una). Codex las usará para detectar pasos visibles."
            >
              <Icon name="image" size={13} /> Adjuntar imagen
              {images.length > 0 && <span className="simple-input__attach-count">{images.length}</span>}
            </button>
            <span className="simple-input__hint">
              {window.SOPVoice && window.SOPVoice.isSupported()
                ? "Micrófono · adjuntá · arrastrá · pegá"
                : "Adjuntá imágenes o arrastralas acá"}
            </span>
            <span style={{ flex: 1 }} />
            {hasContent && (
              <button className="btn" onClick={() => run("refine")} disabled={busy || (!text.trim() && images.length === 0)}>
                <Icon name="edit" size={13} /> Refinar SOP actual
              </button>
            )}
            <button className="btn btn--primary" onClick={() => run("create")} disabled={busy || (!text.trim() && images.length === 0)}>
              {busy ? <span className="spinner" /> : <Icon name="zap" size={13} />}
              {busy ? "Generando…" : hasContent ? "Reemplazar y generar" : "Generar SOP"}
            </button>
          </div>
          {error && <div className="simple-input__err"><Icon name="x" size={12} /> {error}</div>}
        </div>

        {/* ----- Examples ----- */}
        {!hasContent && (
          <div className="simple-examples">
            <span className="simple-examples__label">O empieza desde un ejemplo:</span>
            <div className="simple-examples__chips">
              {EXAMPLE_PROMPTS.map(ex => (
                <button key={ex.label} className="simple-example-chip" onClick={() => useExample(ex)}>
                  {ex.label}
                </button>
              ))}
            </div>
          </div>
        )}

        {/* ----- Tips ----- */}
        <div className="simple-tips">
          <h3 className="simple-tips__title">Consejos para mejores resultados</h3>
          <ul className="simple-tips__list">
            <li><strong>Sé concreto con el objetivo.</strong> Decir <em>“subir plantillas de email al GHL del cliente"</em> da mejor resultado que <em>“proceso de emails"</em>.</li>
            <li><strong>Menciona herramientas y roles.</strong> Si dices <em>“el media buyer hace X y el revisor valida Y"</em>, la IA crea los roles automáticamente.</li>
            <li><strong>Habla en orden o no.</strong> No importa, la IA reorganiza los pasos en fases lógicas.</li>
            <li><strong>Anglicismos del sector están permitidos:</strong> lead, CPL, CTR, adset, creative, funnel.</li>
          </ul>
        </div>

        {/* ----- Status ----- */}
        {hasContent && (
          <div className="simple-status">
            <Icon name="fileText" size={13} />
            <span>SOP actual: <strong>{doc.title || "Sin título"}</strong> · {doc.phases?.length || 0} fases · {doc.phases?.reduce((n, p) => n + (p.steps?.length || 0), 0) || 0} pasos</span>
          </div>
        )}
      </div>
    </div>
  );
}

window.SimpleEditor = SimpleEditor;
