// ============================================================
// Módulo Rutas de Imágenes
// En modo servidor, "Rutas por libro" consulta MySQL mediante booksService.
// ============================================================
const Rutas = ({ libros: librosLocales = [], onUpdate, currentUser, onSessionExpired }) => {
  const serverMode = window.APP_CONFIG.AUTH.MODE === 'server';
  const [librosServidor, setLibrosServidor] = useState([]);
  const [loadingBooks, setLoadingBooks] = useState(serverMode);
  const [booksError, setBooksError] = useState('');
  const [rutasPorLibro, setRutasPorLibro] = useState({});
  const [asignando, setAsignando] = useState(null);
  const [rutaBase, setRutaBase] = useState('\\\\SERVIDOR-DIG\\Digitalizacion\\FCE_2026');
  const [modoLote, setModoLote] = useState(false);
  const [seleccionados, setSeleccionados] = useState(new Set());
  const [filterSerie, setFilterSerie] = useState('');
  const [search, setSearch] = useState('');
  const [showRutaBase, setShowRutaBase] = useState(false);

  const [rutas, setRutas] = useState({
    origen:        '\\\\SERVIDOR-DIG\\Digitalizacion\\FCE_2026',
    edicion:       '\\\\SERVIDOR-EDIT\\Trabajo\\FCE_2026',
    controlCalidad:'\\\\SERVIDOR-CC\\Revision\\FCE_2026',
    salidaFinal:   '\\\\SERVIDOR-FIN\\Publicacion\\FCE_2026',
    backup:        'S:\\Backup\\FCE_2026',
  });

  const mapServerStatus = (book) => {
    const stage = book.currentStage || book.current_stage || '';
    const status = book.status || '';
    if (stage === 'published' || stage === 'publication') return 'finalizado';
    if (stage === 'conversion') return status === 'completed' ? 'finalizado' : 'en_conversion';
    if (stage === 'quality_control') {
      if (status === 'approved') return 'aceptado';
      if (status === 'rejected' || status === 'correction_required') return 'rechazado';
      return 'en_cc';
    }
    if (stage === 'editing') return status === 'completed' ? 'editado' : 'en_edicion';
    if (stage === 'digitization') return status === 'completed' ? 'digitalizado' : 'en_digitalizacion';
    return 'nuevo';
  };

  const normalizeServerBook = (book) => {
    const serverId = book.serverId || book.id;
    const consValue = book.catalogNumber ?? book.catalog_number ?? book.inventoryNumber ?? book.inventory_number ?? serverId;
    return {
      ...book,
      serverId,
      cons: String(consValue ?? '').padStart(4, '0'),
      serie: book.seriesCollection || book.series_collection || book.serie || 'Sin serie',
      titulo: book.title || book.titulo || 'Sin título',
      autor: book.author || book.autor || '',
      estatus: mapServerStatus(book),
      rutaImagenes: rutasPorLibro[serverId] || null,
    };
  };

  const loadAllBooks = async () => {
    if (!serverMode) return;
    setLoadingBooks(true);
    setBooksError('');
    try {
      const first = await window.booksService.listBooks({
        page: 1,
        per_page: 100,
        sort: 'inventory_number',
        direction: 'asc'
      });
      const all = [...first.items];
      const totalPages = Math.max(1, Number(first.pagination.total_pages) || 1);
      for (let page = 2; page <= totalPages; page += 1) {
        const result = await window.booksService.listBooks({
          page,
          per_page: 100,
          sort: 'inventory_number',
          direction: 'asc'
        });
        all.push(...result.items);
      }
      setLibrosServidor(all);
    } catch (error) {
      if (error && error.status === 401 && typeof onSessionExpired === 'function') {
        onSessionExpired();
        return;
      }
      setBooksError(error?.message || 'No fue posible cargar los libros desde la base de datos.');
    } finally {
      setLoadingBooks(false);
    }
  };

  useEffect(() => {
    loadAllBooks();
  }, [serverMode]);

  const libros = serverMode
    ? librosServidor.map(normalizeServerBook)
    : librosLocales;

  // En servidor se muestran todos los libros reales. En demo se conserva el comportamiento anterior.
  const librosDisponibles = serverMode ? libros : libros.filter(l =>
    ['digitalizado','en_edicion','editado','en_cc','aceptado','rechazado','en_conversion','finalizado'].includes(l.estatus)
  );

  const series = [...new Set(librosDisponibles.map(l => l.serie).filter(Boolean))].sort((a, b) => a.localeCompare(b, 'es'));
  const normalizedSearch = search.trim().toLowerCase();
  const filtrados = librosDisponibles.filter((libro) => {
    if (filterSerie && libro.serie !== filterSerie) return false;
    if (!normalizedSearch) return true;
    return [libro.cons, libro.serie, libro.titulo, libro.autor]
      .some(value => String(value || '').toLowerCase().includes(normalizedSearch));
  });

  const conRuta = librosDisponibles.filter(l => l.rutaImagenes).length;
  const sinRuta = librosDisponibles.length - conRuta;

  const generarRuta = (libro) => {
    const serie = String(libro.serie || 'Sin_serie').normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-zA-Z0-9]/g, '_');
    const titulo = String(libro.titulo || 'Sin_titulo').normalize('NFD').replace(/[\u0300-\u036f]/g, '').substring(0, 30).replace(/[^a-zA-Z0-9]/g, '_');
    return `${rutaBase}\\${serie}\\${libro.cons}_${titulo}`;
  };

  const applyRoute = (libro, ruta) => {
    if (serverMode) {
      setRutasPorLibro(prev => ({ ...prev, [libro.serverId]: ruta }));
    } else if (typeof onUpdate === 'function') {
      onUpdate(libro.cons, { rutaImagenes: ruta });
    }
  };

  const asignarLote = () => {
    seleccionados.forEach(key => {
      const libro = librosDisponibles.find(l => String(l.serverId || l.cons) === String(key));
      if (libro) applyRoute(libro, generarRuta(libro));
    });
    setSeleccionados(new Set());
    setModoLote(false);
  };

  const toggleSel = (key) => {
    const nueva = new Set(seleccionados);
    if (nueva.has(key)) nueva.delete(key); else nueva.add(key);
    setSeleccionados(nueva);
  };

  const selTodos = () => {
    if (seleccionados.size === filtrados.length) setSeleccionados(new Set());
    else setSeleccionados(new Set(filtrados.map(l => String(l.serverId || l.cons))));
  };

  const guardarRuta = (libro, ruta) => {
    applyRoute(libro, ruta);
    setAsignando(null);
  };

  return (
    <div className="stack">
      <div className="kpi-grid" style={{ gridTemplateColumns: 'repeat(4, 1fr)' }}>
        <KPI label={serverMode ? 'Libros en MySQL' : 'Total digitalizados'} value={librosDisponibles.length} sub={serverMode ? 'Catálogo real cargado por API' : 'Libros que requieren ruta'} tone="primary"/>
        <KPI label="Con ruta asignada" value={conRuta} sub="Listos para trabajar" tone="success" progress={librosDisponibles.length ? (conRuta/librosDisponibles.length)*100 : 0}/>
        <KPI label="Sin ruta" value={sinRuta} sub="Requieren asignación" tone={sinRuta > 0 ? 'danger' : 'success'}/>
        <KPI label="Fuente de datos" value={serverMode ? 'MySQL' : 'Demo local'} sub={serverMode ? 'api/books/index.php' : 'data.js'} tone="success"/>
      </div>

      <div className="card">
        <div className="card-header">
          <Icon name="settings" size={16} style={{ color: 'var(--text-2)' }}/>
          <div>
            <div className="card-title">Rutas configuradas del proyecto</div>
            <div className="card-subtitle">Ubicaciones de los servidores donde se almacenan las imágenes</div>
          </div>
          <div className="spacer"/>
          <button className="btn btn-ghost btn-sm" onClick={() => setShowRutaBase(!showRutaBase)}>
            {showRutaBase ? 'Ocultar' : 'Editar rutas'}
          </button>
        </div>
        <div className="card-body">
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12 }}>
            {[
              { key: 'origen', label: 'Origen (Digitalización)', color: 'var(--info)', icon: 'camera' },
              { key: 'edicion', label: 'Trabajo (Edición)', color: '#7e22ce', icon: 'edit' },
              { key: 'controlCalidad', label: 'Revisión (CC)', color: 'var(--warn)', icon: 'check_shield' },
              { key: 'salidaFinal', label: 'Publicación (Final)', color: 'var(--success)', icon: 'convert' },
              { key: 'backup', label: 'Backup', color: 'var(--text-2)', icon: 'library' },
            ].map(r => (
              <div key={r.key} style={{ padding: 12, background: 'var(--surface-2)', borderRadius: 8, border: '1px solid var(--border)' }}>
                <div className="row mb-8">
                  <div style={{ width: 28, height: 28, borderRadius: 6, background: r.color + '20', color: r.color, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <Icon name={r.icon} size={14}/>
                  </div>
                  <div style={{ fontWeight: 500, fontSize: 13 }}>{r.label}</div>
                </div>
                {showRutaBase ? (
                  <input className="input text-mono text-xs" value={rutas[r.key]} onChange={e => setRutas({ ...rutas, [r.key]: e.target.value })}/>
                ) : (
                  <div className="text-mono text-xs text-2" style={{ padding: '4px 8px', background: 'var(--surface)', borderRadius: 4, border: '1px solid var(--border)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{rutas[r.key]}</div>
                )}
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="card">
        <div className="card-header">
          <Icon name="library" size={16} style={{ color: 'var(--text-2)' }}/>
          <div>
            <div className="card-title">Rutas por libro</div>
            <div className="card-subtitle">{serverMode ? 'Libros reales consultados desde MySQL' : 'Asigna la ubicación específica de cada libro digitalizado'}</div>
          </div>
          <div className="spacer"/>
          {serverMode && <button className="btn btn-ghost btn-sm" onClick={loadAllBooks} disabled={loadingBooks}>Actualizar libros</button>}
          {modoLote ? (
            <>
              <button className="btn btn-ghost btn-sm" onClick={() => { setModoLote(false); setSeleccionados(new Set()); }}>Cancelar</button>
              <button className="btn btn-primary btn-sm" onClick={asignarLote} disabled={seleccionados.size === 0}>Asignar automáticamente ({seleccionados.size})</button>
            </>
          ) : (
            <button className="btn btn-ghost" onClick={() => setModoLote(true)}>Asignación en lote</button>
          )}
        </div>

        <div style={{ padding: '14px 20px', borderBottom: '1px solid var(--border)', background: 'var(--surface-2)' }}>
          <div className="row" style={{ gap: 12, alignItems: 'end' }}>
            <div style={{ flex: 1 }}>
              <label className="field-label mb-4">Ruta base para asignación automática</label>
              <input className="input text-mono text-sm" value={rutaBase} onChange={e => setRutaBase(e.target.value)} placeholder="\\SERVIDOR\Carpeta"/>
            </div>
            <div style={{ minWidth: 220 }}>
              <label className="field-label mb-4">Filtrar por serie</label>
              <select className="select" value={filterSerie} onChange={e => setFilterSerie(e.target.value)}>
                <option value="">Todas las series</option>
                {series.map(s => <option key={s} value={s}>{s}</option>)}
              </select>
            </div>
            <div style={{ minWidth: 240 }}>
              <label className="field-label mb-4">Buscar libro</label>
              <input className="input" value={search} onChange={e => setSearch(e.target.value)} placeholder="Número, título o autor"/>
            </div>
          </div>
          <div className="text-xs text-3 mt-8"><Icon name="alert" size={11} style={{ display: 'inline', verticalAlign: '-2px', marginRight: 4 }}/>La ruta se genera como <span className="text-mono">{'{RUTA_BASE}\\{SERIE}\\{NUM_CONS}_{TITULO}'}</span></div>
          {serverMode && <div className="text-xs text-3 mt-8">La lista proviene del servidor. Las asignaciones de ruta hechas en esta pantalla se mantienen durante la sesión; la persistencia definitiva por libro requiere una tabla/API específica.</div>}
        </div>

        {booksError && <div style={{ margin: 16, padding: 12, borderRadius: 8, background: 'var(--danger-soft, #fee2e2)', color: 'var(--danger, #b91c1c)' }}>{booksError}</div>}

        <div className="table-wrap" style={{ border: 'none', borderRadius: 0, maxHeight: 560 }}>
          <table className="data">
            <thead><tr>
              {modoLote && <th style={{ width: 40 }}><div className="check-box" style={{ margin: '0 auto', cursor: 'pointer' }} onClick={selTodos}>{seleccionados.size === filtrados.length && filtrados.length > 0 && <Icon name="check" size={12}/>}</div></th>}
              <th>Núm.</th><th>Serie / Título</th><th>Estatus</th><th>Ruta de imágenes</th><th style={{ textAlign: 'right' }}>Acción</th>
            </tr></thead>
            <tbody>
              {loadingBooks && <tr><td colSpan={modoLote ? 6 : 5}><div style={{ padding: 28, textAlign: 'center' }}>Cargando libros reales desde MySQL…</div></td></tr>}
              {!loadingBooks && filtrados.length === 0 && <tr><td colSpan={modoLote ? 6 : 5}><Empty icon="library" title="Sin libros" subtitle={booksError ? 'No fue posible consultar el catálogo' : 'No hay libros que coincidan con los filtros'}/></td></tr>}
              {!loadingBooks && filtrados.map(l => {
                const key = String(l.serverId || l.cons);
                const tieneRuta = !!l.rutaImagenes;
                return <tr key={key}>
                  {modoLote && <td><div className="check-box" style={{ margin: '0 auto', cursor: 'pointer', background: seleccionados.has(key) ? 'var(--success)' : 'transparent', borderColor: seleccionados.has(key) ? 'var(--success)' : 'var(--border-strong)', color: 'white' }} onClick={() => toggleSel(key)}>{seleccionados.has(key) && <Icon name="check" size={12}/>}</div></td>}
                  <td><span className="cons">#{l.cons}</span></td>
                  <td className="title-cell"><div className="text-xs text-3" style={{ textTransform: 'uppercase', letterSpacing: '.04em' }}>{l.serie}</div><div className="title-main">{l.titulo}</div>{l.autor && <div className="text-xs text-2">{l.autor}</div>}</td>
                  <td><StatusPill estatus={l.estatus}/></td>
                  <td>{tieneRuta ? <div className="text-mono text-xs" style={{ maxWidth: 380, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={l.rutaImagenes}>{l.rutaImagenes}</div> : <span className="text-xs text-3">Sin asignar</span>}</td>
                  <td style={{ textAlign: 'right' }}><button className="btn btn-ghost btn-sm" onClick={() => setAsignando(l)}>{tieneRuta ? 'Editar' : 'Asignar ruta'}</button></td>
                </tr>;
              })}
            </tbody>
          </table>
        </div>
        {!loadingBooks && <div style={{ padding: '10px 20px', borderTop: '1px solid var(--border)', fontSize: 12, color: 'var(--text-3)' }}>Mostrando {filtrados.length} de {librosDisponibles.length} libros.</div>}
      </div>

      {asignando && <RutaModal libro={asignando} rutaBase={rutaBase} onClose={() => setAsignando(null)} onSave={(libro, ruta) => guardarRuta(libro, ruta)} generarRuta={generarRuta}/>} 
    </div>
  );
};

const RutaModal = ({ libro, onClose, onSave, generarRuta }) => {
  const [ruta, setRuta] = useState('');
  const [validando, setValidando] = useState(false);
  const [estadoRuta, setEstadoRuta] = useState(null);

  useEffect(() => {
    const initial = libro.rutaImagenes || generarRuta(libro);
    setRuta(initial);
    setEstadoRuta(libro.rutaImagenes ? 'valida' : null);
  }, [libro]);

  const validarRuta = () => {
    setValidando(true);
    setEstadoRuta(null);
    setTimeout(() => {
      setValidando(false);
      setEstadoRuta(ruta.trim() ? 'valida' : 'invalida');
    }, 500);
  };

  return <Modal title={`Ruta de imágenes · #${libro.cons}`} onClose={onClose} width={680} footer={<><button className="btn btn-ghost" onClick={onClose}>Cancelar</button><button className="btn btn-primary" disabled={!ruta.trim()} onClick={() => onSave(libro, ruta.trim())}>Guardar ruta</button></>}>
    <div className="stack">
      <div><div className="field-label">Libro</div><div style={{ fontWeight: 600 }}>{libro.titulo}</div><div className="text-xs text-2">{libro.serie}{libro.autor ? ` · ${libro.autor}` : ''}</div></div>
      <div><label className="field-label mb-4">Ruta de imágenes</label><div className="row" style={{ gap: 8 }}><input className="input text-mono" value={ruta} onChange={e => { setRuta(e.target.value); setEstadoRuta(null); }} style={{ flex: 1 }}/><button className="btn btn-ghost" onClick={validarRuta} disabled={validando}>{validando ? 'Validando…' : 'Validar'}</button></div></div>
      {estadoRuta === 'valida' && <div className="text-xs" style={{ color: 'var(--success)' }}>La ruta tiene un formato válido.</div>}
      {estadoRuta === 'invalida' && <div className="text-xs" style={{ color: 'var(--danger)' }}>Escribe una ruta válida.</div>}
      <button className="btn btn-ghost btn-sm" style={{ alignSelf: 'flex-start' }} onClick={() => { setRuta(generarRuta(libro)); setEstadoRuta(null); }}>Generar automáticamente</button>
    </div>
  </Modal>;
};
