import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom/client';
import { LogtoProvider, UserScope, useLogto } from '@logto/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { BrowserRouter } from 'react-router';
import { ThemeProvider, ToastProvider, BreadcrumbProvider, GlobalFilterProvider, CommandPaletteProvider, Spinner } from '@cameleer/design-system';
import '@cameleer/design-system/style.css';
import { AppRouter } from './router';
import { fetchConfig } from './config';
import { setTokenProvider } from './api/client';
import { useOrgStore } from './auth/useOrganization';


const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      retry: 1,
      staleTime: 10_000,
    },
  },
});

function TokenSync({ resource }: { resource: string }) {
  const { getAccessToken, isAuthenticated } = useLogto();
  const { currentOrgId } = useOrgStore();

  // Set token provider — org-scoped if org selected, plain otherwise.
  // OrgResolver is the sole source of org data (via /api/me).
  // eslint-disable-next-line react-hooks/exhaustive-deps — getAccessToken is unstable (new ref each render)
  useEffect(() => {
    if (isAuthenticated && resource) {
      if (currentOrgId) {
        setTokenProvider(() => getAccessToken(resource, currentOrgId));
      } else {
        setTokenProvider(() => getAccessToken(resource));
      }
    } else {
      setTokenProvider(null);
    }
  }, [isAuthenticated, resource, currentOrgId]);

  return null;
}

function App() {
  const [config, setConfig] = useState<{
    logtoEndpoint: string;
    logtoClientId: string;
    logtoResource: string;
    scopes: string[];
  } | null>(null);

  useEffect(() => {
    fetchConfig().then(setConfig);
  }, []);

  if (!config?.logtoClientId) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh' }}>
        <Spinner />
      </div>
    );
  }

  return (
    <LogtoProvider
      config={{
        endpoint: config.logtoEndpoint,
        appId: config.logtoClientId,
        resources: config.logtoResource ? [config.logtoResource] : [],
        scopes: [
          'openid', 'profile', 'email', 'offline_access',
          UserScope.Organizations,
          UserScope.OrganizationRoles,
          // API resource scopes — served from /api/config, must be requested
          // during sign-in for Logto to include them in access tokens.
          ...(config.scopes ?? []),
        ],
      }}
    >
      <TokenSync resource={config.logtoResource} />
      <QueryClientProvider client={queryClient}>
        <BrowserRouter basename="/platform">
          <AppRouter />
        </BrowserRouter>
      </QueryClientProvider>
    </LogtoProvider>
  );
}

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ThemeProvider>
      <ToastProvider>
        <BreadcrumbProvider>
          <GlobalFilterProvider>
            <CommandPaletteProvider>
              <App />
            </CommandPaletteProvider>
          </GlobalFilterProvider>
        </BreadcrumbProvider>
      </ToastProvider>
    </ThemeProvider>
  </React.StrictMode>,
);
