// ============ AcademIA8 · Consola — componentes UI compartidos ============
const { useState, useRef, useEffect } = React;

// ---------- Iconos (línea, ~1.8px, esquinas redondeadas — estilo de marca) ----------
const PATHS = {
  courses:'M4 5.5A1.5 1.5 0 0 1 5.5 4H18a2 2 0 0 1 2 2v13.5M4 5.5V18a2 2 0 0 0 2 2h14M4 5.5A1.5 1.5 0 0 0 4 8.5H18',
  layers:'M12 3 2 8l10 5 10-5-10-5ZM2 12l10 5 10-5M2 16l10 5 10-5',
  publish:'M12 19V6M5 12l7-7 7 7',
  plus:'M12 5v14M5 12h14',
  edit:'M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z',
  trash:'M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6',
  drag:'M9 5h.01M9 12h.01M9 19h.01M15 5h.01M15 12h.01M15 19h.01',
  up:'M18 15l-6-6-6 6',
  down:'M6 9l6 6 6-6',
  check:'M20 6 9 17l-5-5',
  x:'M18 6 6 18M6 6l12 12',
  text:'M4 6h16M4 12h16M4 18h10',
  video:'M15 10l4.5-2.6v9.2L15 14M3 6h12v12H3z',
  audio:'M9 18V5l10-2v13M9 18a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM19 16a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z',
  image:'M3 5h18v14H3zM3 15l5-5 4 4 3-3 6 6',
  question:'M9.1 9a3 3 0 1 1 5 2.2c-.9.8-2.1 1.3-2.1 2.8M12 17h.01',
  search:'M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14ZM21 21l-4.3-4.3',
  clock:'M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18ZM12 7v5l3 2',
  calendar:'M3 5h18v16H3zM3 10h18M8 3v4M16 3v4',
  eye:'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12ZM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z',
  alert:'M12 3 2 20h20L12 3ZM12 10v4M12 17h.01',
  play:'M6 4l14 8-14 8V4Z',
  upload:'M12 15V3M8 7l4-4 4 4M4 15v4a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-4',
  refresh:'M4 9a8 8 0 0 1 14-3l2 2M20 15a8 8 0 0 1-14 3l-2-2M18 4v4h-4M6 20v-4h4',
  chevright:'M9 6l6 6-6 6',
  settings:'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM19.4 13.5a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 1 1-4 0v-.1a1.6 1.6 0 0 0-2.7-1.1l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.6 1.6 0 0 0-1.1-2.7H3a2 2 0 1 1 0-4h.1a1.6 1.6 0 0 0 1.1-2.7l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.6 1.6 0 0 0 2.7-1.1V3a2 2 0 1 1 4 0v.1a1.6 1.6 0 0 0 2.7 1.1l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.6 1.6 0 0 0-.3 1.8Z',
  send:'M22 2 11 13M22 2l-7 20-4-9-9-4 20-7Z',
  copy:'M9 9h11v11H9zM5 15H4V4h11v1',
  help:'M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18ZM9.6 9a2.4 2.4 0 1 1 3.4 2.2c-.8.4-1 1-1 1.7M12 17h.01',
  doc:'M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8ZM14 3v5h5M9 13h6M9 17h4',
  chat:'M21 12a8 8 0 0 1-8 8 8.5 8.5 0 0 1-3.6-.8L3 20l1-4.4A8 8 0 1 1 21 12ZM8 11h.01M12 11h.01M16 11h.01',
  infinity:'M6 8a4 4 0 1 0 0 8c2 0 3.2-1.5 4-3 1.2-2.3 2.2-5 6-5a4 4 0 0 1 0 8c-3.8 0-4.8-2.7-6-5-.8-1.5-2-3-4-3Z',
  sort:'M4 7h11M4 12h7M4 17h4M18 5v14M18 19l-3.5-3.5M18 19l3.5-3.5',
  logout:'M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4M10 17l-5-5 5-5M5 12h11',
  sidebar:'M4 4h16v16H4zM9 4v16',
  panelclose:'M4 4h16v16H4zM9 4v16M15 9l-2 3 2 3',
  panelopen:'M4 4h16v16H4zM9 4v16M13 9l2 3-2 3',
  money:'M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6',
};
function Icon({ name, style }){
  const d = PATHS[name] || '';
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={style}>
      {d.split('M').filter(Boolean).map((seg,i)=><path key={i} d={'M'+seg} />)}
    </svg>
  );
}

