// cascade.jsx — Cascade search visualization (drill = desktop, stack = mobile)
const { useState: useStateC, useRef: useRefC, useEffect: useEffectC } = React;

/* ═══════════════════ SHARED: LEVEL INPUT ═══════════════════ */
function CascadeInput({ onSubmit, placeholder, disabled, autoFocus, style }) {
  const [val, setVal] = useStateC('');
  const ref = useRefC(null);
  useEffectC(() => { if (autoFocus && ref.current) ref.current.focus(); }, [autoFocus]);
  const submit = () => {
    const t = val.trim();
    if (t) { onSubmit(t); setVal(''); }
  };
  return (
    <input ref={ref} className="input" value={val} disabled={disabled}
      onChange={e => setVal(e.target.value)}
      onKeyDown={e => { if (e.key === 'Enter') submit(); }}
      placeholder={placeholder || 'Refinar busca...'}
      style={{ fontSize: 'inherit', ...style }}
    />
  );
}

/* ═══════════════════ SHARED: EDIT INPUT ═══════════════════ */
function InlineEdit({ value, onSave, onCancel }) {
  const [val, setVal] = useStateC(value);
  const ref = useRefC(null);
  useEffectC(() => { if (ref.current) { ref.current.focus(); ref.current.select(); } }, []);
  return (
    <input ref={ref} className="input" value={val}
      onChange={e => setVal(e.target.value)}
      onKeyDown={e => { if (e.key === 'Enter') onSave(val.trim()); if (e.key === 'Escape') onCancel(); }}
      onBlur={() => onSave(val.trim())}
      style={{ width: Math.max(80, val.length * 8 + 20), fontSize: 'inherit', padding: '2px 6px' }}
    />
  );
}

/* ═══════════════════ SHARED: REDUCTION INDICATOR ═══════════════════ */
function ReductionPct({ from, to, style }) {
  if (!from || !to || from === 0) return null;
  const pct = Math.round((to / from) * 100);
  const reduction = 100 - pct;
  const txt = reduction >= 99 ? '−0.1%' : reduction >= 1 ? `−${reduction}%` : `−${reduction.toFixed(1)}%`;
  return (
    <span style={{
      fontFamily:'var(--font-mono)', fontSize:'0.7rem', color:'var(--text-3)',
      fontWeight:500, whiteSpace:'nowrap', ...style
    }} title={`${pct}% restante do nível anterior`}>{txt}</span>
  );
}

