// ─── Micos CRM · Composer (nuevo correo) ───────────
// Carril B-fr2 (obra 07/07): vínculo real con expediente (ExpedienteCombobox,
// auditoría #28), adjuntos reales locales + del ERP (#29/#30), plantillas con
// variables REEMPLAZADAS (#33), borradores con autosave real (#31/#32) y
// apertura por query params (?compose=1&to=&subject=&exp=&doc= — contrato con
// el carril B-erp: el ERP prellena el composer con un deep-link).
// Consume crm/envio.jsx (useCrmBorrador/useCrmAdjuntosSalientes/plantillas/
// picker) + ExpedienteCombobox (screens/compras/combobox.jsx).
//
// Contrato de borradores con app.jsx (B-fr1): recibe initialCc/initialCuerpo/
// initialAlias/draftId. Al RETOMAR un borrador de la carpeta Borradores
// (draftId presente) prellena todo y APAGA su autosave propio — el borrador ya
// existe y app.jsx lo borra al enviar (eliminarBorrador). Redactar en limpio
// (sin draftId) sí autosalva contra /api/crm-borradores. Ver reporte B-fr2 §
// borradores para la limitación de re-guardar cambios sobre un borrador abierto.

const { useState: _useStateCC, useRef: _useRefCC, useEffect: _useEffectCC } = React;

// Query params del deep-link (una sola lectura al cargar el bundle):
//   compose=1 → abre el composer · to/subject → prellenan · exp=EXP-… vincula
//   expediente · doc=<publicId de comprobante> adjunta ese PDF del ERP.
function _crmLeerParamsCompose() {
  try {
    const sp = new URLSearchParams(window.location.search);
    if (sp.get('compose') !== '1') return null;
    return {
      to: sp.get('to') || '',
      subject: sp.get('subject') || '',
      exp: sp.get('exp') || '',
      doc: sp.get('doc') || '',
    };
  } catch (e) { return null; }
}
function _crmLimpiarParamsCompose() {
  try {
    const url = new URL(window.location.href);
    ['compose', 'to', 'subject', 'exp', 'doc'].forEach((k) => url.searchParams.delete(k));
    window.history.replaceState(window.history.state, '', url.pathname + url.search + url.hash);
  } catch (e) { /* la URL no es crítica */ }
}

