

/* ============================================================
   Dashboard: Organización — Categorías y Colecciones
   ============================================================ */

function slugify(str) {
  return str.trim().toLowerCase()
    .normalize('NFD').replace(/[̀-ͯ]/g, '')
    .replace(/[^a-z0-9\s-]/g, '')
    .replace(/[\s-]+/g, '-')
    .replace(/^-|-$/g, '');
}

function CatalogConfirmModal({ title, message, onCancel, onConfirm }) {
  React.useEffect(() => {
    const scrollY = window.scrollY || window.pageYOffset || 0;
    const prev = { overflow: document.body.style.overflow, position: document.body.style.position, top: document.body.style.top, width: document.body.style.width };
    document.body.style.overflow = 'hidden';
    document.body.style.position = 'fixed';
    document.body.style.top = `-${scrollY}px`;
    document.body.style.width = '100%';
    return () => {
      document.body.style.overflow = prev.overflow;
      document.body.style.position = prev.position;
      document.body.style.top = prev.top;
      document.body.style.width = prev.width;
      window.scrollTo(0, scrollY);
    };
  }, []);
  return (
    <div className="animate-fadeIn" role="dialog" aria-modal="true" aria-labelledby="catalog-confirm-title" style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.45)', zIndex: 200, display: 'grid', placeItems: 'center', padding: 16 }}>
      <div className="card animate-fadeUp" style={{ maxWidth: 420, width: '100%', padding: 28 }}>
        <h3 id="catalog-confirm-title" style={{ margin: '0 0 12px', fontSize: 18, fontWeight: 700, color: 'var(--ink)' }}>{title}</h3>
        <p style={{ margin: '0 0 22px', color: 'var(--ink-2)', fontSize: 14.5, lineHeight: 1.65 }}>{message}</p>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          <button className="btn btn-soft" onClick={onCancel} autoFocus>Cancelar</button>
          <button onClick={onConfirm}
            style={{ display: 'flex', alignItems: 'center', gap: 7, background: 'var(--danger-text)', color: '#fff', border: '1px solid var(--danger-line)', borderRadius: 'var(--r-sm)', padding: '10px 18px', fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>
            <Icon name="trash" size={15} /> Eliminar
          </button>
        </div>
      </div>
    </div>
  );
}

function CatalogManager({ go, photos, categories, collections, onSaveCategories, onSaveCollections }) {
  const TONES = ['rose', 'sky', 'green', 'sand'];

  const [catName, setCatName] = React.useState('');
  const [catTone, setCatTone] = React.useState('rose');
  const [catError, setCatError] = React.useState('');
  const [confirmCat, setConfirmCat] = React.useState(null);

  const [colName, setColName] = React.useState('');
  const [colError, setColError] = React.useState('');
  const [confirmCol, setConfirmCol] = React.useState(null);

  const photosInCat = (id) => photos.filter(p => p.cat === id).length;
  const photosInCol = (col) => photos.filter(p => p.col === col).length;

  /* ——— Categorías ——— */
  const addCategory = () => {
    const label = catName.trim();
    if (!label) { setCatError('Escribe un nombre'); return; }
    const id = slugify(label);
    if (!id) { setCatError('Nombre no válido'); return; }
    if (categories.find(c => c.id === id)) { setCatError('Ya existe una categoría con ese nombre'); return; }
    onSaveCategories([...categories, { id, label, tone: catTone }]);
    setCatName(''); setCatTone('rose'); setCatError('');
  };

  const requestDeleteCat = (id) => {
    photosInCat(id) > 0 ? setConfirmCat(id) : doDeleteCat(id);
  };

  const doDeleteCat = (id) => {
    onSaveCategories(categories.filter(c => c.id !== id));
    setConfirmCat(null);
  };

  /* ——— Colecciones ——— */
  const addCollection = () => {
    const name = colName.trim();
    if (!name) { setColError('Escribe un nombre'); return; }
    if (collections.includes(name)) { setColError('Ya existe esta colección'); return; }
    onSaveCollections([...collections, name]);
    setColName(''); setColError('');
  };

  const requestDeleteCol = (col) => {
    photosInCol(col) > 0 ? setConfirmCol(col) : doDeleteCol(col);
  };

  const doDeleteCol = (col) => {
    onSaveCollections(collections.filter(c => c !== col));
    setConfirmCol(null);
  };

  const ToneRow = () => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
      <span style={{ fontSize: 12.5, color: 'var(--ink-3)', marginRight: 4 }}>Color:</span>
      {TONES.map(t => (
        <button key={t} onClick={() => setCatTone(t)}
          title={t}
          style={{ width: 26, height: 26, borderRadius: '50%', border: catTone === t ? '3px solid var(--ink)' : '3px solid transparent', background: toneVar(t), cursor: 'pointer', outline: 'none', boxSizing: 'border-box', transition: 'border-color .15s' }} />
      ))}
    </div>
  );

  return (
    <DashLayout go={go} route="catalog" title="Organización" sub="Gestiona categorías y colecciones de tu archivo">

      <div className="catalog-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24, alignItems: 'start' }}>

        {/* ——— CATEGORÍAS ——— */}
        <div className="card" style={{ overflow: 'hidden' }}>
          <div style={{ padding: '18px 20px', borderBottom: '1px solid var(--line)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <h3 style={{ margin: 0, fontSize: 16, fontWeight: 700, color: 'var(--ink)' }}>Categorías</h3>
              <p style={{ margin: '3px 0 0', fontSize: 12.5, color: 'var(--ink-3)' }}>{categories.length} categorías · tipo de fotografía</p>
            </div>
          </div>

          <div>
            {categories.length === 0 && (
              <p style={{ padding: '18px 20px', margin: 0, fontSize: 13.5, color: 'var(--ink-3)' }}>No hay categorías. Crea la primera.</p>
            )}
            {categories.map(c => {
              const count = photosInCat(c.id);
              return (
                <div key={c.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 20px', borderBottom: '1px solid var(--line-2)' }}>
                  <span style={{ width: 10, height: 10, borderRadius: '50%', background: toneVar(c.tone), flexShrink: 0 }} />
                  <span style={{ flex: 1, fontSize: 14.5, fontWeight: 600, color: 'var(--ink)' }}>{c.label}</span>
                  <span style={{ fontSize: 12, color: 'var(--ink-3)', whiteSpace: 'nowrap' }}>{count} foto{count !== 1 ? 's' : ''}</span>
                  <button onClick={() => requestDeleteCat(c.id)}
                    title="Eliminar categoría" aria-label="Eliminar categoría"
                    style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-3)', padding: '12px 10px', borderRadius: 'var(--r-sm)', display: 'grid', placeItems: 'center', transition: 'color .15s' }}
                    onMouseOver={e => e.currentTarget.style.color = 'var(--rose)'}
                    onMouseOut={e => e.currentTarget.style.color = 'var(--ink-3)'}>
                    <Icon name="trash" size={15} />
                  </button>
                </div>
              );
            })}
          </div>

          <div style={{ padding: '18px 20px', background: 'var(--surface-2)', borderTop: categories.length ? '1px solid var(--line)' : 'none' }}>
            <p style={{ margin: '0 0 10px', fontSize: 13, fontWeight: 600, color: 'var(--ink-2)' }}>Nueva categoría</p>
            <input className="input" placeholder="Ej: Bodas, Arquitectura…" value={catName}
              onChange={e => { setCatName(e.target.value); setCatError(''); }}
              onKeyDown={e => e.key === 'Enter' && addCategory()}
              style={{ marginBottom: 10 }} />
            <ToneRow />
            {catError && <p style={{ margin: '0 0 8px', fontSize: 12.5, color: 'var(--danger-text)' }}>{catError}</p>}
            <button className="btn btn-primary btn-sm" onClick={addCategory}>
              <Icon name="plus" size={15} /> Crear categoría
            </button>
          </div>
        </div>

        {/* ——— COLECCIONES ——— */}
        <div className="card" style={{ overflow: 'hidden' }}>
          <div style={{ padding: '18px 20px', borderBottom: '1px solid var(--line)' }}>
            <h3 style={{ margin: 0, fontSize: 16, fontWeight: 700, color: 'var(--ink)' }}>Colecciones</h3>
            <p style={{ margin: '3px 0 0', fontSize: 12.5, color: 'var(--ink-3)' }}>{collections.length} colecciones · series de fotografías</p>
          </div>

          <div>
            {collections.length === 0 && (
              <p style={{ padding: '18px 20px', margin: 0, fontSize: 13.5, color: 'var(--ink-3)' }}>No hay colecciones. Crea la primera.</p>
            )}
            {collections.map(col => {
              const count = photosInCol(col);
              return (
                <div key={col} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 20px', borderBottom: '1px solid var(--line-2)' }}>
                  <Icon name="layers" size={15} style={{ color: 'var(--ink-3)', flexShrink: 0 }} />
                  <span style={{ flex: 1, fontSize: 14.5, fontWeight: 600, color: 'var(--ink)' }}>{col}</span>
                  <span style={{ fontSize: 12, color: 'var(--ink-3)', whiteSpace: 'nowrap' }}>{count} foto{count !== 1 ? 's' : ''}</span>
                  <button onClick={() => requestDeleteCol(col)}
                    title="Eliminar colección"
                    style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--ink-3)', padding: 5, borderRadius: 'var(--r-sm)', display: 'grid', placeItems: 'center', transition: 'color .15s' }}
                    onMouseOver={e => e.currentTarget.style.color = 'var(--rose)'}
                    onMouseOut={e => e.currentTarget.style.color = 'var(--ink-3)'}>
                    <Icon name="trash" size={15} />
                  </button>
                </div>
              );
            })}
          </div>

          <div style={{ padding: '18px 20px', background: 'var(--surface-2)', borderTop: collections.length ? '1px solid var(--line)' : 'none' }}>
            <p style={{ margin: '0 0 10px', fontSize: 13, fontWeight: 600, color: 'var(--ink-2)' }}>Nueva colección</p>
            <input className="input" placeholder="Ej: Primavera 2025, Editorial…" value={colName}
              onChange={e => { setColName(e.target.value); setColError(''); }}
              onKeyDown={e => e.key === 'Enter' && addCollection()}
              style={{ marginBottom: 10 }} />
            {colError && <p style={{ margin: '0 0 8px', fontSize: 12.5, color: 'var(--danger-text)' }}>{colError}</p>}
            <button className="btn btn-primary btn-sm" onClick={addCollection}>
              <Icon name="plus" size={15} /> Crear colección
            </button>
          </div>
        </div>
      </div>

      {/* ——— Nota informativa ——— */}
      <div className="card" style={{ padding: '14px 18px', marginTop: 22, display: 'flex', alignItems: 'center', gap: 12, background: 'var(--sky-tint)', borderColor: 'var(--sky-soft)' }}>
        <Icon name="info" size={18} style={{ color: 'var(--sky-text)', flexShrink: 0 }} />
        <p style={{ margin: 0, fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.55 }}>
          Los cambios se guardan automáticamente en Supabase y se aplican en toda la app. Si eliminas una categoría o colección con fotos asignadas, esas fotos quedarán sin clasificar — puedes reasignarlas desde <button onClick={() => go('manage')} style={{ background: 'none', border: 'none', padding: 0, color: 'var(--sky-text)', fontWeight: 600, cursor: 'pointer', textDecoration: 'underline' }}>Fotografías</button>.
        </p>
      </div>

      {/* ——— Modales de confirmación ——— */}
      {confirmCat && (
        <CatalogConfirmModal
          title="Eliminar categoría"
          message={`La categoría "${categories.find(c => c.id === confirmCat)?.label}" tiene ${photosInCat(confirmCat)} foto${photosInCat(confirmCat) !== 1 ? 's' : ''} asignadas. Seguirán existiendo pero quedarán sin categoría.`}
          onCancel={() => setConfirmCat(null)}
          onConfirm={() => doDeleteCat(confirmCat)}
        />
      )}

      {confirmCol && (
        <CatalogConfirmModal
          title="Eliminar colección"
          message={`La colección "${confirmCol}" tiene ${photosInCol(confirmCol)} foto${photosInCol(confirmCol) !== 1 ? 's' : ''} asignadas. Seguirán existiendo pero quedarán sin colección.`}
          onCancel={() => setConfirmCol(null)}
          onConfirm={() => doDeleteCol(confirmCol)}
        />
      )}
    </DashLayout>
  );
}

Object.assign(window, { CatalogManager });
