import { AuthProvider } from 'react-oidc-context';
import { useEffect, useState } from 'react';
import { oidcConfig } from './config';
import {
  getDiscoveryUrl,
  getOidcAuthority,
  getOidcClientId,
  isPlaceholderConfig,
} from './env';

type Props = { children: React.ReactNode };

export function AuthShell({ children }: Props) {
  const [ready, setReady] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const authority = getOidcAuthority();
  const clientId = getOidcClientId();
  const discoveryUrl = getDiscoveryUrl();

  useEffect(() => {
    if (isPlaceholderConfig()) {
      setError(
        'OIDC is still using placeholder values in frontend/.env. ' +
          'Point VITE_AUTHENTIK_URL at your running Authentik instance and set VITE_OIDC_CLIENT_ID from the provider.',
      );
      return;
    }

    let cancelled = false;

    (async () => {
      try {
        const response = await fetch(discoveryUrl);
        if (!response.ok) {
          throw new Error(`HTTP ${response.status} from ${discoveryUrl}`);
        }
        if (!cancelled) {
          setError(null);
          setReady(true);
        }
      } catch (err) {
        if (!cancelled) {
          const message =
            err instanceof Error ? err.message : 'Could not reach Authentik';
          setError(
            `Cannot reach Authentik OIDC discovery (${message}). ` +
              'Start Authentik (see deploy/README.md) or fix VITE_AUTHENTIK_URL / VITE_OIDC_APP_SLUG in frontend/.env.',
          );
        }
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [discoveryUrl]);

  if (error) {
    return (
      <div className="app setup-error">
        <h1>OIDC configuration</h1>
        <p className="error">{error}</p>
        <section className="card">
          <h2>Current settings</h2>
          <dl>
            <dt>Issuer</dt>
            <dd>{authority}</dd>
            <dt>Client ID</dt>
            <dd>{clientId}</dd>
            <dt>Discovery</dt>
            <dd>
              <a href={discoveryUrl} target="_blank" rel="noreferrer">
                {discoveryUrl}
              </a>
            </dd>
          </dl>
        </section>
        <p className="hint">
          After Authentik is running, create an OAuth2/OpenID provider (public,
          redirect URI <code>http://localhost:5173</code>) and copy its slug and
          client ID into <code>frontend/.env</code> and <code>backend/.env</code>.
        </p>
      </div>
    );
  }

  if (!ready) {
    return <div className="app">Connecting to Authentik…</div>;
  }

  return <AuthProvider {...oidcConfig}>{children}</AuthProvider>;
}
