// ============================================================
// Módulo Edición - con cortes horarios 11am / 1pm / 4pm / 6pm
// ============================================================
const CORTES = [
  { key: 'c11', hora: '11:00', label: 'Corte AM' },
  { key: 'c13', hora: '13:00', label: 'Pre-comida' },
  { key: 'c16', hora: '16:00', label: 'Post-comida' },
  { key: 'c18', hora: '18:00', label: 'Cierre' },
];

const EdicionLocal = ({ libros, currentUser, onUpdate, onSelectBook }) => {
  const [editando, setEditando] = useState(null);
  const [imagenes, setImagenes] = useState('');
  const [cortesForm, setCortesForm] = useState({ c11: '', c13: '', c16: '', c18: '' });

  // Cola FIFO: libros digitalizados ordenados por fecha, asignados al editor o disponibles
  const misEnCurso = libros.filter(l => l.estatus === 'en_edicion' && l.editadoPor === currentUser.id);
  const disponibles = libros.filter(l => l.estatus === 'digitalizado')
    .sort((a, b) => a.fechaDigitalizacion.localeCompare(b.fechaDigitalizacion));

  const misEditados = libros.filter(l =>
    l.editadoPor === currentUser.id &&
    ['editado','en_cc','aceptado','rechazado','en_conversion','finalizado'].includes(l.estatus)
  );

  // Producción de hoy (cortes)
  const hoyEditados = misEditados.filter(l => l.fechaEdicion === '2026-08-02');
  const cortesHoy = { c11: 0, c13: 0, c16: 0, c18: 0 };
  hoyEditados.forEach(l => {
    if (l.cortes) {
      cortesHoy.c11 += l.cortes.c11 || 0;
      cortesHoy.c13 += l.cortes.c13 || 0;
      cortesHoy.c16 += l.cortes.c16 || 0;
      cortesHoy.c18 += l.cortes.c18 || 0;
    }
  });
  const totalCortesHoy = cortesHoy.c11 + cortesHoy.c13 + cortesHoy.c16 + cortesHoy.c18;

  // Hora "actual" simulada
  const horaActual = 15; // 3 PM
  const cortesEsperados = [11, 13, 16, 18];
  const cortesCompletados = cortesEsperados.filter(h => h <= horaActual).length;

  const tomarLibro = (libro) => {
    onUpdate(libro.cons, { estatus: 'en_edicion', editadoPor: currentUser.id });
  };

  const abrirRegistro = (libro) => {
    setEditando(libro);
    setImagenes(libro.imagenesResultantes?.toString() || '');
    setCortesForm({ c11: '', c13: '', c16: '', c18: '' });
  };

  const finalizarEdicion = () => {
    if (!editando) return;
    const n = parseInt(imagenes, 10);
    if (isNaN(n) || n <= 0) return;
    onUpdate(editando.cons, {
      estatus: 'editado',
      fechaEdicion: '2026-08-02',
      editadoPor: currentUser.id,
      imagenesEditadas: n,
      cortes: {
        c11: parseInt(cortesForm.c11) || 0,
        c13: parseInt(cortesForm.c13) || 0,
        c16: parseInt(cortesForm.c16) || 0,
        c18: parseInt(cortesForm.c18) || 0,
      },
    });
    setEditando(null);
    setImagenes('');
  };

  return (
    <div className="stack">
      {/* Timeline de cortes de hoy */}
      <div className="card">
        <div className="card-header">
          <Icon name="clock" size={16} style={{ color: 'var(--text-2)' }}/>
          <div>
            <div className="card-title">Registro de productividad de hoy · Sábado 02 Agosto</div>
            <div className="card-subtitle">Jornada L-V 9:00-18:00 · Comida 14:00-15:00 · Cortes en 11:00, 13:00, 16:00 y 18:00</div>
          </div>
          <div className="spacer"/>
          <div className="row" style={{ gap: 4 }}>
            <div className="badge-dot" style={{ background: 'var(--success)' }}/>
            <span className="text-sm text-2">Hora simulada: 15:00</span>
          </div>
        </div>
        <div className="card-body">
          <div className="timeline">
            {CORTES.map((c, i) => {
              const val = cortesHoy[c.key];
              const hora = parseInt(c.hora);
              const isDone = hora <= horaActual;
              const isActive = false; // ninguno activo en este demo
              return (
                <div className="timeline-node" key={c.key}>
                  <div className={`timeline-dot ${isDone ? 'done' : ''} ${isActive ? 'active' : ''}`}>
                    {isDone ? '✓' : i + 1}
                  </div>
                  <div className="timeline-hour">{c.hora}</div>
                  <div className="timeline-count">{val}</div>
                  <div className="timeline-label">{c.label}</div>
                </div>
              );
            })}
          </div>
          <div style={{ marginTop: 20, padding: 14, background: 'var(--surface-2)', borderRadius: 8 }}>
            <div className="row">
              <div>
                <div className="detail-label">Total imágenes editadas hoy</div>
                <div className="text-serif" style={{ fontSize: 26, fontWeight: 600, marginTop: 2 }}>{fmtNum(totalCortesHoy)}</div>
              </div>
              <div className="spacer"/>
              <div style={{ textAlign: 'right' }}>
                <div className="detail-label">Ritmo por hora (estimado)</div>
                <div className="text-serif" style={{ fontSize: 20, fontWeight: 600, marginTop: 2 }}>
                  {cortesCompletados > 0 ? Math.round(totalCortesHoy / (horaActual - 9)) : 0} img/hr
                </div>
              </div>
              <div style={{ textAlign: 'right', marginLeft: 32 }}>
                <div className="detail-label">Libros terminados hoy</div>
                <div className="text-serif" style={{ fontSize: 20, fontWeight: 600, marginTop: 2 }}>{hoyEditados.length}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* Kanban personal */}
      <div className="stat-grid grid-2">
        <div className="card">
          <div className="card-header">
            <Icon name="edit" size={16} style={{ color: 'var(--text-2)' }}/>
            <div>
              <div className="card-title">En edición ({misEnCurso.length})</div>
              <div className="card-subtitle">Libros que estoy editando ahora</div>
            </div>
          </div>
          <div className="card-body">
            {misEnCurso.length === 0 && <Empty icon="edit" title="Sin libros en edición" subtitle="Toma uno de la cola disponible"/>}
            <div className="stack" style={{ gap: 8 }}>
              {misEnCurso.map(l => (
                <div key={l.cons} className="kanban-card" onClick={() => abrirRegistro(l)}>
                  <div className="kanban-card-cons">#{l.cons} · {l.serie}</div>
                  <div className="kanban-card-title">{l.titulo}</div>
                  <div className="kanban-card-meta">
                    <Icon name="camera" size={12}/>
                    <span>{fmtNum(l.imagenesResultantes)} imágenes</span>
                    <span className="spacer"/>
                    <span className="text-3">Digitalizado {fmtDate(l.fechaDigitalizacion)}</span>
                  </div>
                  <button className="btn btn-primary btn-sm mt-8" style={{ width: '100%', justifyContent: 'center' }}>
                    Registrar cortes y finalizar
                  </button>
                </div>
              ))}
            </div>
          </div>
        </div>

        <div className="card">
          <div className="card-header">
            <Icon name="fifo" size={16} style={{ color: 'var(--text-2)' }}/>
            <div>
              <div className="card-title">Cola FIFO disponible ({disponibles.length})</div>
              <div className="card-subtitle">Ordenados por fecha de digitalización · Primeros en entrar, primeros en salir</div>
            </div>
          </div>
          <div className="card-body">
            {disponibles.length === 0 && <Empty icon="fifo" title="Cola vacía" subtitle="No hay libros digitalizados esperando"/>}
            <div className="stack" style={{ gap: 6, maxHeight: 400, overflow: 'auto' }}>
              {disponibles.slice(0, 12).map((l, i) => {
                const dias = daysBetween(l.fechaDigitalizacion, '2026-08-02');
                return (
                  <div key={l.cons} className="fifo-item">
                    <div className={`fifo-order ${dias > 5 ? 'urgent' : ''}`}>{i + 1}</div>
                    <div style={{ minWidth: 0 }}>
                      <div className="text-xs text-3">#{l.cons} · {l.serie}</div>
                      <div className="title-line" style={{ fontWeight: 500 }}>{l.titulo}</div>
                      <div className="text-xs text-2 mt-4">
                        {fmtNum(l.imagenesResultantes)} imág · esperando {dias} día{dias === 1 ? '' : 's'}
                      </div>
                    </div>
                    <div>
                      {dias > 5 && <span className="badge" style={{ background: 'var(--danger-soft)', color: 'var(--danger)' }}>Urgente</span>}
                    </div>
                    <button className="btn btn-ghost btn-sm" onClick={() => tomarLibro(l)}>Tomar</button>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>

      {/* Historial */}
      <div className="card">
        <div className="card-header">
          <Icon name="check" size={16} style={{ color: 'var(--text-2)' }}/>
          <div>
            <div className="card-title">Mis libros editados</div>
            <div className="card-subtitle">Últimos {Math.min(10, misEditados.length)} · click para ver detalle</div>
          </div>
        </div>
        <div className="table-wrap" style={{ border: 'none', borderRadius: 0 }}>
          <table className="data">
            <thead>
              <tr>
                <th>Núm.</th>
                <th>Título</th>
                <th>Fecha edición</th>
                <th style={{ textAlign: 'right' }}>Imágs.</th>
                <th style={{ textAlign: 'right' }}>Cortes 11/13/16/18</th>
                <th>Estatus</th>
              </tr>
            </thead>
            <tbody>
              {misEditados.slice(-10).reverse().map(l => (
                <tr key={l.cons} onClick={() => onSelectBook(l)} style={{ cursor: 'pointer' }}>
                  <td><span className="cons">#{l.cons}</span></td>
                  <td className="title-cell"><div className="title-line">{l.titulo}</div></td>
                  <td className="text-sm text-2">{fmtDate(l.fechaEdicion)}</td>
                  <td style={{ textAlign: 'right' }} className="text-mono">{fmtNum(l.imagenesEditadas)}</td>
                  <td style={{ textAlign: 'right' }} className="text-mono text-xs text-2">
                    {l.cortes ? `${l.cortes.c11}/${l.cortes.c13}/${l.cortes.c16}/${l.cortes.c18}` : '—'}
                  </td>
                  <td><StatusPill estatus={l.estatus}/></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {/* Modal finalizar */}
      <Modal
        open={!!editando}
        onClose={() => setEditando(null)}
        title="Finalizar edición y registrar cortes"
        maxWidth={520}
        footer={<>
          <button className="btn btn-ghost" onClick={() => setEditando(null)}>Cancelar</button>
          <button className="btn btn-primary" onClick={finalizarEdicion}>Enviar a Control de Calidad</button>
        </>}
      >
        {editando && (
          <div>
            <div style={{ padding: 12, background: 'var(--surface-2)', borderRadius: 6, marginBottom: 16 }}>
              <div className="text-xs text-3">#{editando.cons}</div>
              <div style={{ fontWeight: 500, fontSize: 15 }}>{editando.titulo}</div>
              <div className="text-sm text-2 mt-4">{editando.autor} · {fmtNum(editando.imagenesResultantes)} imágenes originales</div>
            </div>

            <div className="field">
              <label className="field-label">Total de imágenes editadas del tomo</label>
              <input type="number" className="input" value={imagenes} onChange={e => setImagenes(e.target.value)} autoFocus/>
            </div>

            <div className="field-label" style={{ marginTop: 12, marginBottom: 6 }}>Cortes horarios (imágenes procesadas en cada tramo)</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
              {CORTES.map(c => (
                <div key={c.key}>
                  <div className="text-xs text-2 mb-4">{c.hora} · {c.label}</div>
                  <input
                    type="number"
                    className="input"
                    placeholder="0"
                    value={cortesForm[c.key]}
                    onChange={e => setCortesForm({ ...cortesForm, [c.key]: e.target.value })}
                  />
                </div>
              ))}
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
};


const EDITING_CUTS = [
  { key: 'cut_11', label: '11:00 · Corte AM' },
  { key: 'cut_13', label: '13:00 · Pre-comida' },
  { key: 'cut_16', label: '16:00 · Post-comida' },
  { key: 'cut_18', label: '18:00 · Cierre' },
];

const editingIsoDate = (value) => {
  if (!value) return '';
  const normalized = String(value).replace(' ', 'T');
  const date = new Date(normalized);
  return Number.isNaN(date.getTime()) ? '' : date.toISOString().slice(0, 10);
};

const editingFormatDate = (value) => {
  const iso = editingIsoDate(value);
  if (!iso) return '—';
  const [y,m,d] = iso.split('-');
  return `${d}/${m}/${y}`;
};

const EdicionServer = ({ currentUser, onSessionExpired }) => {
  const [state, setState] = useState({status:'loading',error:'',available:[],active:[],progress:[],completed:[],today:{date:'',total_images:0,finished_books:0}});
  const [reloadToken,setReloadToken]=useState(0);
  const [feedback,setFeedback]=useState(null);
  const [claimBook,setClaimBook]=useState(null);
  const [claimBusy,setClaimBusy]=useState(false);
  const [workBook,setWorkBook]=useState(null);
  const [workDate,setWorkDate]=useState(new Date().toISOString().slice(0,10));
  const [cuts,setCuts]=useState({cut_11:'',cut_13:'',cut_16:'',cut_18:''});
  const [images,setImages]=useState([]);
  const [finishMode,setFinishMode]=useState(false);
  const [saving,setSaving]=useState(false);
  const [downloadBusy,setDownloadBusy]=useState({});
  const [search,setSearch]=useState('');

  useEffect(()=>{
    let active=true; const controller=new AbortController();
    window.apiRequest('editing/dashboard.php',{signal:controller.signal}).then(response=>{
      if(!active)return; const data=response?.data||{};
      setState({status:'loaded',error:'',available:data.available||[],active:data.active||[],progress:data.progress||[],completed:data.completed||[],today:data.today||{date:'',total_images:0,finished_books:0}});
    }).catch(error=>{
      if(!active)return; if(error?.status===401){onSessionExpired();return;}
      setState(s=>({...s,status:'error',error:error?.message||'No fue posible cargar Edición.'}));
    });
    return()=>{active=false;controller.abort();};
  },[reloadToken,onSessionExpired]);

  const refresh=()=>setReloadToken(v=>v+1);
  const filteredAvailable=state.available.filter(book=>{
    const q=search.trim().toLowerCase(); if(!q)return true;
    return [book.inventory_number,book.catalog_number,book.series_collection,book.title,book.author].some(v=>String(v||'').toLowerCase().includes(q));
  });

  const downloadEditingZip=async(book)=>{
    const assignmentId=Number(book?.assignment_id||0);
    if(!assignmentId)return;
    setDownloadBusy(previous=>({...previous,[assignmentId]:true}));
    setFeedback(null);
    try{
      const base=window.APP_CONFIG.API_BASE_URL.replace(/\/+$/,'');
      const response=await fetch(`${base}/editing/download.php?assignment_id=${encodeURIComponent(assignmentId)}`,{
        method:'GET',
        credentials:'include',
        headers:{Accept:'application/zip,application/json'},
        cache:'no-store'
      });
      const contentType=response.headers.get('content-type')||'';
      if(!response.ok||!contentType.includes('application/zip')){
        let message=`No fue posible descargar el ZIP. HTTP ${response.status}`;
        try{
          const payload=await response.json();
          if(payload?.message)message=payload.message;
        }catch(error){}
        throw Object.assign(new Error(message),{status:response.status});
      }
      const blob=await response.blob();
      if(!blob||blob.size<1)throw new Error('El ZIP generado está vacío.');
      const disposition=response.headers.get('content-disposition')||'';
      const utf8Match=disposition.match(/filename\*=UTF-8''([^;]+)/i);
      const simpleMatch=disposition.match(/filename="?([^";]+)"?/i);
      const fileName=utf8Match
        ? decodeURIComponent(utf8Match[1])
        : simpleMatch
          ? simpleMatch[1]
          : `INPI_2026_EDICION_${new Date().toISOString().replace(/[-:T]/g,'_').slice(0,19)}_ASIGNACION_${assignmentId}.zip`;
      const objectUrl=URL.createObjectURL(blob);
      const anchor=document.createElement('a');
      anchor.href=objectUrl;
      anchor.download=fileName;
      document.body.appendChild(anchor);
      anchor.click();
      anchor.remove();
      window.setTimeout(()=>URL.revokeObjectURL(objectUrl),1500);
      setFeedback({tone:'success',message:`El ZIP de "${book.title||'la obra'}" se descargó nuevamente.`});
    }catch(error){
      if(error?.status===401){onSessionExpired();return;}
      setFeedback({tone:'error',message:error?.message||'No fue posible descargar nuevamente el ZIP.'});
    }finally{
      setDownloadBusy(previous=>{
        const next={...previous};
        delete next[assignmentId];
        return next;
      });
    }
  };

  const confirmClaim=async()=>{
    if(!claimBook)return;
    setClaimBusy(true);
    setFeedback(null);
    let claimedAssignmentId=null;
    try{
      const response=await window.apiRequest('editing/claim.php',{method:'POST',body:{book_id:claimBook.id}});
      const data=response?.data||{};
      claimedAssignmentId=Number(data.assignment?.id)||null;
      const url=`${window.APP_CONFIG.API_BASE_URL.replace(/\/+$/,'')}/${data.download_url}`;
      const downloadResponse=await fetch(url,{method:'GET',credentials:'include',headers:{Accept:'application/zip,application/json'}});
      const contentType=downloadResponse.headers.get('content-type')||'';
      if(!downloadResponse.ok||!contentType.includes('application/zip')){
        let message=`No fue posible descargar el ZIP. HTTP ${downloadResponse.status}`;
        try{
          const raw=await downloadResponse.text();
          const payload=JSON.parse(raw);
          if(payload?.message)message=payload.message;
        }catch(error){}
        throw Object.assign(new Error(message),{status:downloadResponse.status});
      }
      const blob=await downloadResponse.blob();
      if(!blob||blob.size<1)throw new Error('El ZIP generado está vacío.');
      const objectUrl=URL.createObjectURL(blob);
      const a=document.createElement('a');
      a.href=objectUrl;
      a.download=data.download_filename||`INPI_2026_${new Date().toISOString().slice(0,10).split('-').reverse().join('_')}.zip`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      window.setTimeout(()=>URL.revokeObjectURL(objectUrl),1500);
      setClaimBook(null);
      setFeedback({tone:'success',message:`Libro tomado y ZIP descargado correctamente (${data.source_file_count||0} imágenes).`});
      refresh();
    }catch(error){
      if(claimedAssignmentId){
        try{
          await window.apiRequest('editing/release.php',{method:'POST',body:{assignment_id:claimedAssignmentId}});
        }catch(releaseError){}
      }
      if(error?.status===401){onSessionExpired();return;}
      setFeedback({tone:'error',message:error?.message||'No fue posible tomar o descargar el libro. El libro se liberó de la cola de Edición.'});
      refresh();
    }finally{
      setClaimBusy(false);
    }
  };

  const openWork=(book,finish=false)=>{
    setWorkBook(book);setFinishMode(finish);setWorkDate(state.today.date||new Date().toISOString().slice(0,10));
    const existing=state.progress.find(p=>Number(p.assignment_id)===Number(book.assignment_id)&&p.work_date===(state.today.date||new Date().toISOString().slice(0,10)));
    setCuts({cut_11:existing?.cut_11||'',cut_13:existing?.cut_13||'',cut_16:existing?.cut_16||'',cut_18:existing?.cut_18||''});setImages([]);
  };

  const saveProgress=async()=>{
    if(!workBook)return;setSaving(true);setFeedback(null);
    try{
      if(finishMode){
        if(images.length===0)throw new Error('Selecciona las imágenes editadas.');
        const form=new FormData();
        form.append('assignment_id',workBook.assignment_id);
        images.forEach(file=>form.append('images[]',file));
        const response=await fetch(`${window.APP_CONFIG.API_BASE_URL.replace(/\/+$/,'')}/editing/complete.php`,{method:'POST',credentials:'include',body:form});
        const raw=await response.text();
        let payload=null;
        try{payload=raw?JSON.parse(raw):null;}catch(error){}
        if(!response.ok||payload?.success===false)throw Object.assign(new Error(payload?.message||`HTTP ${response.status}`),{status:response.status});
        setFeedback({tone:'success',message:'Edición finalizada, imágenes guardadas y libro enviado a Control de Calidad.'});
      }else{
        await window.apiRequest('editing/save-progress.php',{method:'POST',body:{assignment_id:workBook.assignment_id,...cuts}});
        setFeedback({tone:'success',message:'Avance del día guardado correctamente.'});
      }
      setWorkBook(null);refresh();
    }catch(error){if(error?.status===401){onSessionExpired();return;}setFeedback({tone:'error',message:error?.message||'No fue posible guardar.'});}
    finally{setSaving(false);}
  };

  const todayProgress=state.progress.filter(p=>p.work_date===state.today.date);
  const todayCuts={cut_11:0,cut_13:0,cut_16:0,cut_18:0};todayProgress.forEach(p=>Object.keys(todayCuts).forEach(k=>todayCuts[k]+=Number(p[k]||0)));

  if(state.status==='error')return <div className="card"><Empty icon="alert" title="No se pudo cargar Edición" subtitle={state.error}/><div style={{textAlign:'center',paddingBottom:20}}><button className="btn btn-primary" onClick={refresh}>Reintentar</button></div></div>;

  return <div className="stack" data-source="editing-server">
    {feedback&&<div role={feedback.tone==='success'?'status':'alert'} style={{padding:'12px 14px',borderRadius:6,background:feedback.tone==='success'?'#f0fdf4':'#fef2f2',color:feedback.tone==='success'?'#166534':'#991b1b'}}>{feedback.message}</div>}

    <div className="card">
      <div className="card-header"><Icon name="clock" size={16}/><div><div className="card-title">Historial y productividad de hoy · {editingFormatDate(state.today.date)}</div><div className="card-subtitle">Cortes diarios conservados por fecha; si un libro continúa mañana, se crea un nuevo registro</div></div></div>
      <div className="card-body">
        <div className="timeline">{EDITING_CUTS.map((c,i)=><div className="timeline-node" key={c.key}><div className={`timeline-dot ${todayCuts[c.key]>0?'done':''}`}>{todayCuts[c.key]>0?'✓':i+1}</div><div className="timeline-hour">{c.label.split(' · ')[0]}</div><div className="timeline-count">{fmtNum(todayCuts[c.key])}</div><div className="timeline-label">{c.label.split(' · ')[1]}</div></div>)}</div>
        <div style={{marginTop:20,padding:14,background:'var(--surface-2)',borderRadius:8,display:'flex',justifyContent:'space-between'}}><div><div className="detail-label">Total imágenes editadas hoy</div><div className="text-serif" style={{fontSize:26,fontWeight:600}}>{fmtNum(state.today.total_images)}</div></div><div style={{textAlign:'right'}}><div className="detail-label">Libros terminados hoy</div><div className="text-serif" style={{fontSize:22,fontWeight:600}}>{state.today.finished_books}</div></div></div>
        {state.progress.length>0&&<div className="table-wrap" style={{marginTop:14}}><table className="data"><thead><tr><th>Fecha</th><th>Libro</th><th>11:00</th><th>13:00</th><th>16:00</th><th>18:00</th><th>Total</th></tr></thead><tbody>{state.progress.slice(0,12).map(p=><tr key={p.id}><td>{editingFormatDate(p.work_date)}</td><td>{p.title}</td><td>{p.cut_11}</td><td>{p.cut_13}</td><td>{p.cut_16}</td><td>{p.cut_18}</td><td>{p.total_images}</td></tr>)}</tbody></table></div>}
      </div>
    </div>

    <div className="stat-grid grid-2">
      <div className="card"><div className="card-header"><Icon name="edit" size={16}/><div><div className="card-title">En edición ({state.active.length})</div><div className="card-subtitle">Libros que tomaste y están en proceso</div></div></div><div className="card-body"><div className="stack" style={{gap:8}}>{state.active.length===0&&<Empty icon="edit" title="Sin libros en edición" subtitle="Toma uno de la cola FIFO"/>}{state.active.map(book=><div className="kanban-card" key={book.assignment_id}><div className="kanban-card-cons">#{book.inventory_number} · {book.series_collection}</div><div className="kanban-card-title">{book.title}</div><div className="kanban-card-meta"><span>{fmtNum(book.resulting_images)} imágenes originales</span><span className="spacer"/><span>Tomado {editingFormatDate(book.assigned_at)}</span></div><div className="row mt-8" style={{gap:8,flexWrap:'wrap'}}><button className="btn btn-ghost btn-sm" style={{flex:1,justifyContent:'center'}} disabled={Boolean(downloadBusy[book.assignment_id])} onClick={()=>downloadEditingZip(book)}>{downloadBusy[book.assignment_id]?'Descargando…':'Descargar'}</button><button className="btn btn-ghost btn-sm" style={{flex:1,justifyContent:'center'}} onClick={()=>openWork(book,false)}>Registrar avance</button><button className="btn btn-primary btn-sm" style={{flex:1,justifyContent:'center'}} onClick={()=>openWork(book,true)}>Finalizar y subir</button></div></div>)}</div></div></div>

      <div className="card"><div className="card-header"><Icon name="fifo" size={16}/><div><div className="card-title">Cola FIFO disponible ({filteredAvailable.length})</div><div className="card-subtitle">Digitalizados y sin asignación activa de Edición</div></div></div><div style={{padding:'12px 16px',borderBottom:'1px solid var(--border)'}}><input className="input" placeholder="Buscar libro físico por número, serie, título o autor" value={search} onChange={e=>setSearch(e.target.value)}/></div><div className="card-body"><div className="stack" style={{gap:6,maxHeight:420,overflow:'auto'}}>{filteredAvailable.length===0&&<Empty icon="fifo" title="Cola vacía" subtitle="No hay libros disponibles"/>}{filteredAvailable.map((book,i)=><div className="fifo-item" key={book.id}><div className="fifo-order">{i+1}</div><div style={{minWidth:0}}><div className="text-xs text-3">#{book.inventory_number} · {book.series_collection}</div><div className="title-line" style={{fontWeight:500}}>{book.title}</div><div className="text-xs text-2 mt-4">{fmtNum(book.resulting_images)} imágenes · digitalizado {editingFormatDate(book.digitized_at)}</div></div><button className="btn btn-ghost btn-sm" onClick={()=>setClaimBook(book)}>Tomar</button></div>)}</div></div></div>
    </div>

    <div className="card"><div className="card-header"><Icon name="check" size={16}/><div><div className="card-title">Mis libros editados</div><div className="card-subtitle">Historial real de asignaciones completadas</div></div></div><div className="table-wrap" style={{border:'none'}}><table className="data"><thead><tr><th>Núm.</th><th>Título</th><th>Fecha</th><th>Imágenes</th><th>Días trabajados</th><th>Estatus</th></tr></thead><tbody>{state.completed.map(row=><tr key={row.assignment_id}><td>#{row.inventory_number}</td><td>{row.title}</td><td>{editingFormatDate(row.completed_at)}</td><td>{row.edited_images}</td><td>{row.work_days}</td><td><StatusPill estatus={row.current_stage === 'conversion' ? (row.status === 'in_progress' ? 'en_conversion' : 'aceptado') : row.current_stage === 'quality_control' ? 'en_cc' : row.current_stage === 'publication' || row.current_stage === 'published' ? 'finalizado' : 'editado'}/></td></tr>)}</tbody></table></div></div>

    <Modal open={!!claimBook} onClose={()=>!claimBusy&&setClaimBook(null)} title="Preparar descarga para edición" maxWidth={560} footer={<><button className="btn btn-ghost" disabled={claimBusy} onClick={()=>setClaimBook(null)}>Cancelar</button><button className="btn btn-primary" disabled={claimBusy} onClick={confirmClaim}>{claimBusy?'Preparando ZIP…':'Aceptar y descargar ZIP'}</button></>}>
      {claimBook&&<div><div style={{padding:12,background:'var(--surface-2)',borderRadius:6,marginBottom:16}}><div className="text-xs text-3">#{claimBook.inventory_number}</div><div style={{fontWeight:600,fontSize:17}}>{claimBook.title}</div></div><div style={{padding:14,background:'#fffbeb',color:'#92400e',borderRadius:8}}><strong>Antes de descargar</strong><div style={{marginTop:6}}>Crea esta estructura para mantener el control:</div><div className="text-mono" style={{marginTop:8}}>Documentos\INPI 2026\EDICION\{editingFormatDate(state.today.date||new Date().toISOString().slice(0,10)).replaceAll('/','_')}\</div></div><p className="text-sm text-2">Al aceptar, el libro se asignará exclusivamente a tu usuario y se descargará un ZIP con la estructura Serie\Título\1.JPG\.</p></div>}
    </Modal>

    <Modal open={!!workBook} onClose={()=>!saving&&setWorkBook(null)} title={finishMode?'Finalizar edición y subir imágenes':'Registrar avance diario'} maxWidth={620} footer={<><button className="btn btn-ghost" disabled={saving} onClick={()=>setWorkBook(null)}>Cancelar</button><button className="btn btn-primary" disabled={saving} onClick={saveProgress}>{saving?'Guardando…':finishMode?'Finalizar y enviar a Control de Calidad':'Guardar avance'}</button></>}>
      {workBook&&<div>
        <div style={{padding:12,background:'var(--surface-2)',borderRadius:6,marginBottom:16}}>
          <div className="text-xs text-3">#{workBook.inventory_number} · {workBook.series_collection||'Sin serie'}</div>
          <div style={{fontWeight:600,fontSize:17}}>{workBook.title}</div>
          <div className="text-sm text-2">{workBook.author||'Sin autor'} · {fmtNum(workBook.resulting_images)} imágenes originales</div>
        </div>
        <div className="field">
          <label className="field-label">{finishMode?'Fecha de subida':'Fecha de trabajo'}</label>
          <input type="date" className="input" value={workDate} readOnly disabled/>
          <div className="field-help">La fecha se obtiene automáticamente del servidor y no puede modificarse.</div>
        </div>
        {!finishMode&&<>
          <div className="field-label" style={{marginTop:12,marginBottom:6}}>Cortes horarios del día</div>
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:10}}>
            {EDITING_CUTS.map(c=><div key={c.key}><div className="text-xs text-2 mb-4">{c.label}</div><input type="number" min="0" className="input" value={cuts[c.key]} onChange={e=>setCuts({...cuts,[c.key]:e.target.value})}/></div>)}
          </div>
        </>}
        {finishMode&&<div className="field" style={{marginTop:16}}>
          <label className="field-label">Subir imágenes editadas JPG</label>
          <input type="file" className="input" accept="image/jpeg,.jpg,.jpeg" multiple onChange={e=>setImages(Array.from(e.target.files||[]))}/>
          <div className="field-help">Se guardarán en INPI 2026\EDICION\Serie\Título\1.JPG\ conservando el nombre original.</div>
          <div className="text-sm text-2 mt-4">{images.length} archivos seleccionados</div>
        </div>}
      </div>}
    </Modal>
  </div>;
};

const Edicion = (props) => {
  const serverMode = window.APP_CONFIG.AUTH.MODE === 'server';
  if (serverMode) return <EdicionServer currentUser={props.currentUser} onSessionExpired={props.onSessionExpired}/>;
  return <EdicionLocal {...props}/>;
};

Object.assign(window, { Edicion });
