/* Shared components for iGreen Central */
const { useState, useEffect, useRef, useMemo, useCallback, Fragment } = React;

// --- Icon -------------------------------------------------
function Icon({ name, size = 18, stroke = 1.7 }) {
  const d = window.ICONS[name];
  if (!d) return null;
  // Some icons have multiple paths separated by " M" — split into <path>s
  const paths = d.split(/\s(?=M)/);
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
         stroke="currentColor" strokeWidth={stroke}
         strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      {paths.map((p, i) => <path key={i} d={p} />)}
    </svg>
  );
}

// --- Shared search filter + results list -------------------
// Used by the home hero search, the header search, and the centered Ctrl+K palette
// — keeping a single rendering so all entry points feel coherent.
function filterTools(q) {
  const isDev = !!(window.__identity && window.__identity.isSuperAdmin);
  const tools = (window.TOOLS || []).filter(t => t.role !== 'lideranca' && (!t.devOnly || isDev));
  if (!q) return tools;
  const s = q.toLowerCase();
  return tools.filter(t =>
    t.title.toLowerCase().includes(s) || t.desc.toLowerCase().includes(s) ||
    t.tag.toLowerCase().includes(s) || t.role.includes(s));
}

function CommandResults({ filtered, idx, setIdx, onOpen, q }) {
  return (
    <Fragment>
      <div className="cmd-r-list">
        {filtered.length ? filtered.map((t, i) => (
          <button key={t.id} type="button"
            onMouseEnter={() => setIdx(i)}
            onMouseDown={(e) => e.preventDefault()}
            onClick={() => onOpen(t.id)}
            className={`cmd-r-item ${idx === i ? 'is-active' : ''}`}>
            <span className="cmd-r-item-ic"><Icon name={t.icon} size={14} /></span>
            <span className="cmd-r-item-title">{t.title}</span>
            <span className="cmd-r-item-desc">{t.desc}</span>
            <span className="cmd-r-item-role mono">{t.role.toUpperCase()}</span>
          </button>
        )) : (
          <div className="cmd-r-empty">Nada encontrado para "{q}".</div>
        )}
      </div>
      <div className="cmd-r-footer">
        <span><span className="kbd">↑</span> <span className="kbd">↓</span> NAVEGAR</span>
        <span><span className="kbd">↵</span> ABRIR</span>
        <span><span className="kbd">ESC</span> FECHAR</span>
        <span className="cmd-r-footer-spacer" />
        <span className="mono cmd-r-count">{filtered.length} RESULTADO{filtered.length === 1 ? '' : 'S'}</span>
      </div>
    </Fragment>
  );
}

// Reusable keyboard-navigable search input. Owns its own dropdown state so the
// results appear ANCHORED to wherever it is rendered (top header, hero, etc).
function InlineSearch({ onOpenTool, placeholder, className, autoFocus, kbdHint }) {
  const [q, setQ] = useState('');
  const [idx, setIdx] = useState(0);
  const [open, setOpen] = useState(false);
  const inputRef = useRef(null);
  const wrapRef = useRef(null);

  const filtered = useMemo(() => filterTools(q), [q]);
  useEffect(() => { setIdx(0); }, [q]);

  useEffect(() => {
    if (!autoFocus) return;
    const t = setTimeout(() => inputRef.current?.focus(), 180);
    return () => clearTimeout(t);
  }, [autoFocus]);

  // Close on outside click
  useEffect(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [open]);

  const onKey = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setOpen(true); setIdx(i => Math.min(filtered.length - 1, i + 1)); }
    else if (e.key === 'ArrowUp') { e.preventDefault(); setIdx(i => Math.max(0, i - 1)); }
    else if (e.key === 'Enter') {
      e.preventDefault();
      const t = filtered[idx];
      if (t) { onOpenTool(t.id); setQ(''); setOpen(false); inputRef.current?.blur(); }
    }
    else if (e.key === 'Escape') { setQ(''); setOpen(false); inputRef.current?.blur(); }
  };

  const showDropdown = open && q.length > 0;

  return (
    <div ref={wrapRef} className={`inline-search ${className || ''} ${showDropdown ? 'is-open' : ''}`}>
      <div className="inline-search-bar" onClick={() => inputRef.current?.focus()}>
        <span className="inline-search-icon"><Icon name="search" size={16} /></span>
        <input
          ref={inputRef}
          type="text"
          className="inline-search-input"
          value={q}
          onChange={e => { setQ(e.target.value); setOpen(true); }}
          onFocus={() => setOpen(true)}
          onKeyDown={onKey}
          placeholder={placeholder || 'Buscar ferramenta, colaborador, conversa…'}
          autoComplete="off"
          spellCheck={false}
          aria-label="Buscar ferramenta"
        />
        {kbdHint && !q && (
          <span className="inline-search-hint">
            {kbdHint}
          </span>
        )}
      </div>
      {showDropdown && (
        <div className="inline-search-dropdown" role="listbox">
          <CommandResults filtered={filtered} idx={idx} setIdx={setIdx} q={q}
            onOpen={(id) => { onOpenTool(id); setQ(''); setOpen(false); inputRef.current?.blur(); }} />
        </div>
      )}
    </div>
  );
}