/* ═══════════════════ STYLE A: DRILL (desktop default) ═══════════════════ */
function CascadeDrill({ levels, activeLevel, onNavigate, onEdit, onRemove, onAdd, maxLevels, esgotado }) {
  const [editing, setEditing] = useStateC(null);
  const canAdd = levels.length < maxLevels && levels.length > 0 && !esgotado;

  const drillS = {
    wrap: { display:'flex', alignItems:'center', gap:0, flexWrap:'wrap', padding:'var(--sp-3) var(--sp-4)', background:'var(--bg-1)', borderBottom:'1px solid var(--border-1)', minHeight:48 },
    base: { display:'flex', alignItems:'baseline', gap:'var(--sp-2)', padding:'4px 12px', background:'var(--bg-2)', border:'1px solid var(--border-1)', borderRadius:'var(--radius)', marginRight:2, cursor:'pointer', transition:'all var(--tr-fast)' },
    baseCount: { fontFamily:'var(--font-mono)', fontWeight:600, fontSize:'1rem', color:'var(--text-0)', letterSpacing:'-0.01em' },
    baseLabel: { color:'var(--text-3)', fontWeight:400, fontSize:'0.77rem' },
    sep: { display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', color:'var(--text-3)', margin:'0 4px', flexShrink:0, minWidth:36, gap:1 },
    level: (isActive) => ({
      display:'flex', alignItems:'baseline', gap:'var(--sp-2)',
      padding:'4px 12px', borderRadius:'var(--radius)', cursor:'pointer',
      background: isActive ? 'var(--accent-subtle)' : 'var(--bg-2)',
      border: isActive ? '1px solid var(--accent-muted)' : '1px solid var(--border-1)',
      transition: 'all var(--tr-fast)', position:'relative'
    }),
    num: (isActive) => ({
      width:18, height:18, borderRadius:'var(--radius-sm)',
      background: isActive ? 'var(--accent)' : 'var(--depth-bar)',
      color:'#fff', display:'flex', alignItems:'center', justifyContent:'center',
      fontSize:'0.7rem', fontWeight:700, fontFamily:'var(--font-mono)', flexShrink:0, opacity: isActive ? 1 : 0.45,
      alignSelf:'center'
    }),
    term: { fontWeight:500, color:'var(--text-0)', whiteSpace:'nowrap', fontSize:'0.923rem' },
    count: { fontFamily:'var(--font-mono)', fontSize:'1rem', color:'var(--text-0)', fontWeight:600, letterSpacing:'-0.01em' },
    remove: { padding:'0 2px', cursor:'pointer', color:'var(--text-3)', borderRadius:'var(--radius-sm)', display:'flex', alignItems:'center', marginLeft:2, alignSelf:'center' },
    addWrap: { display:'flex', alignItems:'center', gap:'var(--sp-2)', marginLeft:2 },
    esgotado: { display:'flex', alignItems:'center', gap:'var(--sp-2)', padding:'4px 10px', background:'var(--warning-subtle)', borderRadius:'var(--radius)', fontSize:'0.846rem', color:'var(--warning)', fontWeight:500 }
  };

  return (
    <div style={drillS.wrap}>
      {/* Base */}
      <div style={drillS.base} onClick={() => levels.length > 0 && onNavigate(-1)}
        onMouseEnter={e => e.currentTarget.style.background='var(--bg-hover)'}
        onMouseLeave={e => e.currentTarget.style.background='var(--bg-2)'}>
        <span style={drillS.baseCount}>{fmtNum(MockAPI.BASE_TOTAL)}</span>
        <span style={drillS.baseLabel}>proposições</span>
      </div>

      {/* Levels */}
      {levels.map((lv, i) => {
        const prevTotal = i === 0 ? MockAPI.BASE_TOTAL : levels[i-1].total;
        return (
          <React.Fragment key={i}>
            <div style={drillS.sep}>
              <IcoChevRight size={10}/>
              {i > 0 && <ReductionPct from={prevTotal} to={lv.total}/>}
            </div>
            <div style={drillS.level(i === activeLevel)}
              onClick={() => onNavigate(i)}
              onMouseEnter={e => { if (i !== activeLevel) e.currentTarget.style.background='var(--bg-hover)'; }}
              onMouseLeave={e => { if (i !== activeLevel) e.currentTarget.style.background='var(--bg-2)'; }}>
              <span style={drillS.num(i === activeLevel)}>{i + 1}</span>
              {editing === i ? (
                <InlineEdit value={lv.termo} onSave={v => { setEditing(null); if (v && v !== lv.termo) onEdit(i, v); }} onCancel={() => setEditing(null)}/>
              ) : (
                <span style={drillS.term} onDoubleClick={(e) => { e.stopPropagation(); setEditing(i); }}>{lv.termo}</span>
              )}
              <span style={drillS.count}>{fmtNum(lv.total)}</span>
              <span style={drillS.remove} title="Remover nível"
                onClick={e => { e.stopPropagation(); onRemove(i); }}
                onMouseEnter={e => e.currentTarget.style.color='var(--danger)'}
                onMouseLeave={e => e.currentTarget.style.color='var(--text-3)'}>
                <IcoClose size={10}/>
              </span>
            </div>
          </React.Fragment>
        );
      })}

      {/* Esgotado indicator */}
      {esgotado && (
        <>
          <div style={drillS.sep}><IcoChevRight size={10}/></div>
          <div style={drillS.esgotado}>Nenhuma proposição contém esse termo</div>
        </>
      )}

      {/* Add level input */}
      {canAdd && !esgotado && (
        <>
          <div style={drillS.sep}><IcoChevRight size={10}/></div>
          <div style={drillS.addWrap}>
            <CascadeInput onSubmit={onAdd} placeholder={`Nível ${levels.length + 1}...`} style={{width:160, padding:'3px 8px', fontSize:'0.846rem'}}/>
          </div>
        </>
      )}

      {/* Max reached */}
      {levels.length >= maxLevels && !esgotado && (
        <>
          <div style={drillS.sep}><IcoChevRight size={10}/></div>
          <div style={{fontSize:'0.77rem', color:'var(--text-3)', padding:'4px 8px'}}>máx. {maxLevels} níveis</div>
        </>
      )}
    </div>
  );
}

/* ═══════════════════ STYLE C: STACK (mobile default) ═══════════════════ */
function CascadeStack({ levels, activeLevel, onNavigate, onEdit, onRemove, onAdd, maxLevels, esgotado }) {
  const [editing, setEditing] = useStateC(null);
  const canAdd = levels.length < maxLevels && levels.length > 0 && !esgotado;
  const depthBgs = ['var(--depth-bg-1)','var(--depth-bg-2)','var(--depth-bg-3)','var(--depth-bg-4)'];

  const stackS = {
    wrap: { background:'var(--bg-1)', borderBottom:'1px solid var(--border-1)' },
    row: (i, isActive) => ({
      display:'flex', alignItems:'center', gap:'var(--sp-3)',
      padding: isActive ? 'var(--sp-3) var(--sp-4)' : 'var(--sp-2) var(--sp-4)',
      background: depthBgs[i] || depthBgs[3],
      borderBottom: '1px solid var(--border-1)',
      cursor:'pointer', transition:'all var(--tr-fast)',
      borderLeft: isActive ? '3px solid var(--accent)' : '3px solid transparent'
    }),
    num: { fontFamily:'var(--font-mono)', fontSize:'0.77rem', fontWeight:700, color:'var(--accent-text)', width:20, flexShrink:0 },
    term: { fontWeight:500, color:'var(--text-0)', flex:1 },
    count: { fontFamily:'var(--font-mono)', fontSize:'0.846rem', color:'var(--text-1)', fontWeight:600 },
    countLabel: { fontSize:'0.77rem', color:'var(--text-2)', fontWeight:400, marginLeft:4 },
    actions: { display:'flex', gap:'var(--sp-1)', opacity:0.5 },
    addRow: { display:'flex', alignItems:'center', gap:'var(--sp-3)', padding:'var(--sp-2) var(--sp-4)', borderBottom:'1px solid var(--border-1)', background:'var(--bg-2)' },
    esgotadoRow: { display:'flex', alignItems:'center', gap:'var(--sp-3)', padding:'var(--sp-2) var(--sp-4)', background:'var(--warning-subtle)', borderBottom:'1px solid var(--border-1)' }
  };

  return (
    <div style={stackS.wrap}>
      {levels.map((lv, i) => {
        const prevTotal = i === 0 ? MockAPI.BASE_TOTAL : levels[i-1].total;
        return (
          <div key={i} style={stackS.row(i, i === activeLevel)} onClick={() => onNavigate(i)}
            onMouseEnter={e => { const a = e.currentTarget.querySelector('.stack-actions'); if (a) a.style.opacity = 1; }}
            onMouseLeave={e => { const a = e.currentTarget.querySelector('.stack-actions'); if (a) a.style.opacity = 0.5; }}>
            <span style={stackS.num}>{i + 1}</span>
            {editing === i ? (
              <InlineEdit value={lv.termo} onSave={v => { setEditing(null); if (v && v !== lv.termo) onEdit(i, v); }} onCancel={() => setEditing(null)}/>
            ) : (
              <span style={stackS.term} onDoubleClick={e => { e.stopPropagation(); setEditing(i); }}>{lv.termo}</span>
            )}
            {i > 0 && <ReductionPct from={prevTotal} to={lv.total} style={{marginRight:'var(--sp-2)'}}/>}
            <span style={stackS.count}>
              {fmtNum(lv.total)}<span style={stackS.countLabel}>resultados</span>
            </span>
            <span className="stack-actions" style={stackS.actions}>
              <span className="btn-xs btn-ghost" style={{cursor:'pointer',display:'flex',padding:2}} title="Editar"
                onClick={e => { e.stopPropagation(); setEditing(i); }}>
                <IcoEdit size={11}/>
              </span>
              <span className="btn-xs btn-ghost" style={{cursor:'pointer',display:'flex',padding:2,color:'var(--danger)'}} title="Remover"
                onClick={e => { e.stopPropagation(); onRemove(i); }}>
                <IcoClose size={11}/>
              </span>
            </span>
          </div>
        );
      })}
      {esgotado && (
        <div style={stackS.esgotadoRow}>
          <span style={{...stackS.num, color:'var(--warning)'}}>—</span>
          <span style={{fontSize:'0.846rem', color:'var(--warning)', fontWeight:500}}>Nenhuma proposição neste nível contém esse termo — tente uma palavra diferente</span>
        </div>
      )}
      {canAdd && !esgotado && (
        <div style={stackS.addRow}>
          <span style={{...stackS.num, color:'var(--text-3)'}}>{levels.length + 1}</span>
          <CascadeInput onSubmit={onAdd} placeholder="Refinar dentro destes resultados..." style={{flex:1, padding:'4px 8px', fontSize:'0.923rem'}}/>
        </div>
      )}
    </div>
  );
}

/* ═══════════════════ WRAPPER: CASCADE ═══════════════════ */
function Cascade({ style: cascadeStyle, ...props }) {
  switch(cascadeStyle) {
    case 'stack': return <CascadeStack {...props}/>;
    default: return <CascadeDrill {...props}/>;
  }
}

Object.assign(window, { CascadeInput, Cascade, CascadeDrill, CascadeStack });
