/* Root — auth gate, API-backed state, routing, tweaks ===============
   Auth + team + connection + ad data now come from the PHP/MySQL backend
   (see /api and apiClient.jsx). The dashboard chrome lives in shell.jsx
   (Workspace); the Admin Panel lives in admin.jsx.
=================================================================== */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "defaultView": "dashboard",
  "adminDensity": "comfortable"
}/*EDITMODE-END*/;

function BootSplash({ brand }){
  return (
    <div className="min-h-screen grid place-items-center bg-ink-50 dark:bg-ink-900">
      <div className="flex flex-col items-center gap-3 animate-fade">
        <BrandLogo brand={brand} size={40}/>
        <div className="inline-flex items-center gap-2 text-[12px] font-mono text-ink-400">
          <span className="w-3.5 h-3.5 rounded-full border-2 border-ink-300 border-t-accent-500 animate-spin"/>
          connecting…
        </div>
      </div>
    </div>
  );
}

/* Error boundary — a render error in any view shows a recoverable card
   instead of a white screen. */
class ErrorBoundary extends React.Component {
  constructor(props){ super(props); this.state = { error: null }; }
  static getDerivedStateFromError(error){ return { error }; }
  componentDidCatch(error, info){
    console.error('[relay] render error:', error, info && info.componentStack);
  }
  render(){
    if (this.state.error){
      return (
        <div className="min-h-[60vh] grid place-items-center p-6">
          <div className="max-w-md w-full rounded-2xl border border-rose-200 dark:border-rose-500/30 bg-white dark:bg-ink-900 p-6 text-center shadow-card">
            <div className="text-[15px] font-semibold mb-1">Something broke while rendering this view</div>
            <div className="text-[12.5px] text-ink-500 dark:text-ink-300 font-mono mb-4 break-all">
              {String(this.state.error && this.state.error.message || this.state.error)}
            </div>
            <div className="flex items-center justify-center gap-2">
              <button onClick={()=>this.setState({error:null})}
                className="h-9 px-4 rounded-lg bg-accent-600 text-white text-[13px] font-medium hover:bg-accent-700 transition">Try again</button>
              <button onClick={()=>location.reload()}
                className="h-9 px-4 rounded-lg border border-ink-200 dark:border-white/10 text-[13px] font-medium hover:bg-ink-100 dark:hover:bg-white/5 transition">Reload app</button>
            </div>
          </div>
        </div>
      );
    }
    return this.props.children;
  }
}
window.ErrorBoundary = ErrorBoundary;

function Root(){
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  const [boot, setBoot]            = useState('checking');   // checking | ready
  const [wsLoaded, setWsLoaded]    = useState(false);        // workspace data ready
  const [currentUser, setCurrentUser] = useState(null);
  const [users, setUsers]          = useState([]);
  const [integrations, setIntegrations] = useState([]);
  const [audit, setAudit]          = useState([]);
  const [accounts, setAccountsState] = useState([]);
  const [brand, setBrandRaw]       = useState(loadBranding);
  const [dark, setDark]            = useState(()=>loadLS(LS.theme, false));
  const [view, setView]            = useState('dashboard');

  const setBrand = (b)=>{ setBrandRaw(b); saveBranding(b); };
  const applyAccounts = (next)=>{ const arr = typeof next==='function'?next(accounts):next; setAccountsState(arr); setAccounts(arr); };
  useEffect(()=>{ document.documentElement.classList.toggle('dark', dark); saveLS(LS.theme, dark); }, [dark]);
  useEffect(()=>{ document.title = (brand.name||'Relay') + ' — Ads Dashboard'; }, [brand.name]);

  /* ---- Data loaders ---- */
  const refreshAudit = ()=> RelayAPI.audit.list().then(setAudit).catch(()=>{});
  const loadWorkspaceData = React.useCallback(async ()=>{
    const [accs, ints] = await Promise.all([
      RelayAPI.accounts.list().catch(()=>[]),
      RelayAPI.integrations.list().catch(()=>[]),
    ]);
    setAccounts(accs); setAccountsState(accs); setIntegrations(ints);
    // Team + audit need admin permission; ignore failures for non-admins.
    RelayAPI.users.list().then(setUsers).catch(()=>setUsers([]));
    refreshAudit();
    setWsLoaded(true);
  }, []);

  /* ---- Restore session on first load ---- */
  useEffect(()=>{
    RelayAPI.auth.me()
      .then(r => { setCurrentUser(r.user); return loadWorkspaceData(); })
      .catch(()=>{})
      .finally(()=> setBoot('ready'));
  }, []);

  const signIn = async (email, password, remember) => {
    const r = await RelayAPI.auth.login(email, password, remember);   // throws on failure → shown in LoginScreen
    setCurrentUser(r.user);
    await loadWorkspaceData();
    const canAdmin = can(r.user,'users.manage') || can(r.user,'integrations.manage');
    setView(canAdmin && t.defaultView==='admin' ? 'admin' : 'dashboard');
  };
  const signOut = async () => {
    try { await RelayAPI.auth.logout(); } catch(e){}
    RelayLive.clearAll();
    setWsLoaded(false);
    setCurrentUser(null); setUsers([]); setIntegrations([]); setAudit([]);
    setAccounts([]); setAccountsState([]); setView('dashboard');
  };

  const tweaksPanel = (
    <TweaksPanel>
      <TweakSection label="Workspace"/>
      <TweakRadio label="Default view" value={t.defaultView}
        options={['dashboard','admin']} onChange={v=>setTweak('defaultView', v)}/>
      <TweakRadio label="Admin density" value={t.adminDensity}
        options={['comfortable','compact']} onChange={v=>setTweak('adminDensity', v)}/>
    </TweaksPanel>
  );

  if (boot === 'checking') return <BootSplash brand={brand}/>;

  if (!currentUser){
    return (<>
      <LoginScreen onSignIn={signIn} brand={brand}/>
      {tweaksPanel}
    </>);
  }

  if (!wsLoaded) return <BootSplash brand={brand}/>;

  if (view==='admin'){
    return (
      <div data-density={t.adminDensity}>
        <AdminPanel
          currentUser={currentUser}
          users={users} setUsers={setUsers}
          integrations={integrations} setIntegrations={setIntegrations}
          accounts={accounts} setAccounts={applyAccounts}
          audit={audit} pushAudit={refreshAudit}
          brand={brand} setBrand={setBrand}
          onExit={()=>setView('dashboard')}
          onSignOut={signOut}
          dark={dark} setDark={setDark}
        />
        {tweaksPanel}
      </div>
    );
  }

  return (<>
    <GlobalProvider currentUser={currentUser} integrations={integrations} brand={brand}>
      <ErrorBoundary>
        <Workspace
          currentUser={currentUser}
          integrations={integrations}
          onOpenAdmin={()=>setView('admin')}
          onSignOut={signOut}
          dark={dark} setDark={setDark}
          pushAudit={refreshAudit}
        />
      </ErrorBoundary>
    </GlobalProvider>
    {tweaksPanel}
  </>);
}

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