// --- Refresh action ---------------------------------------
// Botão que força re-mount do <main> pai (via pageNonce). Usado pra contornar
// "failed to fetch" sem precisar trocar de menu e voltar. Cooldown visual de 600ms.
function RefreshButton({ onClick }) {
  const [spinning, setSpinning] = useState(false);
  return (
    <button
      type="button"
      aria-label="Atualizar página"
      title="Atualizar (recarrega dados do menu atual)"
      onClick={() => {
        if (spinning) return;
        setSpinning(true);
        onClick();
        setTimeout(() => setSpinning(false), 600);
      }}
      className="header-refresh"
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        width: 34, height: 34, borderRadius: 8,
        background: 'transparent',
        border: 'none',
        color: 'rgba(255,255,255,0.65)',
        cursor: 'pointer',
        transition: 'background 160ms ease, color 160ms ease, border-color 160ms ease',
      }}>
      <span style={{
        display: 'inline-flex',
        animation: spinning ? 'cc-refresh-spin 600ms ease' : 'none',
      }}>
        <Icon name="rotate" size={14} />
      </span>
    </button>
  );
}

// --- Header -----------------------------------------------
function HeaderBar({ user, onOpenTool, breadcrumb, onRefresh, onSignOut, hideSearch }) {
  const [avatarUrl, setAvatarUrl] = useState(user.avatarUrl || null);
  const [avatarMenu, setAvatarMenu] = useState(false);
  const [uploading, setUploading] = useState(false);
  const fileRef = useRef(null);
  const menuRef = useRef(null);

  useEffect(() => {
    if (!avatarMenu) return;
    const onClick = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) setAvatarMenu(false); };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, [avatarMenu]);

  async function handleUpload(e) {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    try {
      const url = await window.CCApi.me.uploadAvatar(file);
      setAvatarUrl(url);
      setAvatarMenu(false);
    } catch {}
    setUploading(false);
    e.target.value = '';
  }

  async function handleRemove() {
    setUploading(true);
    try {
      await window.CCApi.me.removeAvatar();
      setAvatarUrl(null);
      setAvatarMenu(false);
    } catch {}
    setUploading(false);
  }

  return (
    <header className="rise" style={{
      display: 'flex', alignItems: 'center', gap: 14,
      padding: '14px 28px', borderBottom: '1px solid rgba(255,255,255,0.06)',
      position: 'relative', zIndex: 5,
      background: 'linear-gradient(180deg, rgba(10,14,39,0.5), transparent)',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <img src="assets/igreen-logo.png" alt="iGreen Energy"
             onClick={() => window.location.reload()}
             style={{ height: 28, width: 'auto', objectFit: 'contain',
                      filter: 'drop-shadow(0 0 16px rgba(34,197,94,0.30))', cursor: 'pointer' }} />
        <div style={{ width: 1, height: 24, background: 'rgba(255,255,255,0.06)' }} />
        <div>
          <div style={{ fontSize: 13, fontWeight: 600, letterSpacing: '-0.01em' }}>
            Suporte ao Gestor<span style={{ color: 'var(--green)' }}>.</span>
          </div>
          <div className="mono" style={{ fontSize: 8.5, color: 'rgba(255,255,255,0.4)', marginTop: 1 }}>
            CONEXÃO GREEN
          </div>
        </div>
      </div>


      <div style={{ flex: 1 }} />

      {!hideSearch && <InlineSearch
        onOpenTool={onOpenTool}
        className="inline-search--header"
        placeholder="Buscar ferramenta..."
        kbdHint={<Fragment><span className="kbd">⌘</span><span className="kbd">K</span></Fragment>} />}

      {onRefresh && <RefreshButton onClick={onRefresh} />}

      <div style={{ position: 'relative' }} ref={menuRef}>
        <button type="button" onClick={() => setAvatarMenu(o => !o)}
          style={{
            display: 'flex', alignItems: 'center', gap: 10,
            padding: '4px 10px 4px 4px',
            background: 'rgba(255,255,255,0.03)',
            border: 'none',
            borderRadius: 9999, cursor: 'pointer', color: 'inherit',
          }}>
          {avatarUrl ? (
            <img src={avatarUrl} alt="" style={{
              width: 30, height: 30, borderRadius: '50%', objectFit: 'cover',
              border: 'none',
            }} />
          ) : (
            <div style={{
              width: 30, height: 30, borderRadius: '50%',
              background: 'linear-gradient(135deg, #22c55e, #16a34a)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 11, fontWeight: 600, color: '#06170d',
            }}>{user.initials}</div>
          )}
          <div style={{ textAlign: 'left' }}>
            <div style={{ fontSize: 12.5, fontWeight: 500 }}>{user.name}</div>
            <div className="mono" style={{ fontSize: 8.5, color: 'var(--green)', letterSpacing: '0.20em' }}>
              {user.role}
            </div>
          </div>
        </button>

        {avatarMenu && (
          <div style={{
            position: 'absolute', top: '100%', right: 0, marginTop: 6,
            background: 'rgba(15,18,37,0.65)',
            backdropFilter: 'blur(20px) saturate(1.4)',
            WebkitBackdropFilter: 'blur(20px) saturate(1.4)',
            border: 'none',
            borderRadius: 12, padding: 6, minWidth: 180,
            boxShadow: '0 16px 48px rgba(0,0,0,0.45), 0 0 0 1px rgba(255,255,255,0.04) inset',
            zIndex: 100,
          }}>
            <input ref={fileRef} type="file" accept="image/jpeg,image/png,image/webp" style={{ display: 'none' }} onChange={handleUpload} />
            <button type="button" onClick={() => fileRef.current?.click()} disabled={uploading}
              style={{
                width: '100%', padding: '8px 12px', borderRadius: 6, textAlign: 'left',
                background: 'transparent', border: 'none', color: 'rgba(255,255,255,0.8)',
                fontSize: 12, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 8,
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'rgba(255,255,255,0.05)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
              <Icon name="upload" size={13} /> {uploading ? 'Enviando...' : 'Alterar foto'}
            </button>
            {avatarUrl && (
              <button type="button" onClick={handleRemove} disabled={uploading}
                style={{
                  width: '100%', padding: '8px 12px', borderRadius: 6, textAlign: 'left',
                  background: 'transparent', border: 'none', color: 'rgba(239,68,68,0.8)',
                  fontSize: 12, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 8,
                }}
                onMouseEnter={e => e.currentTarget.style.background = 'rgba(239,68,68,0.06)'}
                onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                <Icon name="ban" size={13} /> Remover foto
              </button>
            )}
            <div style={{ borderTop: '1px solid rgba(255,255,255,0.06)', margin: '4px 0' }} />
            <button type="button" onClick={() => {
              setAvatarMenu(false);
              if (onSignOut) window.CCConfirm({
                title: 'Sair da sessão?',
                message: 'Você precisará entrar novamente.',
                confirmLabel: 'Sair', cancelLabel: 'Ficar', tone: 'danger',
              }).then(ok => { if (ok) onSignOut(); });
            }}
              style={{
                width: '100%', padding: '8px 12px', borderRadius: 6, textAlign: 'left',
                background: 'transparent', border: 'none', color: 'rgba(255,255,255,0.5)',
                fontSize: 12, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 8,
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'rgba(255,255,255,0.04)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
              <Icon name="lock" size={13} /> Sair
            </button>
          </div>
        )}
      </div>
    </header>
  );
}

// --- Stat card --------------------------------------------
function Stat({ label, value, trend, accent, spark }) {
  return (
    <div className="stat">
      <div className="lbl">
        <span>/ {label}</span>
        {trend && <span className={`trend ${trend.dir}`} style={{ letterSpacing: 0 }}>
          {trend.dir === 'up' ? '↑' : '↓'} {trend.value}
        </span>}
      </div>
      <div className={`val ${accent ? 'is-accent' : ''}`}>{value}</div>
      {spark && <Sparkline points={spark} color={accent ? '#22c55e' : trend?.dir === 'down' ? '#ef4444' : '#94a3b8'} />}
    </div>
  );
}

function Sparkline({ points, color = '#22c55e' }) {
  const w = 200, h = 14;
  const min = Math.min(...points), max = Math.max(...points);
  const r = max - min || 1;
  const step = w / (points.length - 1);
  const d = points.map((p, i) =>
    `${i === 0 ? 'M' : 'L'} ${i * step} ${h - ((p - min) / r) * h}`
  ).join(' ');
  return (
    <svg className="spark" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
      <path d={d} fill="none" stroke={color} strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" opacity="0.85" />
    </svg>
  );
}

// --- Tool card --------------------------------------------
function ToolCard({ tool, onOpen, delay = 0 }) {
  const cls = 'tool-card rise' + (
    tool.kind === 'danger' ? ' is-danger' :
    tool.kind === 'warn'   ? ' is-warn'   :
    tool.kind === 'info'   ? ' is-info'   : ''
  );
  return (
    <button className={cls} style={{ animationDelay: `${delay}ms` }} onClick={() => onOpen(tool)}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div className="ic"><Icon name={tool.icon} size={16} /></div>
        <span className="mono" style={{ fontSize: 9, color: 'rgba(255,255,255,0.4)', letterSpacing: '0.28em' }}>
          {tool.tag}
        </span>
      </div>
      <h3>{tool.title}</h3>
      <p>{tool.desc}</p>
      <div className="meta">
        <span>{tool.uses}</span>
        <span className="arrow">ABRIR ↗</span>
      </div>
    </button>
  );
}

// --- Section header ---------------------------------------
function SectionTitle({ idx, label, count, sublabel }) {
  return (
    <div className="section-title rise" style={{ marginTop: 36, marginBottom: 14, animationDelay: '120ms' }}>
      <span className="mono" style={{ color: 'var(--green)', fontSize: 11 }}>{`0${idx}`.slice(-2)}</span>
      <h2>{label}</h2>
      {sublabel && <span className="mono" style={{ fontSize: 10, color: 'rgba(255,255,255,0.4)', letterSpacing: '0.28em' }}>· {sublabel}</span>}
      <div className="rule" />
      <span className="count">{count} FERRAMENTAS</span>
    </div>
  );
}

// expose
Object.assign(window, {
  Icon, HeaderBar, Stat, Sparkline, ToolCard, SectionTitle,
});
