// Main app shell with view routing, tweaks, cmdk, drawer
const { useState: useS, useEffect: useE, useCallback: useC, useRef: useR } = React;

// ── Auth helpers ─────────────────────────────────────────────────────────────
const _TOKEN_KEY = 'rc_token';
function getToken()       { return localStorage.getItem(_TOKEN_KEY); }
function saveToken(t)     { t ? localStorage.setItem(_TOKEN_KEY, t) : localStorage.removeItem(_TOKEN_KEY); }

window.rcFetch = async function(url, opts = {}) {
  const tok = getToken();
  const headers = { 'Content-Type': 'application/json', ...(opts.headers || {}) };
  if (tok) headers['Authorization'] = 'Bearer ' + tok;
  const r = await fetch(url, { ...opts, headers });
  if (r.status === 401) { saveToken(null); window.location.reload(); }
  return r;
};

function useDocAttrs(theme, density) {
  useE(() => {
    document.body.setAttribute('data-theme', theme);
    document.body.setAttribute('data-density', density);
  }, [theme, density]);
}

const TWEAK_DEFAULS = /*EDITMODE-BEGIN*/{
  "theme": "dark",
  "density": "normal"
}/*EDITMODE-END*/;

function LoadingScreen({ error, onRetry }) {
  return (
    <div style={{ height: '100vh', display: 'grid', placeItems: 'center', background: 'var(--bg)' }}>
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>
        {error ? (
          <>
            <span style={{ fontSize: 13, color: 'var(--err)', maxWidth: 420, textAlign: 'center' }}>
              Falha ao carregar dados: {error}
            </span>
            <button
              onClick={onRetry}
              style={{ marginTop: 6, padding: '6px 14px', background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 6, color: 'var(--text)', cursor: 'pointer', fontSize: 13 }}
            >
              Tentar novamente
            </button>
          </>
        ) : (
          <>
            <div className="spin" style={{ width: 22, height: 22, border: '2px solid var(--line-strong)', borderTopColor: 'var(--accent)', borderRadius: '50%' }} />
            <span style={{ fontSize: 12, color: 'var(--text-dim)' }}>Carregando dados…</span>
          </>
        )}
      </div>
    </div>
  );
}

