// authorize.jsx — Browser-mediated desktop authorization page.
//
// Replaces pairing-code UX (onboard-step-pair.jsx). Lives at
// /authorize?callback=http://localhost:N&device_name=...
//
// Same pattern as `gh auth login` / `stripe login` / `firebase login`:
// desktop opens this URL in the user's browser, user clicks Allow,
// browser redirects back to the localhost callback with a custom-token
// query param.
//
// Loaded by Root() in index.html when path === '/authorize'.

(function (window) {
  'use strict';

  const { useAuth, AuthGate, db, fns, signOut } = window.exoteamAuth || {};
  if (!useAuth) {
    console.error('authorize.jsx: window.exoteamAuth missing');
    return;
  }

  function Authorize() {
    return (
      <AuthGate>
        <AuthorizeInner />
      </AuthGate>
    );
  }

  function AuthorizeInner() {
    const { user, userDoc } = useAuth();
    const params = React.useMemo(() => new URLSearchParams(window.location.search), []);
    const callbackUrl = params.get('callback') || '';
    const deviceName =
      params.get('device_name') ||
      params.get('name') ||
      'Untitled device';

    const [state, setState] = React.useState('idle'); // idle | authorizing | success | error | denied
    const [error, setError] = React.useState(null);

    // Validate callback shape — must be localhost / loopback so a malicious
    // page can't trick a user into authorizing a remote attacker.
    const callbackError = React.useMemo(() => {
      if (!callbackUrl) return 'No callback URL was provided.';
      try {
        const u = new URL(callbackUrl);
        const isLoopback =
          u.hostname === 'localhost' ||
          u.hostname === '127.0.0.1' ||
          u.hostname === '::1';
        if (!isLoopback) {
          return 'Callback URL must point to localhost or 127.0.0.1.';
        }
        return null;
      } catch {
        return 'Callback URL is not a valid URL.';
      }
    }, [callbackUrl]);

    async function handleAllow() {
      if (callbackError) return;
      setState('authorizing');
      setError(null);
      try {
        const callable = fns.httpsCallable('authorizeDevice');
        const { data } = await callable({
          device_name: deviceName,
          callback_url: callbackUrl,
          user_agent: typeof navigator !== 'undefined' ? navigator.userAgent : '',
        });
        // Redirect back to the desktop's local HTTP server.
        const redir = new URL(callbackUrl);
        redir.searchParams.set('token', data.custom_token);
        redir.searchParams.set('device_id', data.device_id);
        redir.searchParams.set('workspace_id', data.workspace_id);
        setState('success');
        // Small delay so the success state is visible briefly before
        // the browser jumps to localhost.
        setTimeout(() => {
          window.location.assign(redir.toString());
        }, 1200);
      } catch (err) {
        console.error('authorize: authorizeDevice failed', err);
        setError(err.message || String(err));
        setState('error');
      }
    }

    function handleDeny() {
      setState('denied');
      // If we have a callback URL, redirect with an explicit denial so the
      // desktop knows to stop polling / waiting.
      if (!callbackError && callbackUrl) {
        try {
          const redir = new URL(callbackUrl);
          redir.searchParams.set('error', 'access_denied');
          redir.searchParams.set('error_description', 'User denied authorization');
          setTimeout(() => window.location.assign(redir.toString()), 1000);
        } catch {
          // Stay on the page.
        }
      }
    }

    const name = (userDoc && userDoc.display_name) || (user && user.email) || 'there';

    if (state === 'success') {
      return (
        <div className="exo-auth-shell">
          <div className="exo-auth-card exo-auth-card--centred">
            <div className="exo-spinner" aria-hidden="true" />
            <h1 className="exo-auth-title">Authorized ✓</h1>
            <p className="exo-auth-body">
              Returning you to your desktop client…
            </p>
          </div>
        </div>
      );
    }

    if (state === 'denied') {
      return (
        <div className="exo-auth-shell">
          <div className="exo-auth-card exo-auth-card--centred">
            <h1 className="exo-auth-title">Authorization denied</h1>
            <p className="exo-auth-body">
              No device was authorized. You can close this tab.
            </p>
          </div>
        </div>
      );
    }

    return (
      <div className="exo-auth-shell">
        <div className="exo-auth-card">
          <h1 className="exo-auth-title">Authorize a device</h1>
          <p className="exo-auth-body">
            Hi {name}, your desktop client is asking for permission to
            access your Exoteam Workspaces.
          </p>

          <div
            style={{
              background: 'var(--exo-bone)',
              borderRadius: 10,
              padding: '14px 16px',
              margin: '8px 0',
              fontSize: 14,
            }}
          >
            <div style={{ fontSize: 11.5, color: '#8a8a92', textTransform: 'uppercase', letterSpacing: 0.04, marginBottom: 4 }}>
              Device
            </div>
            <div style={{ fontWeight: 500, color: 'var(--exo-ink)' }}>
              {deviceName}
            </div>
          </div>

          <div style={{ fontSize: 13, lineHeight: 1.55, color: '#4a4a52' }}>
            <p style={{ margin: '8px 0' }}>This will let the desktop client:</p>
            <ul
              style={{
                paddingLeft: 20,
                margin: '4px 0 8px',
                color: '#4a4a52',
                lineHeight: 1.7,
              }}
            >
              <li>Sync your Workspaces, products, and ICPs from the registry</li>
              <li>Manage Google Workspace tokens locally on your device</li>
              <li>Run scheduled scouts and morning reports on your behalf</li>
              <li>Send outreach drafts from your connected Workspaces</li>
            </ul>
            <p style={{ margin: '8px 0', fontSize: 12.5, color: '#8a8a92' }}>
              You can revoke this device any time from Settings → Workspace.
            </p>
          </div>

          {callbackError && (
            <p className="exo-auth-error">
              <strong>Invalid request:</strong> {callbackError} This usually
              means the link was opened manually instead of by the desktop
              client. Re-launch the desktop app and try again.
            </p>
          )}

          {error && <p className="exo-auth-error">{error}</p>}

          <div style={{ display: 'flex', gap: 12, marginTop: 16 }}>
            <button
              type="button"
              onClick={handleDeny}
              disabled={state === 'authorizing'}
              style={{
                flex: 1,
                padding: '11px 16px',
                fontSize: 15,
                fontWeight: 500,
                border: '1px solid rgba(10,10,26,0.14)',
                background: '#fff',
                color: 'var(--exo-ink)',
                borderRadius: 10,
                cursor: 'pointer',
                fontFamily: 'inherit',
              }}
            >
              Deny
            </button>
            <button
              type="button"
              className="exo-auth-submit"
              style={{ flex: 1, margin: 0 }}
              onClick={handleAllow}
              disabled={state === 'authorizing' || !!callbackError}
            >
              {state === 'authorizing' ? 'Authorizing…' : 'Allow'}
            </button>
          </div>

          <p className="exo-auth-tos" style={{ marginTop: 16 }}>
            Signed in as <strong>{user && user.email}</strong> ·{' '}
            <button type="button" className="exo-link" onClick={() => signOut()}>
              not you?
            </button>
          </p>
        </div>
      </div>
    );
  }

  window.Authorize = Authorize;
})(window);