const FRAG_ICON = { texto:'text', video:'video', audio:'audio', imagen:'image', documento:'doc' };
const FRAG_LABEL = { texto:'Texto', video:'Video', audio:'Audio', imagen:'Imagen', documento:'Documento' };

// ---------- Botón ----------
function Btn({ variant='ghost', size, icon, iconRight, children, ...rest }){
  const cls = `btn btn-${variant}${size==='sm'?' btn-sm':''}`;
  return (
    <button className={cls} {...rest}>
      {icon && <Icon name={icon} />}
      {children}
      {iconRight && <Icon name={iconRight} />}
    </button>
  );
}
function IconBtn({ icon, danger, title, ...rest }){
  return <button className={`btn-icon${danger?' danger':''}`} title={title} {...rest}><Icon name={icon} /></button>;
}

// ---------- Pill de estado del curso ----------
function StatusPill({ status }){
  if (status==='draft-only') return <span className="pill pill-draft"><span className="dt"></span>Borrador · sin publicar</span>;
  if (status==='published-dirty') return <span className="pill pill-dirty"><span className="dt"></span>Cambios sin publicar</span>;
  return <span className="pill pill-pub"><span className="dt"></span>Publicado</span>;
}

// ---------- Toggle global Borrador / Publicado ----------
function ViewToggle({ value, onChange, disabled }){
  return (
    <div className="viewtoggle" title={disabled ? 'Este curso todavía no se publicó' : 'Cambiá entre tu borrador y lo que ve el alumno'}>
      <span className="hint">Estás viendo</span>
      <button data-v="borrador" className={value==='borrador'?'on':''} onClick={()=>onChange('borrador')}>
        <span className="dt"></span>Borrador
      </button>
      <button data-v="publicado" className={value==='publicado'?'on':''} onClick={()=>!disabled&&onChange('publicado')} disabled={disabled}>
        <span className="dt"></span>Publicado
      </button>
    </div>
  );
}

// ---------- Modal ----------
function Modal({ title, subtitle, icon, danger, wide, onClose, children, foot }){
  useEffect(()=>{
    const h = (e)=>{ if(e.key==='Escape') onClose(); };
    window.addEventListener('keydown', h);
    return ()=>window.removeEventListener('keydown', h);
  },[]);
  return (
    <div className="modal-scrim" onMouseDown={(e)=>{ if(e.target===e.currentTarget) onClose(); }}>
      <div className={`modal${wide?' wide':''}`}>
        <div className={`modal-head${danger?' danger':''}`}>
          {icon && <div className="mh-ic"><Icon name={icon} /></div>}
          <div className="grow">
            <div className="mh-t">{title}</div>
            {subtitle && <div className="mh-s">{subtitle}</div>}
          </div>
          <IconBtn icon="x" className="mh-x" onClick={onClose} title="Cerrar" />
        </div>
        <div className="modal-body">{children}</div>
        {foot && <div className="modal-foot">{foot}</div>}
      </div>
    </div>
  );
}

// ---------- Field ----------
function Field({ label, optional, hint, children }){
  return (
    <div className="field">
      {label && <label>{label}{optional && <span className="opt-tag">opcional</span>}</label>}
      {children}
      {hint && <div className="hint">{hint}</div>}
    </div>
  );
}

// ---------- Toast ----------
function Toast({ msg }){
  return <div className="toast ok"><Icon name="check" />{msg}</div>;
}

