// ============ AcademIA8 · Consola — Campañas · Vista CONTACTOS ============
// Tabla paginada + buscar/filtrar + importar (CSV o pegar) + editar etiquetas + eliminar.

const CONTACT_COLS = '1.7fr 1.9fr 1.8fr 128px 62px';

function estadoPillClass(e){ return e==='activo'?'pill-activo':e==='dado_de_baja'?'pill-baja':'pill-rebotado'; }

// ---------- parser de filas (CSV o texto pegado) ----------
function parseContactRows(text){
  const lines = text.split(/\r?\n/).map(l=>l.trim()).filter(Boolean);
  if(!lines.length) return [];
  const delim = (lines[0].includes(';') && !lines[0].includes(',')) ? ';' : ',';
  const first = lines[0].toLowerCase();
  const hasHeader = first.includes('email') || first.includes('correo') || first.includes('mail');
  const body = hasHeader ? lines.slice(1) : lines;
  return body.map(l=>{
    const cells = l.split(delim).map(c=>c.trim().replace(/^["']|["']$/g,''));
    // heurística: la celda que parece email
    let email = cells.find(c=>/@/.test(c)) || cells[0] || '';
    const rest = cells.filter(c=>c!==email);
    const [nombre='', apellido=''] = rest;
    const valido = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    return { email, nombre, apellido, valido };
  });
}

// ---------- editor de etiquetas de UN contacto ----------
function EditTagsModal({ contact, tags, onClose, onSave, onCreateTag }){
  const [sel, setSel] = useState(contact.etiquetas.slice());
  const [nueva, setNueva] = useState('');
  const [allTags, setAllTags] = useState(tags);
  const toggle = (id)=> setSel(s=> s.includes(id) ? s.filter(x=>x!==id) : [...s, id]);
  const crear = async ()=>{
    const n = nueva.trim(); if(!n) return;
    const t = await onCreateTag(n);
    setAllTags(a=> a.find(x=>x.id===t.id)?a:[...a,t]);
    setSel(s=> s.includes(t.id)?s:[...s,t.id]);
    setNueva('');
  };
  return (
    <Modal icon="edit" title="Editar etiquetas"
      subtitle={`${contact.nombre} ${contact.apellido} · ${contact.email}`}
      onClose={onClose}
      foot={<><div className="spacer"></div><Btn variant="subtle" onClick={onClose}>Cancelar</Btn><Btn variant="primary" icon="check" onClick={()=>onSave(sel)}>Guardar</Btn></>}>
      <Field label="Etiquetas del contacto">
        <div className="tag-edit-list">
          {allTags.map(t=>(
            <button key={t.id} className={`rcpt-tag${sel.includes(t.id)?' on':''}`} onClick={()=>toggle(t.id)}>
              <span className="rcpt-chk">{sel.includes(t.id) && <Icon name="check" />}</span>
              {t.nombre}
            </button>
          ))}
        </div>
      </Field>
      <Field label="Crear una etiqueta nueva" optional>
        <div className="imp-newtag">
          <input placeholder="Nombre de la etiqueta…" value={nueva}
            onChange={e=>setNueva(e.target.value)} onKeyDown={e=>{ if(e.key==='Enter'){ e.preventDefault(); crear(); } }} />
          <Btn variant="ghost" icon="plus" onClick={crear}>Crear</Btn>
        </div>
      </Field>
    </Modal>
  );
}

// ---------- importador ----------
function ImportModal({ tags, onClose, onImported, onCreateTag, notify }){
  const [mode, setMode] = useState('csv'); // csv | pegar
  const [rows, setRows] = useState([]);
  const [fileName, setFileName] = useState('');
  const [pasted, setPasted] = useState('');
  const [selTags, setSelTags] = useState([]);
  const [allTags, setAllTags] = useState(tags);
  const [nueva, setNueva] = useState('');
  const [over, setOver] = useState(false);
  const [busy, setBusy] = useState(false);
  const [result, setResult] = useState(null);
  const fileRef = useRef(null);

  const readFile = (file)=>{
    if(!file) return;
    setFileName(file.name);
    const r = new FileReader();
    r.onload = ()=> setRows(parseContactRows(String(r.target.result||'')));
    r.readAsText(file);
  };
  useEffect(()=>{ if(mode==='pegar') setRows(parseContactRows(pasted)); },[pasted, mode]);

  const toggleTag = (id)=> setSelTags(s=> s.includes(id)?s.filter(x=>x!==id):[...s,id]);
  const crearTag = async ()=>{
    const n = nueva.trim(); if(!n) return;
    const t = await onCreateTag(n);
    setAllTags(a=> a.find(x=>x.id===t.id)?a:[...a,t]);
    setSelTags(s=> s.includes(t.id)?s:[...s,t.id]);
    setNueva('');
  };

  const validas = rows.filter(r=>r.valido);
  const invalidas = rows.length - validas.length;

  // Resultado del import: creados/actualizados + filas omitidas (nuevo respecto del mock).
  if (result){
    const skipped = result.skipped || [];
    const skpCols = '70px 1.4fr 1.6fr';
    return (
      <Modal wide icon="check" title="Importación completa"
        subtitle="Así quedó el lote que importaste."
        onClose={onClose}
        foot={<><div className="spacer"></div><Btn variant="primary" icon="check" onClick={onClose}>Listo</Btn></>}>
        <div style={{display:'flex',gap:'12px',marginBottom: skipped.length?'18px':'2px'}}>
          {[['creados',result.creados],['actualizados',result.actualizados],['omitidos',skipped.length]].map(([l,n])=>(
            <div key={l} style={{flex:1,background:'#fff',border:'1px solid var(--linea,#e7e3da)',borderRadius:'12px',padding:'14px 16px'}}>
              <div style={{fontSize:'26px',fontWeight:800,lineHeight:1,color: (l==='omitidos'&&skipped.length)?'var(--magenta)':'var(--tinta,#0A0440)'}}>{Number(n||0).toLocaleString('es-AR')}</div>
              <div style={{fontSize:'12px',color:'var(--gris)',fontWeight:600,marginTop:'4px'}}>{l}</div>
            </div>
          ))}
        </div>
        {skipped.length>0 && (
          <Field label={`Filas omitidas (${skipped.length})`} hint="No se importaron por el motivo indicado. Corregílas y volvé a importar solo esas.">
            <div className="imp-preview">
              <div className="imp-preview-b">
                <div className="imp-prow head" style={{gridTemplateColumns:skpCols}}><span>Línea</span><span>Email</span><span>Motivo</span></div>
                {skipped.slice(0,100).map((s,i)=>(
                  <div key={i} className="imp-prow bad" style={{gridTemplateColumns:skpCols}}>
                    <span>{s.line!=null?s.line:'—'}</span>
                    <span className="ip-em">{s.email||'—'}</span>
                    <span>{s.reason||'—'}</span>
                  </div>
                ))}
              </div>
            </div>
          </Field>
        )}
      </Modal>
    );
  }

  const importar = async ()=>{
    if(!validas.length){ notify('No hay filas válidas para importar'); return; }
    if(!selTags.length){ notify('Elegí al menos una etiqueta para el lote'); return; }
    setBusy(true);
    try{
      const res = await CampAPI.importarContactos(validas, selTags);
      setResult(res);
      onImported(res); // refresca la lista de fondo sin cerrar el modal
    }catch(e){ notify(e.message||'No se pudo importar'); }
    setBusy(false);
  };

  return (
    <Modal wide icon="upload" title="Importar contactos"
      subtitle="Subí un CSV (email, nombre, apellido) o pegá una lista. Las etiquetas que elijas se aplican a todo el lote."
      onClose={onClose}
      foot={<>
        <div className="spacer"></div>
        <Btn variant="subtle" onClick={onClose}>Cancelar</Btn>
        <Btn variant="magenta" icon="upload" disabled={!validas.length || !selTags.length || busy}
          onClick={importar}>{busy?'Importando…':`Importar ${validas.length||''} contacto${validas.length===1?'':'s'}`}</Btn>
      </>}>
      <div className="imp-modes">
        <button className={`imp-mode${mode==='csv'?' on':''}`} onClick={()=>setMode('csv')}>
          <Icon name="doc" /><span className="imp-mode-t">Subir CSV</span>
        </button>
        <button className={`imp-mode${mode==='pegar'?' on':''}`} onClick={()=>setMode('pegar')}>
          <Icon name="text" /><span className="imp-mode-t">Pegar lista</span>
        </button>
      </div>

      {mode==='csv' && !fileName && (
        <div className={`imp-drop${over?' over':''}`}
          onClick={()=>fileRef.current?.click()}
          onDragOver={e=>{e.preventDefault();setOver(true);}}
          onDragLeave={()=>setOver(false)}
          onDrop={e=>{e.preventDefault();setOver(false);readFile(e.dataTransfer.files[0]);}}>
          <div className="imp-drop-ic"><Icon name="upload" /></div>
          <div className="imp-drop-t">Arrastrá tu CSV o hacé clic para elegirlo</div>
          <div className="imp-drop-s">Columnas: email, nombre, apellido · con o sin encabezado</div>
          <input ref={fileRef} type="file" accept=".csv,text/csv,text/plain" style={{display:'none'}}
            onChange={e=>readFile(e.target.files[0])} />
        </div>
      )}
      {mode==='csv' && fileName && (
        <div className="imp-file">
          <span className="iic"><Icon name="doc" /></span>
          <div style={{flex:1,minWidth:0}}>
            <div className="cell-strong">{fileName}</div>
            <div className="cell-sub">{rows.length} fila{rows.length===1?'':'s'} leída{rows.length===1?'':'s'}</div>
          </div>
          <IconBtn icon="x" title="Quitar archivo" onClick={()=>{setFileName('');setRows([]);}} />
        </div>
      )}
      {mode==='pegar' && (
        <Field label="Pegá una dirección por línea (o email,nombre,apellido)">
          <textarea className="html-code" style={{minHeight:'120px'}} placeholder={"ana@gmail.com, Ana, Pérez\njuan@hotmail.com, Juan, Gómez"}
            value={pasted} onChange={e=>setPasted(e.target.value)} />
        </Field>
      )}

      {rows.length>0 && (
        <div className="imp-preview">
          <div className="imp-preview-h">
            <span>Vista previa</span>
            <span>{validas.length} válida{validas.length===1?'':'s'}{invalidas>0 && ` · ${invalidas} con error`}</span>
          </div>
          <div className="imp-preview-b">
            <div className="imp-prow head"><span>Email</span><span>Nombre</span><span>Apellido</span></div>
            {rows.slice(0,60).map((r,i)=>(
              <div key={i} className={`imp-prow${r.valido?'':' bad'}`}>
                <span className="ip-em">{r.email||'—'}</span>
                <span>{r.nombre||'—'}</span>
                <span>{r.apellido||'—'}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      <Field label="Etiquetas para todo el lote" hint="Se agregan a cada contacto importado. Podés elegir varias o crear una nueva.">
        <div className="imp-tagpick">
          {allTags.map(t=>(
            <button key={t.id} className={`rcpt-tag${selTags.includes(t.id)?' on':''}`} onClick={()=>toggleTag(t.id)}>
              <span className="rcpt-chk">{selTags.includes(t.id) && <Icon name="check" />}</span>
              {t.nombre}
            </button>
          ))}
        </div>
        <div className="imp-newtag">
          <input placeholder="Crear etiqueta nueva (ej. Curso de Ventas)…" value={nueva}
            onChange={e=>setNueva(e.target.value)} onKeyDown={e=>{ if(e.key==='Enter'){ e.preventDefault(); crearTag(); } }} />
          <Btn variant="ghost" icon="plus" onClick={crearTag}>Crear</Btn>
        </div>
        {selTags.length===0 && <div style={{marginTop:'8px',fontSize:'12px',color:'var(--magenta)',fontWeight:600}}>Elegí o creá al menos una etiqueta — el backend la exige para importar.</div>}
      </Field>
    </Modal>
  );
}

// ---------- vista principal ----------
function ContactsView({ notify }){
  const [tags, setTags] = useState([]);
  const [tagMap, setTagMap] = useState({});
  const [resumen, setResumen] = useState(null);
  const [data, setData] = useState({ items:[], nextCursor:null, prevCursor:null, pageSize:25 });
  const [loading, setLoading] = useState(true);
  const [etq, setEtq] = useState('todas');
  const curRef = useRef(null);
  const stackRef = useRef([]); // pila de cursores visitados (el backend no da prevCursor)
  const [hasPrev, setHasPrev] = useState(false);
  const [editing, setEditing] = useState(null);
  const [deleting, setDeleting] = useState(null);
  const [importing, setImporting] = useState(false);

  const loadTags = async ()=>{ try{ const t = await CampAPI.listarEtiquetas(); setTags(t); const m={}; t.forEach(x=>m[x.id]=x.nombre); setTagMap(m); }catch(e){ /* no crítico */ } };
  const loadResumen = async ()=>{ try{ setResumen(await CampAPI.resumenContactos()); }catch(e){ /* no crítico */ } };
  const loadList = async (cursor=curRef.current)=>{
    curRef.current = cursor;
    setLoading(true);
    try{
      const res = await CampAPI.listarContactos({ etiqueta:etq, cursor, pageSize:25 });
      setData(res);
    }catch(e){ notify(e.message||'No se pudieron cargar los contactos'); }
    setLoading(false);
  };

  useEffect(()=>{ loadTags(); loadResumen(); },[]);
  // el filtro por etiqueta (soportado por el backend) resetea el cursor y la pila
  useEffect(()=>{ stackRef.current=[]; setHasPrev(false); loadList(null); },[etq]);

  const goNext = ()=>{ if(!data.nextCursor) return; stackRef.current.push(curRef.current); setHasPrev(true); loadList(data.nextCursor); };
  const goPrev = ()=>{ const prev = stackRef.current.pop(); setHasPrev(stackRef.current.length>0); loadList(prev||null); };

  const refreshAll = ()=>{ loadList(); loadResumen(); };

  const saveTags = async (etiquetas)=>{
    await CampAPI.actualizarContacto(editing.id, { etiquetas });
    setEditing(null); notify('Etiquetas actualizadas'); refreshAll();
  };
  const doDelete = async ()=>{
    await CampAPI.eliminarContacto(deleting.id);
    setDeleting(null); notify('Contacto eliminado'); refreshAll();
  };
  const createTag = async (n)=>{ const t = await CampAPI.crearEtiqueta(n); await loadTags(); return t; };

  return (
    <div>
      {/* resumen */}
      {resumen && (
        <div className="cmp-stats">
          <span className="cmp-stat"><b>{resumen.total.toLocaleString('es-AR')}</b> contactos</span>
          <span className="cmp-stat"><span className="cs-dot" style={{background:'var(--verde-prof)'}}></span><b>{resumen.activos.toLocaleString('es-AR')}</b> activos</span>
          <span className="cmp-stat"><span className="cs-dot" style={{background:'var(--gris)'}}></span>{resumen.baja} dados de baja</span>
          <span className="cmp-stat"><span className="cs-dot" style={{background:'var(--draft)'}}></span>{resumen.rebote} rebotados</span>
        </div>
      )}

      {/* toolbar — solo filtro por etiqueta (lo único que soporta el backend).
          Búsqueda de texto y filtro por estado se ocultaron: eran page-local con
          paginación (resultado engañoso). Si el uso real los pide, irán al backend. */}
      <div className="list-toolbar">
        <select className="tbl-select" value={etq} onChange={e=>setEtq(e.target.value)}>
          <option value="todas">Todas las etiquetas</option>
          {tags.map(t=><option key={t.id} value={t.id}>{t.nombre}</option>)}
        </select>
        <div style={{marginLeft:'auto'}}>
          <Btn variant="primary" icon="upload" onClick={()=>setImporting(true)}>Importar contactos</Btn>
        </div>
      </div>

      {/* tabla */}
      <div className="tbl">
        <div className="tbl-head">
          <div className="tbl-row" style={{gridTemplateColumns:CONTACT_COLS}}>
            <div className="tbl-cell">Contacto</div>
            <div className="tbl-cell">Email</div>
            <div className="tbl-cell">Etiquetas</div>
            <div className="tbl-cell">Estado</div>
            <div className="tbl-cell right">Acciones</div>
          </div>
        </div>
        <div className="tbl-body">
          {loading ? (
            <div className="cmp-loading"><span className="cmp-spin"></span>Cargando contactos…</div>
          ) : data.items.length===0 ? (
            <div className="empty-state" style={{padding:'54px 20px'}}>
              <div className="es-ic"><Icon name="search" /></div>
              <h3>Sin resultados</h3>
              <p>No hay contactos con esta etiqueta. Probá con otra o importá contactos nuevos.</p>
            </div>
          ) : data.items.map(c=>(
            <div key={c.id} className="tbl-row" style={{gridTemplateColumns:CONTACT_COLS}}>
              <div className="tbl-cell">
                <div className="cell-name">{c.nombre} {c.apellido}</div>
              </div>
              <div className="tbl-cell"><div className="cell-mono">{c.email}</div></div>
              <div className="tbl-cell">
                <div className="etq-cell">
                  {c.etiquetas.slice(0,2).map(id=>(
                    <span key={id} className="etq"><span className="etq-dot"></span><span className="etq-txt">{tagMap[id]||'—'}</span></span>
                  ))}
                  {c.etiquetas.length>2 && <span className="etq-more">+{c.etiquetas.length-2}</span>}
                  {c.etiquetas.length===0 && <span className="etq-none">sin etiquetas</span>}
                </div>
              </div>
              <div className="tbl-cell">
                <span className={`pill ${estadoPillClass(c.estado)}`}><span className="dt"></span>{CampAPI.ESTADO_CONTACTO[c.estado]}</span>
              </div>
              <div className="tbl-cell">
                <div className="tbl-actions">
                  <IconBtn icon="edit" title="Editar etiquetas" onClick={()=>setEditing(c)} />
                  <IconBtn icon="trash" danger title="Eliminar contacto" onClick={()=>setDeleting(c)} />
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* paginación por cursor (Anterior / Siguiente — sin número de página) */}
      {!loading && data.items.length>0 && (data.nextCursor || hasPrev) && (
        <div className="pager">
          <div className="pager-info">Mostrando <b>{data.items.length}</b> contacto{data.items.length===1?'':'s'} en esta página</div>
          <div className="pager-ctl">
            <button className="pager-btn" disabled={!hasPrev} onClick={goPrev}><Icon name="chevright" style={{transform:'rotate(180deg)'}} />Anterior</button>
            <button className="pager-btn" disabled={!data.nextCursor} onClick={goNext}>Siguiente<Icon name="chevright" /></button>
          </div>
        </div>
      )}

      {editing && <EditTagsModal contact={editing} tags={tags} onClose={()=>setEditing(null)} onSave={saveTags} onCreateTag={createTag} />}
      {deleting && <ConfirmDelete what="contacto"
        detail={`Vas a eliminar a ${deleting.nombre} ${deleting.apellido} (${deleting.email}). No recibirá más campañas.`}
        onClose={()=>setDeleting(null)} onConfirm={doDelete} />}
      {importing && <ImportModal tags={tags} notify={notify} onCreateTag={createTag}
        onClose={()=>setImporting(false)}
        onImported={(res)=>{ notify(`${res.creados} creados · ${res.actualizados} actualizados${res.skipped&&res.skipped.length?` · ${res.skipped.length} omitidos`:''}`); loadTags(); refreshAll(); }} />}
    </div>
  );
}

Object.assign(window, { ContactsView, ImportModal, EditTagsModal, parseContactRows });
