import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * AuthScreen — Multi-step authentication and account setup (SUSI flow).
 *
 * Steps:
 *   1. Browser sign-in wait — spinner + login URL until OAuth completes
 *   2. Org selection — picker if the user belongs to multiple orgs
 *   3. Project selection — picker if the org has multiple projects
 *   4. Environment selection — picker if the project has multiple environments
 *   5. API key entry — text input (only if no project key could be resolved)
 *
 * The screen drives itself from session.pendingOrgs + session.credentials.
 * When credentials are set the router resolves past this screen.
 */
import { Box, Text, measureElement } from 'ink';
import { useState, useEffect, useRef } from 'react';
import { TextInput } from '@inkjs/ui';
import { useContentArea } from '../context/ContentAreaContext.js';
import { useWizardStore } from '../hooks/useWizardStore.js';
import { useEscapeBack } from '../hooks/useEscapeBack.js';
import { useScreenInput } from '../hooks/useScreenInput.js';
import { useTimedCoaching } from '../hooks/useTimedCoaching.js';
import { PickerMenu, TerminalLink } from '../primitives/index.js';
import { Colors, Icons } from '../styles.js';
import { BrailleSpinner } from '../components/BrailleSpinner.js';
import { DEFAULT_AMPLITUDE_ZONE, DEFAULT_HOST_URL, } from '../../../lib/constants.js';
import { isCreateAccountOnboarding } from '../../../lib/wizard-session.js';
import { resolveZone } from '../../../lib/zone-resolution.js';
import { toCredentialAppId } from '../../../lib/wizard-session.js';
import { analytics } from '../../../utils/analytics.js';
import { wizardSuccessExit } from '../../../utils/wizard-abort.js';
import { ExitCode } from '../../../lib/exit-codes.js';
const CREATE_ACTION = '__create__';
const RESTART_ACTION = '__restart__';
function isPickerAction(value) {
    return value === CREATE_ACTION || value === RESTART_ACTION;
}
/**
 * Returns the environments with usable API keys from a project, sorted by rank.
 */