function CrmComposer({ open, onClose, onSend, initialTo, initialAsunto, initialCc, initialCuerpo, initialAlias, draftId, user }) {
  // Deep-link (?compose=1): fuerza la apertura aunque app.jsx no lo haya pedido.
  const paramsRef = _useRefCC(undefined);
  if (paramsRef.current === undefined) paramsRef.current = _crmLeerParamsCompose();
  const [urlOpen, setUrlOpen] = _useStateCC(() => !!paramsRef.current);
  const abierto = open || urlOpen;

  const [to, setTo] = _useStateCC(initialTo || '');
  const [cc, setCc] = _useStateCC('');
  const [showCc, setShowCc] = _useStateCC(false);
  const [asunto, setAsunto] = _useStateCC(initialAsunto || '');
  const [cuerpo, setCuerpo] = _useStateCC('');
  const [minimized, setMinimized] = _useStateCC(false);
  const [showTpls, setShowTpls] = _useStateCC(false);
  // Vínculo real con el ERP (#28): guarda el publicId (EXP-…) que ya persiste
  // el backend en linked_expediente_id. `expEdit` = combobox visible.
  const [linkedExp, setLinkedExp] = _useStateCC(null);
  const [expEdit, setExpEdit] = _useStateCC(false);
  const [expTexto, setExpTexto] = _useStateCC('');
  const [pickerErp, setPickerErp] = _useStateCC(false);
  // ?doc=<publicId/código> del deep-link: el picker adjunta ESE comprobante solo.
  const [docPreferido, setDocPreferido] = _useStateCC(null);
  const [enviando, setEnviando] = _useStateCC(false);
  const [errorEnvio, setErrorEnvio] = _useStateCC(null);
  // Alias de envío: null = personal (privado, solo lo ven los destinatarios);
  // 'ventas'|'administracion'|'tesoreria' = en nombre del equipo (grupo).
  const [fromAlias, setFromAlias] = _useStateCC(null);
  const textareaRef = _useRefCC(null);
  const fileRef = _useRefCC(null);

  const adj = useCrmAdjuntosSalientes();
  // Autosave real SOLO en "Redactar en limpio": retomar un borrador ya guardado
  // (draftId) no lo re-autosalva — evita un borrador duplicado; app.jsx lo borra
  // al enviar. Ver header.
  const borrador = useCrmBorrador({
    activo: abierto && !draftId,
    hiloId: null,
    datos: { para: to, cc, asunto, cuerpo, alias: fromAlias },
  });

  // El composer queda MONTADO entre aperturas (recibe `open` por prop), así que
  // su estado interno sobrevive al cerrar. Sin este reset, el alias del envío
  // anterior queda pegado y un mail pensado como personal/privado puede salir
  // al grupo sin que el usuario lo note (bug cazado en verificación e2e 02/07).
  _useEffectCC(() => {
    if (!abierto) return;
    // Prioridad de prellenado: deep-link (?compose=1) > props de app.jsx (redactar
    // suelto o retomar un borrador) > vacío. El deep-link solo trae to/subject/
    // exp/doc; cc/cuerpo/alias vienen SIEMPRE de las props (initial*).
    const p = paramsRef.current || {};
    setTo(p.to || initialTo || '');
    setCc(initialCc || '');
    setShowCc(!!(initialCc && initialCc.trim()));
    setAsunto(p.subject || initialAsunto || '');
    setCuerpo(initialCuerpo || '');
    setFromAlias(initialAlias || null);
    setLinkedExp(p.exp || null);
    setExpEdit(false);
    setExpTexto('');
    setMinimized(false);
    setShowTpls(false);
    setPickerErp(false);
    setEnviando(false);
    setErrorEnvio(null);
    adj.limpiar();
    borrador.reiniciar();
    // ?doc=<publicId> → adjuntar ese comprobante del ERP apenas abre (el picker
    // en modo `preferido` lo genera y adjunta solo, sin clicks de más).
    setDocPreferido(p.exp && p.doc ? p.doc : null);
    if (p.exp && p.doc) setPickerErp(true);
    // Los params del deep-link se consumen UNA vez.
    if (paramsRef.current) { _crmLimpiarParamsCompose(); paramsRef.current = null; }
  }, [abierto]);

  if (!abierto) return null;

  const u = user || CRM_USER;
  const nombreCompleto = `${u.nombre || ''} ${u.apellido || ''}`.trim() || u.email || 'Mi usuario';

  const cerrar = () => {
    borrador.flush(); // que las últimas teclas no se pierdan
    if (urlOpen) setUrlOpen(false);
    onClose();
  };

  // Plantillas con variables reales (#33): lo resuelto se inserta YA
  // reemplazado; lo que no se puede saber queda como [completar] visible.
  const applyTpl = (tpl) => {
    setShowTpls(false);
    const pseudoEmail = linkedExp
      ? { linkedExpedienteId: linkedExp, asunto, messages: [] }
      : (asunto ? { asunto, messages: [] } : null);
    crmPrepararPlantilla(tpl, { email: pseudoEmail, user: u }).then(({ asunto: a, cuerpo: c }) => {
      if (!asunto) setAsunto(a);
      setCuerpo((prev) => prev ? prev + '\n\n' + c : c);
      textareaRef.current?.focus();
    });
  };

  const descartarBorrador = () => {
    borrador.descartar();
    adj.limpiar();
    if (urlOpen) setUrlOpen(false);
    onClose();
  };

  const send = () => {
    if (enviando) return;
    const toList = crmParseEmails(to);
    const ccList = crmParseEmails(cc);
    if (!toList.length) { setErrorEnvio('Cargá al menos un destinatario.'); return; }
    setErrorEnvio(null);

    const base = {
      asunto, cuerpo, to: toList, cc: ccList, alias: fromAlias,
      linkedExpedienteId: linkedExp,
    };

    // Con adjuntos: POST directo (no optimista) — los adjuntos viajan en el MISMO
    // body de /api/crm-hilos, que los sube/registra ANTES de mandar el mail y
    // devuelve el hilo ya completo (con adjuntos). El mail nace entero, sin un
    // optimista que muestre adjuntos que todavía no existen.
    if (adj.adjuntos.length) {
      setEnviando(true);
      fetch('/api/crm-hilos', {
        method: 'POST', credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...base, ...crmPayloadAdjuntos(adj.adjuntos) }),
      })
        .then(async (r) => {
          if (r.ok) return r.json();
          const e = await r.json().catch(() => ({}));
          throw new Error(e.error || 'POST /api/crm-hilos → ' + r.status);
        })
        .then((hilo) => {
          const arr = window.CRM_EMAILS || [];
          if (!arr.some((e) => e.id === hilo.id)) arr.unshift(hilo);
          borrador.descartar();
          adj.limpiar();
          setEnviando(false);
          if (onSend) onSend(hilo);
          if (urlOpen) setUrlOpen(false);
          onClose();
        })
        .catch((e) => { setEnviando(false); setErrorEnvio(e.message || 'No se pudo enviar.'); });
      return;
    }

    // Sin adjuntos: mismo camino optimista de siempre (MicosStore.create).
    const payload = {
      ...base,
      // Shape optimista (mismos campos que devuelve GET /api/crm-hilos) para
      // que la bandeja lo pinte YA — MicosStore.create reemplaza esto con la
      // respuesta real del server apenas resuelve.
      snippet: (cuerpo || '').slice(0, 120),
      tags: [], linkedEntityId: null, linkedEntityType: null,
      folder: 'sent', starred: false, unread: false, important: false,
      slaHours: 0, lastFrom: 'me', entityFlags: {}, adjuntos: [],
      messages: [{
        from: { nombre: nombreCompleto, email: u.email || '' },
        to: toList, cc: ccList, fecha: new Date().toISOString(), cuerpo,
        direccion: 'salida', alias: fromAlias, visibilidad: fromAlias ? 'grupo' : 'privada',
      }],
    };
    if (window.MicosStore) window.MicosStore.create('crmHilos', payload, () => borrador.descartar());
    else borrador.descartar();
    if (onSend) onSend(payload);
    if (urlOpen) setUrlOpen(false);
    onClose();
  };

  if (minimized) {
    return (
      <div
        className="fixed bottom-0 right-6 z-50"
        style={{
          width: 320,
          background: 'var(--card)',
          border: '1px solid var(--border)',
          borderTopLeftRadius: 14,
          borderTopRightRadius: 14,
          boxShadow: 'var(--shadow-lg)',
        }}
      >
        <div className="flex items-center gap-2 px-4 py-3 cursor-pointer" onClick={() => setMinimized(false)}>
          <IconPencil size={13} style={{ color: 'var(--accent)' }} />
          <p className="text-[12.5px] font-bold flex-1 truncate" style={{ color: 'var(--foreground)' }}>
            {asunto || 'Sin asunto'}
          </p>
          <button type="button" onClick={(e) => { e.stopPropagation(); setMinimized(false); }} className="cursor-pointer" style={{ color: 'var(--muted-foreground)' }}>
            <IconMaximize size={13} />
          </button>
          <button type="button" onClick={(e) => { e.stopPropagation(); cerrar(); }} className="cursor-pointer" style={{ color: 'var(--muted-foreground)' }}>
            <IconX size={14} />
          </button>
        </div>
      </div>
    );
  }

  return (
    <>
      {/* Backdrop (light, so user still sees the inbox behind) */}
      <div
        className="fixed inset-0 z-40 animate-fade-in"
        style={{ background: 'color-mix(in oklab, var(--foreground) 12%, transparent)' }}
        onClick={cerrar}
      />
      {/* Modal */}
      <div
        className="fixed z-50 flex flex-col animate-scale-in"
        style={{
          bottom: 0,
          right: 32,
          width: 'min(680px, calc(100vw - 64px))',
          height: 'min(680px, calc(100vh - 80px))',
          background: 'var(--card)',
          border: '1px solid var(--border)',
          borderTopLeftRadius: 18,
          borderTopRightRadius: 18,
          boxShadow: 'var(--shadow-elevated)',
          overflow: 'hidden',
        }}
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <div
          className="flex items-center gap-2 px-5 py-3"
          style={{ borderBottom: '1px solid var(--border)', background: 'var(--surface)' }}
        >
          <div className="flex items-center gap-2 flex-1">
            <IconPencil size={14} style={{ color: 'var(--accent)' }} />
            <p className="text-[13px] font-extrabold" style={{ color: 'var(--foreground)' }}>
              {draftId ? 'Editar borrador' : 'Nuevo mensaje'}
            </p>
          </div>
          <button type="button" onClick={() => { borrador.flush(); setMinimized(true); }} className="cursor-pointer" style={{ color: 'var(--muted-foreground)' }} title="Minimizar">
            <IconMinimize size={14} />
          </button>
          <button type="button" onClick={cerrar} className="cursor-pointer" style={{ color: 'var(--muted-foreground)' }} title="Cerrar">
            <IconX size={15} />
          </button>
        </div>

        {/* Fields */}
        <div className="px-5 pt-4">
          {/* From: alias del equipo (grupo, lo ve todo el grupo) o personal
              (privado, solo emisor + destinatarios) */}
          <div className="flex items-center gap-2.5 py-2" style={{ borderBottom: '1px solid color-mix(in oklab, var(--border) 50%, transparent)' }}>
            <span className="text-[11.5px] font-bold uppercase tracking-[0.08em] w-12" style={{ color: 'var(--muted-foreground)' }}>De</span>
            <select
              value={fromAlias || ''}
              onChange={(e) => setFromAlias(e.target.value || null)}
              className="flex-1 bg-transparent outline-none text-[13px] font-semibold"
              style={{ color: 'var(--foreground)' }}
            >
              <option value="">{`${nombreCompleto} — personal`}</option>
              {CRM_ALIASES.map(a => <option key={a.key} value={a.key}>{a.label}</option>)}
            </select>
          </div>
          {!fromAlias && (
            <p className="text-[11px] pt-1 pl-[58px]" style={{ color: 'var(--muted-foreground)' }}>
              Personal — solo lo ven los destinatarios.
            </p>
          )}

          {/* To */}
          <div className="flex items-center gap-2.5 py-2" style={{ borderBottom: '1px solid color-mix(in oklab, var(--border) 50%, transparent)' }}>
            <span className="text-[11.5px] font-bold uppercase tracking-[0.08em] w-12" style={{ color: 'var(--muted-foreground)' }}>Para</span>
            <input
              type="text"
              value={to}
              onChange={(e) => { setTo(e.target.value); if (errorEnvio) setErrorEnvio(null); }}
              placeholder="ejemplo@dominio.com"
              className="flex-1 bg-transparent outline-none text-[13px]"
              style={{ color: 'var(--foreground)' }}
            />
            {!showCc && (
              <button type="button" onClick={() => setShowCc(true)} className="text-[11px] font-bold cursor-pointer" style={{ color: 'var(--muted-foreground)' }}>
                CC
              </button>
            )}
          </div>

          {/* CC */}
          {showCc && (
            <div className="flex items-center gap-2.5 py-2" style={{ borderBottom: '1px solid color-mix(in oklab, var(--border) 50%, transparent)' }}>
              <span className="text-[11.5px] font-bold uppercase tracking-[0.08em] w-12" style={{ color: 'var(--muted-foreground)' }}>CC</span>
              <input
                type="text"
                value={cc}
                onChange={(e) => setCc(e.target.value)}
                placeholder="ejemplo@dominio.com"
                className="flex-1 bg-transparent outline-none text-[13px]"
                style={{ color: 'var(--foreground)' }}
              />
            </div>
          )}

          {/* Asunto */}
          <div className="flex items-center gap-2.5 py-2" style={{ borderBottom: '1px solid color-mix(in oklab, var(--border) 50%, transparent)' }}>
            <span className="text-[11.5px] font-bold uppercase tracking-[0.08em] w-12" style={{ color: 'var(--muted-foreground)' }}>Asunto</span>
            <input
              type="text"
              value={asunto}
              onChange={(e) => setAsunto(e.target.value)}
              placeholder="Asunto"
              className="flex-1 bg-transparent outline-none text-[14px] font-bold"
              style={{ color: 'var(--foreground)' }}
            />
          </div>

          {/* Vínculo real con expediente (#28) — persiste en linked_expediente_id */}
          <div className="flex items-center gap-2.5 py-2.5">
            <span className="text-[11.5px] font-bold uppercase tracking-[0.08em] w-12" style={{ color: 'var(--muted-foreground)' }}>ERP</span>
            {linkedExp ? (
              <span className="inline-flex items-center gap-1.5">
                <span
                  className="font-mono inline-flex items-center gap-1"
                  style={{
                    fontSize: 11.5, fontWeight: 700, color: 'var(--accent)',
                    background: 'color-mix(in oklab, var(--accent) 10%, transparent)',
                    padding: '3px 9px', borderRadius: 999,
                  }}
                >
                  <IconLink size={11} />
                  {linkedExp}
                </span>
                <button
                  type="button"
                  onClick={() => { setLinkedExp(null); setExpTexto(''); }}
                  className="cursor-pointer inline-flex items-center justify-center"
                  style={{ width: 20, height: 20, color: 'var(--muted-foreground)' }}
                  title="Quitar vínculo"
                >
                  <IconX size={12} />
                </button>
              </span>
            ) : expEdit ? (
              <div className="flex-1 max-w-[300px]">
                <ExpedienteCombobox
                  value={expTexto}
                  onChange={setExpTexto}
                  onPick={(e) => { setLinkedExp(e.publicId); setExpEdit(false); setExpTexto(''); }}
                />
              </div>
            ) : (
              <button
                type="button"
                onClick={() => setExpEdit(true)}
                className="flex items-center gap-1.5 text-[12px] font-bold cursor-pointer"
                style={{ color: 'var(--accent)' }}
              >
                <IconLink size={12} />
                Vincular con expediente
              </button>
            )}
          </div>
        </div>

        {/* Body */}
        <textarea
          ref={textareaRef}
          value={cuerpo}
          onChange={(e) => setCuerpo(e.target.value)}
          placeholder="Escribí tu mensaje…"
          className="flex-1 px-5 py-4 outline-none border-none bg-transparent resize-none"
          style={{
            fontFamily: 'inherit',
            fontSize: 13.5,
            lineHeight: 1.65,
            color: 'var(--foreground)',
          }}
        />

        {/* Adjuntos que van a salir con el mensaje */}
        <CrmChipsAdjuntos adjuntos={adj.adjuntos} onQuitar={adj.quitar} error={adj.error} />
        {errorEnvio && (
          <p className="px-5 pb-1 text-[11.5px] font-semibold" style={{ color: 'var(--destructive)' }}>{errorEnvio}</p>
        )}

        {/* Footer */}
        <div
          className="px-5 py-3 flex items-center gap-2 flex-wrap"
          style={{ borderTop: '1px solid var(--border)', background: 'var(--surface)' }}
        >
          <button type="button" onClick={send} disabled={enviando} className="btn btn-primary">
            <IconSend size={14} />
            {enviando ? 'Enviando…' : 'Enviar'}
          </button>
          <input
            ref={fileRef}
            type="file"
            multiple
            className="hidden"
            onChange={(e) => { adj.agregarArchivos(e.target.files); e.target.value = ''; }}
          />
          <button
            type="button"
            onClick={() => fileRef.current && fileRef.current.click()}
            className="btn btn-icon h-9 w-9"
            style={{ background: 'transparent', color: 'var(--muted-foreground)' }}
            title="Adjuntar archivo"
          >
            <IconPaperclip size={15} />
          </button>
          <button
            type="button"
            onClick={() => linkedExp && setPickerErp(true)}
            disabled={!linkedExp}
            className="btn btn-icon h-9 w-9"
            style={{ background: 'transparent', color: linkedExp ? 'var(--accent)' : 'var(--muted-foreground)', opacity: linkedExp ? 1 : 0.5 }}
            title={linkedExp ? 'Adjuntar comprobante del ERP' : 'Vinculá un expediente para adjuntar sus comprobantes'}
          >
            <IconLink size={15} />
          </button>

          {/* Templates */}
          <div className="relative">
            <button
              type="button"
              onClick={() => setShowTpls(o => !o)}
              className="btn btn-icon h-9 w-9"
              style={{ background: showTpls ? 'color-mix(in oklab, var(--accent) 12%, transparent)' : 'transparent', color: showTpls ? 'var(--accent)' : 'var(--muted-foreground)' }}
              title="Plantillas"
            >
              <IconSparkles size={15} />
            </button>
            <CrmPlantillasDropdown open={showTpls} onClose={() => setShowTpls(false)} onPick={applyTpl} />
          </div>

          <span className="ml-auto">
            <CrmEstadoBorrador estado={borrador.estado} />
          </span>
          <button
            type="button"
            onClick={descartarBorrador}
            className="btn btn-icon h-9 w-9"
            style={{ background: 'transparent', color: 'var(--muted-foreground)' }}
            title="Descartar borrador"
          >
            <IconTrash size={15} />
          </button>
        </div>
      </div>

      {/* Picker de comprobantes del ERP (expediente vinculado). `preferido`
          solo cuando vino ?doc= en el deep-link — adjunta ese PDF directo. */}
      <CrmPickerComprobantes
        open={pickerErp}
        expRef={linkedExp}
        preferido={docPreferido}
        onClose={() => { setPickerErp(false); setDocPreferido(null); }}
        onPick={(item) => { adj.agregarItem(item); setDocPreferido(null); }}
      />
    </>
  );
}

Object.assign(window, { CrmComposer });