// ---------- Confirmar borrado ----------
function ConfirmDelete({ what, detail, onClose, onConfirm }){
  return (
    <Modal danger icon="trash" title={`Borrar ${what}`}
      subtitle="Borrar es definitivo por ahora — no hay papelera ni forma de recuperarlo."
      onClose={onClose}
      foot={<><div className="spacer"></div><Btn variant="subtle" onClick={onClose}>Cancelar</Btn><Btn variant="magenta" icon="trash" onClick={onConfirm}>Sí, borrar</Btn></>}>
      <p style={{fontSize:'13.5px', lineHeight:1.6, color:'var(--grafito)'}}>{detail}</p>
    </Modal>
  );
}

// ---------- HelpTip: ícono ? + popover con reglas (reutilizable) ----------
function HelpTip({ title, children, align }){
  const [open,setOpen]=useState(false);
  return (
    <span className={`helptip${align==='right'?' ht-r':''}`} onMouseEnter={()=>setOpen(true)} onMouseLeave={()=>setOpen(false)}>
      <button type="button" className="helptip-btn" aria-label="Ayuda" onClick={(e)=>{ e.preventDefault(); e.stopPropagation(); setOpen(o=>!o); }}><Icon name="help" /></button>
      {open && (
        <span className="helptip-pop" onClick={e=>e.stopPropagation()}>
          {title && <span className="ht-title">{title}</span>}
          <span className="ht-body">{children}</span>
        </span>
      )}
    </span>
  );
}

// ---------- Indicador de sesión (usuario logueado vía Cognito) ----------
function SessionMenu({ user, onLogout }){
  const [open,setOpen]=useState(false);
  const ref=useRef(null);
  useEffect(()=>{
    if(!open) return;
    const h=(e)=>{ if(ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown',h);
    return ()=>document.removeEventListener('mousedown',h);
  },[open]);
  return (
    <div className={`session${open?' open':''}`} ref={ref}>
      <button className="session-btn" onClick={()=>setOpen(o=>!o)} title={user.email}>
        <span className="sav">{user.initials}</span>
        <span className="snm">{user.name}</span>
        <Icon name="down" style={{width:14,height:14}} />
      </button>
      {open && (
        <div className="session-menu">
          <div className="sm-id">
            <span className="sav">{user.initials}</span>
            <div style={{minWidth:0}}>
              <div className="sm-nm">{user.name}</div>
              <div className="sm-em">{user.email}</div>
            </div>
          </div>
          <button className="sm-item" onClick={()=>{ setOpen(false); onLogout&&onLogout(); }}>
            <Icon name="logout" /> Cerrar sesión
          </button>
        </div>
      )}
    </div>
  );
}

// ---------- Estado de compresión de video (polling async post-upload) ----------
function CompressionStatusLine({ status, info }){
  if (status==='procesando') return (
    <span className="hint" style={{display:'flex',alignItems:'center',gap:'5px',color:'var(--gris)'}}>
      <Icon name="refresh" style={{width:13,height:13}} /> Comprimiendo video para WhatsApp (hasta 16 MB)…
    </span>
  );
  if (status==='listo') return (
    <span className="hint" style={{display:'flex',alignItems:'center',gap:'5px',color:'var(--verde-prof)'}}>
      <Icon name="check" style={{width:13,height:13}} /> Comprimido{info && info.tamano_final_bytes ? ` · ${(info.tamano_final_bytes/1024/1024).toFixed(1)} MB` : ''}
    </span>
  );
  if (status==='error') return (
    <span className="hint" style={{display:'flex',alignItems:'center',gap:'5px',color:'var(--magenta)'}}>
      <Icon name="alert" style={{width:13,height:13}} /> No se pudo comprimir{info && info.motivo ? `: ${info.motivo}` : ''}
    </span>
  );
  return null;
}

Object.assign(window, {
  Icon, FRAG_ICON, FRAG_LABEL, Btn, IconBtn, StatusPill, ViewToggle, Modal, Field, Toast, ConfirmDelete, HelpTip, SessionMenu, CompressionStatusLine,
  useState, useRef, useEffect,
});