function App() {
  const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULS);

  const [logged, setLogged] = useS(!!getToken());
  const [rcLoaded, setRcLoaded] = useS(false);
  const [loadError, setLoadError] = useS(null);
  const _VALID_VIEWS = ['dashboard', 'clientes', 'times', 'servidores', 'sync', 'historico', 'criar', 'operacao'];
  const [view, setView] = useS(() => {
    const hash = window.location.hash.replace('#', '');
    return _VALID_VIEWS.includes(hash) ? hash : 'dashboard';
  });
  const [openClient, setOpenClient] = useS(null);
  const [cmdkOpen, setCmdkOpen] = useS(false);
  const [confirm, setConfirm] = useS(null);
  const [toast, setToast] = useS(null);

  useDocAttrs(tweaks.theme, tweaks.density);

  const doLoad = useC(async () => {
    setLoadError(null);
    try {
      await window.RC.load();
      setRcLoaded(true);
    } catch (err) {
      setLoadError(err?.message || String(err));
    }
  }, []);

  // Load/reload RC data from API
  const reloadRC = useC(async () => {
    await window.RC.load();
    setRcLoaded(true);
    setOpenClient(cur => cur ? (window.RC.clients.find(c => c.id === cur.id) || null) : cur);
  }, []);
  window.RC.reload = reloadRC;

  useE(() => {
    if (!logged) { setRcLoaded(false); setLoadError(null); return; }
    doLoad();
  }, [logged]);

  const showToast = useC((title, body, kind = 'ok') => {
    setToast({ title, body, kind });
    setTimeout(() => setToast(null), 3500);
  }, []);

  const go = useC((v, opts) => {
    setView(v);
    window.location.hash = v;
    setOpenClient(null);
    if (opts?.selectId) {
      const c = window.RC.clients.find(x => x.id === opts.selectId);
      if (c) setOpenClient(c);
    }
  }, []);

  // Back/forward browser navigation
  useE(() => {
    const onHash = () => {
      const hash = window.location.hash.replace('#', '');
      if (_VALID_VIEWS.includes(hash)) setView(hash);
    };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  // global keyboard shortcuts
  useE(() => {
    let lastG = 0;
    const onKey = (e) => {
      const tag = (e.target.tagName || '').toLowerCase();
      const inField = tag === 'input' || tag === 'textarea' || e.target.isContentEditable;

      // cmdk
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        setCmdkOpen(o => !o);
        return;
      }
      if (inField) return;

      // sequences starting with g
      if (e.key === 'g') {
        lastG = Date.now();
        return;
      }
      if (Date.now() - lastG < 1500) {
        const map = { c: 'clientes', t: 'times', s: 'servidores', y: 'sync', d: 'dashboard', h: 'historico' };
        if (map[e.key]) {
          e.preventDefault();
          go(map[e.key]);
          lastG = 0;
          return;
        }
      }

      if (e.key === '/') {
        e.preventDefault();
        // best effort: focus first input on screen
        const f = document.querySelector('main .input input');
        if (f) f.focus();
      }
      if (e.key === 'n') {
        e.preventDefault();
        go('criar');
      }
      if (e.key === '?') {
        setCmdkOpen(true);
      }
    };
    window.addEventListener('keydown', onKey);
    const onCmdk = () => setCmdkOpen(true);
    window.addEventListener('rc-cmdk', onCmdk);
    return () => { window.removeEventListener('keydown', onKey); window.removeEventListener('rc-cmdk', onCmdk); };
  }, [go]);

  // titles per view
  const titles = {
    dashboard:  { title: 'Dashboard',          crumbs: ['RodaiClientes', 'Dashboard'] },
    clientes:   { title: 'Clientes',           crumbs: ['RodaiClientes', 'Clientes'] },
    times:      { title: 'Times',              crumbs: ['RodaiClientes', 'Times'] },
    servidores: { title: 'Servidores',         crumbs: ['RodaiClientes', 'Servidores'] },
    sync:       { title: 'Sincronização',      crumbs: ['RodaiClientes', 'Sincronização'] },
    historico:  { title: 'Histórico de operações', crumbs: ['RodaiClientes', 'Histórico'] },
    criar:      { title: 'Novo cliente',       crumbs: ['RodaiClientes', 'Clientes', 'Novo'] },
    operacao:   { title: 'Operação op-2412',   crumbs: ['RodaiClientes', 'Operações', 'op-2412'] },
  };

  const topbarActions = (() => {
    if (view === 'clientes') return null;
    if (view === 'dashboard') {
      return (
        <div className="row" style={{ gap: 6 }}>
          <Btn kind="secondary" size="sm" icon="refresh" onClick={() => window.dispatchEvent(new CustomEvent('rc-recheck-all'))}>Verificar tudo</Btn>
          <Btn kind="primary" size="sm" icon="plus" onClick={() => go('criar')}>Novo cliente</Btn>
        </div>
      );
    }
    if (view === 'servidores') {
      return (
        <Btn kind="secondary" size="sm" icon="refresh"
          onClick={() => window.dispatchEvent(new CustomEvent('rc-recheck-all'))}>
          Re-checar todos
        </Btn>
      );
    }
    if (view === 'historico') {
      return (
        <div className="row" style={{ gap: 6 }}>
          <Input placeholder="Filtrar histórico…" icon="search" value="" />
          <Btn kind="secondary" size="sm" icon="download">Exportar CSV</Btn>
        </div>
      );
    }
    return null;
  })();

  const handleLogin  = useC((token) => { saveToken(token); setLogged(true); }, []);
  const handleLogout = useC(() => { saveToken(null); setLogged(false); }, []);

  if (!logged) return <LoginView onLogin={handleLogin} />;
  if (!rcLoaded) return <LoadingScreen error={loadError} onRetry={doLoad} />;

  const t1 = titles[view];

  return (
    <div className="app-shell" style={{ display: 'flex', height: '100vh', background: 'var(--bg)', color: 'var(--text)' }}>
      <Sidebar view={view} setView={go} opsBadge={window.RC.ops.length} />

      <main className="app-main" style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, position: 'relative' }}>
        <Topbar
          title={t1.title}
          crumbs={t1.crumbs}
          info={view === 'clientes' && window.RC.syncDiff.length ? (
            <span className="chip chip-warn"><span className="dot dot-warn" /> {window.RC.syncDiff.length} divergente{window.RC.syncDiff.length !== 1 ? 's' : ''}</span>
          ) : null}
          actions={topbarActions || (
            <div className="row" style={{ gap: 6 }}>
              <button onClick={() => setCmdkOpen(true)} className="row" style={{
                gap: 6, height: 28, padding: '0 8px',
                background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 6,
                fontSize: 12, color: 'var(--text-muted)', cursor: 'pointer',
              }}>
                <Icon name="search" size={12} /> Buscar… <span className="kbd" style={{ marginLeft: 4 }}>⌘K</span>
              </button>
              <IconBtn name="bell" size="md" title="Notificações" />
              <IconBtn name="cog" size="md" title="Configurações" />
            </div>
          )}
        />

        <LiveOpBanner op={window.RC.liveOp} onOpen={() => go('operacao')} />

        <div className="view-scroll" style={{ flex: 1, overflow: 'auto', minHeight: 0 }}>
          {view === 'dashboard'  && <DashboardView go={go} />}
          {view === 'clientes'   && <ClientesView go={go} openClient={(c) => setOpenClient(c)} />}
          {view === 'times'      && <TimesView openClient={(c) => setOpenClient(c)} go={go} />}
          {view === 'servidores' && <ServidoresView />}
          {view === 'sync'       && <SyncView />}
          {view === 'historico'  && <HistoricoView />}
          {view === 'criar'      && <CriarClienteView go={go} onSubmit={(name) => showToast('Cliente criado', `${name} propagado para 3/4 servidores`)} />}
          {view === 'operacao'   && <OperacaoView goBack={() => go('clientes')} />}
        </div>

        {openClient ? (
          <ClientDrawer client={openClient} onClose={() => setOpenClient(null)} go={go} />
        ) : null}
      </main>

      {/* Tweaks panel — self-manages open/close via host protocol */}
      {window.TweaksPanel ? (
        <window.TweaksPanel title="Tweaks">
          <window.TweakSection label="Aparência">
            <window.TweakRadio
              label="Tema"
              value={tweaks.theme}
              onChange={(v) => setTweak('theme', v)}
              options={[
                { value: 'dark',  label: 'Dark' },
                { value: 'light', label: 'Light' },
              ]}
            />
            <window.TweakSelect
              label="Densidade"
              value={tweaks.density}
              onChange={(v) => setTweak('density', v)}
              options={[
                { value: 'compact', label: 'Compacta' },
                { value: 'normal',  label: 'Normal' },
                { value: 'relax',   label: 'Confortável' },
              ]}
            />
          </window.TweakSection>

          <window.TweakSection label="Atalhos">
            <div style={{ fontSize: 11.5, color: 'var(--text-muted)', display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '4px 10px' }}>
              <span className="kbd">⌘K</span><span>Abrir paleta de comandos</span>
              <span className="kbd">/</span><span>Focar busca</span>
              <span className="kbd">N</span><span>Novo cliente</span>
              <span className="kbd">g c</span><span>Ir para Clientes</span>
              <span className="kbd">g t</span><span>Ir para Times</span>
              <span className="kbd">g s</span><span>Ir para Servidores</span>
              <span className="kbd">g y</span><span>Ir para Sincronização</span>
              <span className="kbd">g d</span><span>Ir para Dashboard</span>
              <span className="kbd">g h</span><span>Ir para Histórico</span>
              <span className="kbd">esc</span><span>Fechar painel/drawer</span>
            </div>
          </window.TweakSection>

          <window.TweakSection label="Sessão">
            <window.TweakButton onClick={handleLogout}>Sair</window.TweakButton>
          </window.TweakSection>
        </window.TweaksPanel>
      ) : null}

      <CmdK open={cmdkOpen} onClose={() => setCmdkOpen(false)} gotoView={go} />
      <ConfirmModal open={!!confirm} {...(confirm || {})} onCancel={() => setConfirm(null)} />
      <Toast toast={toast} onClose={() => setToast(null)} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