function getSelectableEnvironments(project) {
    if (!project?.environments)
        return [];
    return project.environments
        .filter((env) => env.app?.apiKey)
        .sort((a, b) => a.rank - b.rank);
}
function useMeasuredRows(ref) {
    const [rows, setRows] = useState(0);
    useEffect(() => {
        if (!ref.current) {
            if (rows !== 0)
                setRows(0);
            return;
        }
        const { height } = measureElement(ref.current);
        if (height !== rows) {
            setRows(height);
        }
    });
    return rows;
}
export const AuthScreen = ({ store }) => {
    useWizardStore(store);
    // Esc → back to RegionSelect. Self-disables on the very first run
    // (no region picked yet, canGoBack=false) so it doesn't hijack the
    // OAuth-waiting phase.
    useEscapeBack(store);
    const { session } = store;
    const contentArea = useContentArea();
    // Local step state — which org the user has selected in this render session
    const [selectedOrg, setSelectedOrg] = useState(null);
    // When the user invokes the [M] manual fallback while the browser auth
    // hasn't completed (typically because no browser opened — SSH, codespace),
    // we surface a manual API-key input form. The router still resolves Auth
    // when credentials land via setCredentials, so this flow piggybacks on
    // the existing manual entry path (Step 5).
    const [manualFallbackOpen, setManualFallbackOpen] = useState(false);
    // Track the selected project locally so we can access its environments
    const [selectedProject, setSelectedProject] = useState(null);
    const [selectedEnv, setSelectedEnv] = useState(null);
    const [apiKeyError, setApiKeyError] = useState('');
    const [savedKeySource, setSavedKeySource] = useState(null);
    const [pickerNotice, setPickerNotice] = useState(null);
    const completedStepsRef = useRef(null);
    const orgChromeRef = useRef(null);
    const projectChromeRef = useRef(null);
    const envChromeRef = useRef(null);
    const pendingOrgs = session.pendingOrgs;
    const completedStepsRows = useMeasuredRows(completedStepsRef);
    const orgChromeRows = useMeasuredRows(orgChromeRef);
    const projectChromeRows = useMeasuredRows(projectChromeRef);
    const envChromeRows = useMeasuredRows(envChromeRef);
    // Validate pre-populated org/project IDs against live data.
    // If the user's access changed (removed from org, switched accounts),
    // stale IDs from ./ampli.json could silently select the wrong project.
    useEffect(() => {
        if (!pendingOrgs || pendingOrgs.length === 0)
            return;
        if (session.selectedOrgId &&
            !pendingOrgs.some((o) => o.id === session.selectedOrgId)) {
            // Stale org — clear pre-populated values so the picker shows.
            // persist: false — this effect runs automatically when pendingOrgs
            // arrive; the user's subsequent picker selection writes ampli.json
            // with fresh values.
            store.setOrgAndProject({ id: '', name: '' }, { id: '', name: '' }, session.installDir, { persist: false });
        }
    }, [pendingOrgs]);
    // Resolve org: user-picked > single-org auto-select > pre-populated from session
    const prePopulatedOrg = session.selectedOrgId && pendingOrgs
        ? pendingOrgs.find((o) => o.id === session.selectedOrgId) ?? null
        : null;
    const effectiveOrg = selectedOrg ??
        (pendingOrgs?.length === 1 ? pendingOrgs[0] : null) ??
        prePopulatedOrg;
    // Resolve project: user-picked > single-project auto-select > pre-populated from session
    const singleProject = effectiveOrg?.projects.length === 1 ? effectiveOrg.projects[0] : null;
    const prePopulatedProject = session.selectedProjectId && effectiveOrg
        ? effectiveOrg.projects.find((project) => project.id === session.selectedProjectId) ?? null
        : null;
    const effectiveProject = selectedProject ?? singleProject ?? prePopulatedProject ?? null;
    useEffect(() => {
        if (effectiveOrg &&
            effectiveProject &&
            (!session.selectedProjectId ||
                !session.selectedOrgName ||
                !session.selectedProjectName)) {
            // Persist ampli.json only when this effect is committing genuinely
            // new IDs (e.g. first-time single-org / single-project auto-select).
            // When the IDs already match what's in the session, this effect is
            // simply backfilling names that ampli.json doesn't store — the disk
            // already has the correct values, so we skip the redundant write.
            // That removes the render-time disk I/O the snapshot tests had to
            // work around without changing the auth flow's observable outcome.
            const idsAlreadyMatch = session.selectedOrgId === effectiveOrg.id &&
                session.selectedProjectId === effectiveProject.id;
            store.setOrgAndProject(effectiveOrg, effectiveProject, session.installDir, { persist: !idsAlreadyMatch });
        }
    }, [
        effectiveOrg?.id,
        effectiveProject?.id,
        session.selectedOrgId,
        session.selectedProjectId,
        session.selectedOrgName,
        session.selectedProjectName,
    ]);
    // projectChosen requires the local project object (effectiveProject)
    // rather than just session.selectedProjectId, because we need the
    // environments list to drive the environment picker. When selectedProjectId is
    // pre-populated from ampli.json but no project object exists yet,
    // selectableEnvs would be empty and the picker would be bypassed.
    const projectChosen = effectiveProject !== null;
    // Environments available in the selected project
    const selectableEnvs = getSelectableEnvironments(effectiveProject);
    const hasMultipleEnvs = selectableEnvs.length > 1;
    // Auto-select the environment when there's only one with an API key
    useEffect(() => {
        if (projectChosen && !selectedEnv && selectableEnvs.length === 1) {
            setSelectedEnv(selectableEnvs[0]);
            store.setSelectedEnvName(selectableEnvs[0].name);
        }
    }, [projectChosen, selectedEnv, selectableEnvs.length]);
    // True once the user has picked an environment (or it was auto-selected),
    // or there are no environments to pick from (falls through to manual key entry).
    const envResolved = selectedEnv !== null || selectableEnvs.length === 0;
    const pickerBudget = (chromeRows) => {
        if (!contentArea)
            return undefined;
        return Math.max(5, contentArea.height - completedStepsRows - chromeRows);
    };
    // Resolve API key from local storage, selected environment, or backend fetch.
    useEffect(() => {
        if (!projectChosen || !envResolved || session.credentials !== null)
            return;
        let cancelled = false;
        void (async () => {
            const s = store.session;
            if (s.credentials !== null)
                return;
            const { readApiKeyWithSource, persistApiKey } = await import('../../../utils/api-key-store.js');
            if (cancelled)
                return;
            // 1. Check local storage first
            const local = readApiKeyWithSource(s.installDir);
            if (local) {
                setSavedKeySource(local.source);
                analytics.wizardCapture('api key submitted', {
                    'key source': local.source,
                });
                // Resolve env name + appId from the key when we can — the header
                // slot is informational, not required for Auth to complete.
                let matchedAppId = null;
                if (effectiveProject) {
                    const match = (effectiveProject.environments ?? []).find((e) => e.app?.apiKey === local.key);
                    if (match) {
                        if (!s.selectedEnvName)
                            store.setSelectedEnvName(match.name);
                        matchedAppId = match.app?.id ?? null;
                    }
                }
                store.setCredentials({
                    accessToken: s.pendingAuthAccessToken ?? '',
                    idToken: s.pendingAuthIdToken ?? undefined,
                    projectApiKey: local.key,
                    host: DEFAULT_HOST_URL,
                    appId: toCredentialAppId(matchedAppId),
                });
                store.setProjectHasData(false);
                store.setApiKeyNotice(null);
                return;
            }
            // 2. Use the API key from the selected environment
            if (selectedEnv?.app?.apiKey) {
                const apiKey = selectedEnv.app.apiKey;
                const envAppId = selectedEnv.app.id ?? null;
                // readDisk: true — auth screen runs before the RegionSelect gate.
                const zone = resolveZone(s, DEFAULT_AMPLITUDE_ZONE, { readDisk: true });
                const { getHostFromRegion } = await import('../../../utils/urls.js');
                if (cancelled || store.session.credentials !== null)
                    return;
                persistApiKey(apiKey, s.installDir);
                analytics.wizardCapture('api key submitted', {
                    'key source': 'environment_picker',
                });
                store.setCredentials({
                    accessToken: s.pendingAuthAccessToken ?? '',
                    idToken: s.pendingAuthIdToken ?? undefined,
                    projectApiKey: apiKey,
                    host: getHostFromRegion(zone),
                    appId: toCredentialAppId(envAppId),
                });
                store.setProjectHasData(false);
                store.setApiKeyNotice(null);
                return;
            }
            // 3. Fall back to backend fetch (no environments with keys available)
            const idToken = s.pendingAuthIdToken;
            if (!idToken)
                return;
            // readDisk: true — auth screen runs before the RegionSelect gate.
            const zone = resolveZone(s, DEFAULT_AMPLITUDE_ZONE, { readDisk: true });
            const { getAPIKey } = await import('../../../utils/get-api-key.js');
            const { getHostFromRegion } = await import('../../../utils/urls.js');
            const projectApiKey = await getAPIKey({
                installDir: s.installDir,
                idToken,
                zone,
                projectId: s.selectedProjectId ?? undefined,
            });
            if (cancelled || store.session.credentials !== null)
                return;
            if (projectApiKey) {
                persistApiKey(projectApiKey, s.installDir);
                analytics.wizardCapture('api key submitted', {
                    'key source': 'backend_fetch',
                });
                // Resolve env name + appId from the returned key when possible.
                // Not required for Auth to complete.
                let fetchedAppId = null;
                if (effectiveProject) {
                    const match = (effectiveProject.environments ?? []).find((e) => e.app?.apiKey === projectApiKey);
                    if (match) {
                        if (!store.session.selectedEnvName) {
                            store.setSelectedEnvName(match.name);
                        }
                        fetchedAppId = match.app?.id ?? null;
                    }
                }
                store.setCredentials({
                    accessToken: s.pendingAuthAccessToken ?? '',
                    idToken: s.pendingAuthIdToken ?? undefined,
                    projectApiKey,
                    host: getHostFromRegion(zone),
                    appId: toCredentialAppId(fetchedAppId),
                });
                store.setProjectHasData(false);
                store.setApiKeyNotice(null);
            }
            else {
                store.setApiKeyNotice("Your API key couldn't be fetched automatically. " +
                    'Only organization admins can access project API keys — ' +
                    'if you need one, ask an admin to share it with you.');
            }
        })();
        return () => {
            cancelled = true;
        };
    }, [
        projectChosen,
        envResolved,
        selectedEnv,
        session.credentials,
        session.selectedProjectId,
        session.pendingAuthIdToken,
        session.region,
        session.installDir,
    ]);
    const needsOrgPick = pendingOrgs !== null && pendingOrgs.length > 1 && effectiveOrg === null;
    const needsProjectPick = effectiveOrg !== null &&
        effectiveOrg.projects.length > 1 &&
        !selectedProject;
    const needsEnvPick = projectChosen && hasMultipleEnvs && !selectedEnv && !needsProjectPick;
    const needsApiKey = effectiveOrg !== null &&
        projectChosen &&
        envResolved &&
        session.credentials === null &&
        // Only show manual input if there's no selected env with a key
        // (either no envs available, or the env had no key)
        !selectedEnv?.app?.apiKey;
    const handleCreateProject = (fromScreen) => {
        // Pre-resolve the org: during the project picker, session.selectedOrgId
        // may still be null even though effectiveOrg is known. Commit it now so
        // CreateProjectScreen has the orgId it needs to POST /projects.
        if (effectiveOrg && !session.selectedOrgId) {
            store.setOrgAndProject(effectiveOrg, effectiveProject ?? { id: '', name: '' }, session.installDir);
        }
        analytics.wizardCapture('create project link opened', {
            'from screen': fromScreen,
        });
        setPickerNotice(null);
        store.startCreateProject(fromScreen);
    };
    const handleStartOver = (fromScreen) => {
        analytics.wizardCapture('picker start over', { 'from screen': fromScreen });
        setSelectedOrg(null);
        setSelectedProject(null);
        setSelectedEnv(null);
        setPickerNotice(null);
        store.setOrgAndProject({ id: '', name: '' }, { id: '', name: '' }, session.installDir);
        // Clear stale env name — setOrgAndProject doesn't touch it.
        store.setSelectedEnvName(null);
        // Re-fetch the org list so newly-created projects show up in the picker.
        // Best-effort: silently ignore failures and fall back to the cached list.
        const idToken = session.pendingAuthIdToken;
        // readDisk: true — auth screen runs before the RegionSelect gate.
        const zone = resolveZone(session, DEFAULT_AMPLITUDE_ZONE, {
            readDisk: true,
        });
        if (idToken) {
            void import('../../../lib/api.js').then(({ fetchAmplitudeUser }) => fetchAmplitudeUser(idToken, zone)
                .then((info) => store.setPendingOrgs(info.orgs))
                .catch(() => {
                // Keep the cached list — Start Over still resets local selection.
            }));
        }
    };
    const handleApiKeySubmit = (value) => {
        const trimmed = value.trim();
        if (!trimmed) {
            setApiKeyError('API key cannot be empty');
            return;
        }
        setApiKeyError('');
        analytics.wizardCapture('api key submitted', {
            'key source': 'manual_entry',
        });
        store.setApiKeyNotice(null);
        // Env name stays null for manually-entered keys — we can't determine
        // which environment the key belongs to without an extra backend call.
        // The header will render org / project only, which is acceptable.
        store.setCredentials({
            accessToken: session.pendingAuthAccessToken ?? '',
            idToken: session.pendingAuthIdToken ?? undefined,
            projectApiKey: trimmed,
            host: DEFAULT_HOST_URL,
            appId: 0,
        });
        // Fresh project: no existing event data — advance past DataSetup
        store.setProjectHasData(false);
        // Persist so the user doesn't have to enter it again
        void import('../../../utils/api-key-store.js').then(({ persistApiKey }) => {
            const source = persistApiKey(trimmed, session.installDir);
            setSavedKeySource(source);
        });
    };
    // ─── OAuth wait-state coaching ────────────────────────────────────────
    // While step 1 is rendering (pendingOrgs === null), the user is waiting
    // for the browser callback. On SSH / codespace / locked-down envs the
    // browser may never open — and even on local machines a stale stored
    // token can leave the wizard probing the API for several seconds before
    // it falls through to opening the browser. Without coaching the user
    // sees a blank spinner with no actions and assumes the wizard is broken.
    //
    // Two-tier strategy:
    //   - Always-on: [M] manual API key + [Esc] cancel are surfaced from t=0
    //     so the user is never stuck on a screen with no exit. Cheap UI cost,
    //     huge resilience win.
    //   - Tier-1 (15s): emphatic "Still waiting…" coaching with [R] retry
    //     surfaces if we still don't have a login URL or org list. The old
    //     60s threshold was longer than the user reported putting up with
    //     before quitting and re-running.
    const oauthWaiting = pendingOrgs === null && !manualFallbackOpen;
    // After email capture + ToS, "authentication" sounds like we're still
    // waiting on the user; the real wait is browser OAuth completing.
    const oauthWaitHeadline = isCreateAccountOnboarding(session)
        ? 'Complete sign-in in your browser'
        : 'Signing you in';
    const oauthWaitPreparingLine = isCreateAccountOnboarding(session)
        ? 'Opening your Amplitude sign-in page'
        : 'Preparing your sign-in link';
    const { tier: oauthCoachingTier } = useTimedCoaching({
        thresholds: [15],
        progressSignal: oauthWaiting ? 'waiting' : 'resolved',
    });
    const showOauthFallbackHints = oauthWaiting && oauthCoachingTier >= 1;
    // [R] retry browser launch while waiting for OAuth callback. Re-invokes
    // opn() against the cached login URL — useful when the user accidentally
    // closed the browser tab or the first launch silently failed. The wait
    // timer is implicitly reset because the action triggers a re-render
    // cycle and the user sees activity.
    const retryBrowser = async () => {
        const url = session.loginUrl;
        if (!url)
            return;
        analytics.wizardCapture('auth retry browser launch');
        try {
            const opn = (await import('opn')).default;
            void opn(url, { wait: false }).catch(() => {
                // No browser — user already sees the URL on screen for paste.
            });
        }
        catch {
            // import failed — nothing to do; the URL is still on screen.
        }
    };
    useScreenInput((input, key) => {
        if (!oauthWaiting)
            return;
        const ch = input.toLowerCase();
        // [R] only does something once we have a URL to relaunch — gate it
        // on that, not on the coaching tier, so the same key works whether
        // the user notices the URL at t=2s or at t=20s.
        if (ch === 'r' && session.loginUrl) {
            void retryBrowser();
            return;
        }
        if (ch === 'm') {
            analytics.wizardCapture('auth manual fallback opened');
            setManualFallbackOpen(true);
            return;
        }
        if (key.escape) {
            // Cancel auth — gracefully exit. The OAuth callback server is
            // owned by the outer oauth.ts; unwinding requires SIGINT-style
            // exit. process.exit(0) matches the convention used elsewhere
            // (OutageScreen onCancel) and produces a clean shutdown.
            analytics.wizardCapture('auth cancelled by user');
            process.exit(0);
        }
    }, { isActive: oauthWaiting });
    // ─── Account confirmation (returning user) ────────────────────────────
    // When the wizard resolves credentials silently from disk on a returning
    // run, the user gets a one-shot confirm step before we route them to a
    // project they didn't explicitly choose. Renders as the only Auth-screen
    // content while active — every other step is suppressed below.
    const accountConfirm = session.requiresAccountConfirmation;
    useScreenInput((input, key) => {
        if (!accountConfirm)
            return;
        const ch = input.toLowerCase();
        if (key.return || ch === 'y') {
            store.confirmAccount();
            return;
        }
        if (ch === 'c' || ch === 'n') {
            store.rejectStoredAccount();
            return;
        }
        if (key.escape) {
            analytics.wizardCapture('auth cancelled by user', {
                'from screen': 'account-confirm',
            });
            // Route through wizardSuccessExit so the analytics SDK gets a
            // chance to flush before the process tears down — a bare
            // process.exit(0) silently dropped the 'auth cancelled by user'
            // event (the SDK queues on a timer and the queue dies with the
            // process).
            void wizardSuccessExit(ExitCode.USER_CANCELLED);
        }
    }, { isActive: accountConfirm });
    // Completed-step indicators shown above the active step
    const completedSteps = [];
    if (session.detectedFrameworkLabel) {
        completedSteps.push({
            label: `Framework: ${session.detectedFrameworkLabel}`,
        });
    }
    if (effectiveOrg && !needsOrgPick) {
        completedSteps.push({ label: `Organization: ${effectiveOrg.name}` });
    }
    if (effectiveProject && !needsProjectPick) {
        completedSteps.push({ label: `Project: ${effectiveProject.name}` });
    }
    if (selectedEnv && !needsEnvPick) {
        completedSteps.push({ label: `Environment: ${selectedEnv.name}` });
    }
    // While the confirm step is active, render ONLY that — all other steps
    // are suppressed below by short-circuiting on `accountConfirm`.
    if (accountConfirm) {
        const orgLabel = session.selectedOrgName ?? session.selectedOrgId ?? '—';
        const projectLabel = session.selectedProjectName ?? session.selectedProjectId ?? '—';
        const envLabel = session.selectedEnvName ?? null;
        return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, gap: 1, children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Continue with this Amplitude project?" }), _jsx(Text, { color: Colors.muted, children: "We picked up your previous selection from this machine. Confirm it's still right before we run the wizard against it." })] }), _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: Colors.muted, children: "Organization: " }), _jsx(Text, { color: Colors.body, children: orgLabel })] }), _jsxs(Text, { children: [_jsx(Text, { color: Colors.muted, children: "Project: " }), _jsx(Text, { color: Colors.body, children: projectLabel })] }), envLabel && (_jsxs(Text, { children: [_jsx(Text, { color: Colors.muted, children: "Environment: " }), _jsx(Text, { color: Colors.body, children: envLabel })] })), session.userEmail && (_jsxs(Text, { children: [_jsx(Text, { color: Colors.muted, children: "Signed in as: " }), _jsx(Text, { color: Colors.body, children: session.userEmail })] }))] }), _jsxs(Box, { gap: 2, children: [_jsxs(Box, { children: [_jsx(Text, { color: Colors.muted, children: "[" }), _jsx(Text, { bold: true, color: Colors.body, children: "Enter" }), _jsx(Text, { color: Colors.muted, children: "] Continue" })] }), _jsxs(Box, { children: [_jsx(Text, { color: Colors.muted, children: "[" }), _jsx(Text, { bold: true, color: Colors.body, children: "C" }), _jsx(Text, { color: Colors.muted, children: "] Change project" })] }), _jsxs(Box, { children: [_jsx(Text, { color: Colors.muted, children: "[" }), _jsx(Text, { bold: true, color: Colors.body, children: "Esc" }), _jsx(Text, { color: Colors.muted, children: "] Cancel" })] })] })] }));
    }
    return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [completedSteps.length > 0 && (_jsxs(Box, { ref: completedStepsRef, flexDirection: "column", children: [completedSteps.map((step, i) => (_jsxs(Text, { children: [_jsxs(Text, { color: Colors.success, children: [Icons.checkmark, " "] }), _jsx(Text, { color: Colors.body, children: step.label })] }, i))), _jsx(Box, { height: 1 })] })), pendingOrgs === null && !manualFallbackOpen && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(BrailleSpinner, { color: Colors.accent }), _jsxs(Text, { color: Colors.body, children: [oauthWaitHeadline, Icons.ellipsis] })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: session.loginUrl ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: Colors.muted, children: "If the browser didn't open, copy and paste this URL:" }), _jsx(TerminalLink, { url: session.loginUrl, children: session.loginUrl })] })) : (_jsxs(Text, { color: Colors.muted, children: [oauthWaitPreparingLine, Icons.ellipsis, " (this normally takes a few seconds)"] })) }), _jsxs(Box, { marginTop: 1, gap: 2, children: [session.loginUrl && (_jsxs(Box, { children: [_jsx(Text, { color: Colors.muted, children: "[" }), _jsx(Text, { bold: true, color: Colors.body, children: "R" }), _jsx(Text, { color: Colors.muted, children: "] Retry browser" })] })), _jsxs(Box, { children: [_jsx(Text, { color: Colors.muted, children: "[" }), _jsx(Text, { bold: true, color: Colors.body, children: "M" }), _jsx(Text, { color: Colors.muted, children: "] Enter API key manually" })] }), _jsxs(Box, { children: [_jsx(Text, { color: Colors.muted, children: "[" }), _jsx(Text, { bold: true, color: Colors.body, children: "Esc" }), _jsx(Text, { color: Colors.muted, children: "] Cancel" })] })] }), showOauthFallbackHints && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: Colors.warning, children: ["Still waiting", Icons.ellipsis, " If your browser didn't open or you'd rather not wait, use one of the actions above."] }) }))] })), pendingOrgs === null && manualFallbackOpen && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Enter your project API key" }), _jsxs(Text, { color: Colors.muted, children: ["Amplitude ", Icons.arrowRight, " Settings ", Icons.arrowRight, " Projects", ' ', Icons.arrowRight, " [your project] ", Icons.arrowRight, " API Keys"] }), session.loginUrl && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: Colors.muted, children: "Or finish browser sign-in at:" }), _jsx(TerminalLink, { url: session.loginUrl, children: session.loginUrl })] }))] }), _jsx(TextInput, { placeholder: "Paste API key here...", onSubmit: handleApiKeySubmit }), apiKeyError && _jsx(Text, { color: Colors.error, children: apiKeyError })] })), needsOrgPick && pendingOrgs && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { ref: orgChromeRef, flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Select your organization" }), _jsx(Box, { marginTop: 1 })] }), _jsx(Box, { children: _jsx(PickerMenu, { availableRows: pickerBudget(orgChromeRows), options: pendingOrgs.map((org) => ({
                                label: org.name,
                                value: org,
                            })), onSelect: (value) => {
                                const org = Array.isArray(value) ? value[0] : value;
                                setSelectedOrg(org);
                            } }) })] })), needsProjectPick && effectiveOrg && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { ref: projectChromeRef, flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Select a project" }), _jsxs(Text, { color: Colors.secondary, children: ["in ", _jsx(Text, { color: Colors.body, children: effectiveOrg.name })] }), pickerNotice && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.warning, children: pickerNotice }) })), _jsx(Box, { marginTop: 1 })] }), _jsx(Box, { children: _jsx(PickerMenu, { availableRows: pickerBudget(projectChromeRows), options: [
                                ...effectiveOrg.projects.map((project) => ({
                                    label: project.name,
                                    value: project,
                                })),
                                {
                                    label: 'Create new project\u2026',
                                    value: CREATE_ACTION,
                                },
                                ...(pendingOrgs && pendingOrgs.length > 1
                                    ? [
                                        {
                                            label: 'Start over',
                                            value: RESTART_ACTION,
                                        },
                                    ]
                                    : []),
                            ], onSelect: (value) => {
                                const picked = Array.isArray(value) ? value[0] : value;
                                if (picked === CREATE_ACTION) {
                                    handleCreateProject('project');
                                    return;
                                }
                                if (picked === RESTART_ACTION) {
                                    handleStartOver('project');
                                    return;
                                }
                                if (isPickerAction(picked))
                                    return;
                                setPickerNotice(null);
                                setSelectedProject(picked);
                                store.setOrgAndProject(effectiveOrg, picked, session.installDir);
                            } }) })] })), needsEnvPick && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { ref: envChromeRef, flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Select an environment" }), pickerNotice && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.warning, children: pickerNotice }) })), _jsx(Box, { marginTop: 1 })] }), _jsx(Box, { children: _jsx(PickerMenu, { availableRows: pickerBudget(envChromeRows), options: [
                                ...selectableEnvs.map((env) => ({
                                    label: env.name,
                                    value: env,
                                })),
                                {
                                    label: 'Create new project\u2026',
                                    value: CREATE_ACTION,
                                },
                                {
                                    label: 'Start over',
                                    value: RESTART_ACTION,
                                },
                            ], onSelect: (value) => {
                                const picked = Array.isArray(value) ? value[0] : value;
                                if (picked === CREATE_ACTION) {
                                    handleCreateProject('environment');
                                    return;
                                }
                                if (picked === RESTART_ACTION) {
                                    handleStartOver('environment');
                                    return;
                                }
                                if (isPickerAction(picked))
                                    return;
                                setPickerNotice(null);
                                setSelectedEnv(picked);
                                store.setSelectedEnvName(picked.name);
                            } }) })] })), needsApiKey && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Enter your project API key" }), _jsxs(Text, { color: Colors.muted, children: ["Amplitude ", Icons.arrowRight, " Settings ", Icons.arrowRight, " Projects", ' ', Icons.arrowRight, " [your project] ", Icons.arrowRight, " API Keys"] }), session.apiKeyNotice && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.warning, children: session.apiKeyNotice }) }))] }), _jsx(TextInput, { placeholder: "Paste API key here...", onSubmit: handleApiKeySubmit }), apiKeyError && _jsx(Text, { color: Colors.error, children: apiKeyError }), savedKeySource && (_jsxs(Text, { color: Colors.success, children: [Icons.checkmark, ' ', savedKeySource === 'cache'
                                ? 'API key saved'
                                : 'API key saved to .env.local'] }))] }))] }));
};
