import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { createContext, useContext, useEffect, useMemo, useState, useRef, } from 'react';
import { observer, useLocalObservable } from 'mobx-react-lite';
import { clsx, AssistantIcon, compareLabelFn, GitBranchIcon, CustomSelectorInput, LongArrowRightIcon, DividerWithText, SearchIcon, BaseCard, OpenIcon, Dialog, MarkdownTextViewer, Modal, } from '@finos/legend-art';
import { LEGEND_STUDIO_TEST_ID } from '../../__lib__/LegendStudioTesting.js';
import { generateEditorRoute, LEGEND_STUDIO_ROUTE_PATTERN_TOKEN, } from '../../__lib__/LegendStudioNavigation.js';
import { flowResult } from 'mobx';
import { useApplicationNavigationContext } from '@finos/legend-application';
import { useParams } from '@finos/legend-application/browser';
import { LEGEND_STUDIO_DOCUMENTATION_KEY } from '../../__lib__/LegendStudioDocumentation.js';
import { CreateProjectModal } from './CreateProjectModal.js';
import { ActivityBarMenu, ColorThemeToggle } from '../editor/ActivityBar.js';
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../__lib__/LegendStudioApplicationNavigationContext.js';
import { CreateWorkspaceModal } from './CreateWorkspaceModal.js';
import { RecentWorkspacesPanel } from './RecentWorkspacesPanel.js';
import { useLegendStudioApplicationStore, useLegendStudioBaseStore, } from '../LegendStudioFrameworkProvider.js';
import { buildProjectOption, getProjectOptionLabelFormatter, } from './ProjectSelectorUtils.js';
import { buildWorkspaceOption, formatWorkspaceOptionLabel, } from './WorkspaceSelectorUtils.js';
import { debounce, guaranteeNonNullable, } from '@finos/legend-shared';
import { Project } from '@finos/legend-server-sdlc';
import { WorkspaceSetupStore } from '../../stores/workspace-setup/WorkspaceSetupStore.js';
import { openShowcaseManager } from '../../stores/ShowcaseManagerState.js';
const WorkspaceSetupStoreContext = createContext(undefined);
export const DEFAULT_WORKSPACE_SOURCE = 'HEAD';
export const ShowcaseCard = (props) => {
    const applicationStore = useLegendStudioApplicationStore();
    const appDocUrl = applicationStore.documentationService.url;
    return (_jsx(BaseCard, { className: "workspace-setup__content__card", cardMedia: undefined, cardName: "Showcase Projects", cardContent: _jsxs("div", { className: "workspace-setup__content__card__content", children: ["Review showcase projects with sample project code and re-use existing code snippets to quickly build your model.", ' ', !props.hideDocumentation && (_jsxs(_Fragment, { children: ["Review Studio", ' ', _jsx("a", { href: appDocUrl, target: "_blank", rel: "noreferrer", className: "workspace-setup__content__link", children: "documentation" }), "."] }))] }), cardActions: [
            {
                title: 'Showcase explorer',
                content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })),
                action: () => openShowcaseManager(applicationStore),
            },
        ], isStable: true }));
};
export const DocumentationCard = () => {
    const applicationStore = useLegendStudioApplicationStore();
    const appDocUrl = applicationStore.documentationService.url;
    return (_jsx(BaseCard, { className: "workspace-setup__content__card", cardName: "Documentation", cardContent: _jsxs("div", { className: "workspace-setup__content__card__content", children: ["Review Studio", ' ', _jsx("a", { href: appDocUrl, target: "_blank", rel: "noreferrer", className: "workspace-setup__content__link", children: "documentation" }), "."] }), cardActions: [
            {
                title: 'Review documentation',
                content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })),
                action: () => {
                    if (appDocUrl) {
                        applicationStore.navigationService.navigator.visitAddress(appDocUrl);
                    }
                },
            },
        ], isStable: true }));
};
export const ProductionCard = () => {
    const applicationStore = useLegendStudioApplicationStore();
    const productionDocument = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.APPLICATION_PRODUCTION);
    return (productionDocument?.title &&
        productionDocument.markdownText &&
        productionDocument.text && (_jsx(BaseCard, { className: "workspace-setup__content__card", cardName: productionDocument.title, cardContent: productionDocument.markdownText.value, cardActions: [
            {
                title: productionDocument.text,
                content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })),
                action: () => {
                    if (productionDocument.url) {
                        applicationStore.navigationService.navigator.visitAddress(productionDocument.url);
                    }
                },
            },
        ], isStable: true })));
};
export const SandboxCard = () => {
    const applicationStore = useLegendStudioApplicationStore();
    const sandboxDocument = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.APPLICATION_SANDBOX);
    return (sandboxDocument?.title &&
        sandboxDocument.markdownText &&
        sandboxDocument.text && (_jsx(BaseCard, { className: "workspace-setup__content__card", cardName: sandboxDocument.title, cardContent: sandboxDocument.markdownText.value, cardActions: [
            {
                title: sandboxDocument.text,
                content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })),
                action: () => {
                    if (sandboxDocument.url) {
                        applicationStore.navigationService.navigator.visitAddress(sandboxDocument.url);
                    }
                },
            },
        ], isStable: true })));
};
export const RuleEngagementCard = () => {
    const applicationStore = useLegendStudioApplicationStore();
    const ruleEngagementDocument = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.APPLICATION_RULE_ENGAGEMENT);
    return (ruleEngagementDocument?.title &&
        ruleEngagementDocument.markdownText &&
        ruleEngagementDocument.text && (_jsx(BaseCard, { className: "workspace-setup__content__card", cardMedia: undefined, cardName: ruleEngagementDocument.title, cardContent: ruleEngagementDocument.markdownText.value, cardActions: [
            {
                title: ruleEngagementDocument.text,
                content: (_jsx("div", { className: "workspace-setup__content__card__action__icon", children: _jsx(OpenIcon, {}) })),
                action: () => {
                    if (ruleEngagementDocument.url) {
                        applicationStore.navigationService.navigator.visitAddress(ruleEngagementDocument.url);
                    }
                },
            },
        ], isStable: true })));
};
const WorkspaceSetupStoreProvider = ({ children }) => {
    const applicationStore = useLegendStudioApplicationStore();
    const baseStore = useLegendStudioBaseStore();
    const store = useLocalObservable(() => new WorkspaceSetupStore(applicationStore, baseStore.sdlcServerClient));
    return (_jsx(WorkspaceSetupStoreContext.Provider, { value: store, children: children }));
};
export const useWorkspaceSetupStore = () => guaranteeNonNullable(useContext(WorkspaceSetupStoreContext), `Can't find workspace setup store in context`);
const withWorkspaceSetupStore = (WrappedComponent) => function WithWorkspaceSetupStore() {
    return (_jsx(WorkspaceSetupStoreProvider, { children: _jsx(WrappedComponent, {}) }));
};
const SandboxAccessModal = observer(() => {
    const setupStore = useWorkspaceSetupStore();
    const closeModal = () => setupStore.setSandboxModal(false);
    const applicationStore = setupStore.applicationStore;
    const documentation = applicationStore.documentationService.getDocEntry(LEGEND_STUDIO_DOCUMENTATION_KEY.SETUP_CREATE_SANDBOX_UNAUTHORIZED);
    return (_jsx(Dialog, { open: true, onClose: closeModal, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, className: "sandbox-project-modal", children: [_jsx("div", { className: "sandbox-project-modal__header", children: _jsx("div", { className: "sandbox-project-modal__header__label", children: "Create Sandbox Project" }) }), _jsx("div", { className: "sandbox-project-modal__form panel__content__form", children: _jsx("div", { className: "panel__content__form__section sandbox-project-modal__form__unsupported", children: "You do not have access to create a Sandbox Project" }) }), _jsx("div", { className: "sandbox-project-modal__content", children: documentation?.markdownText && (_jsx("div", { className: "panel__content__form__section", children: _jsx(MarkdownTextViewer, { value: documentation.markdownText }) })) })] }) }));
});
export const WorkspaceSetup = withWorkspaceSetupStore(observer(() => {
    const params = useParams();
    const projectId = params[LEGEND_STUDIO_ROUTE_PATTERN_TOKEN.PROJECT_ID];
    const workspaceId = params[LEGEND_STUDIO_ROUTE_PATTERN_TOKEN.WORKSPACE_ID];
    const groupWorkspaceId = params[LEGEND_STUDIO_ROUTE_PATTERN_TOKEN.GROUP_WORKSPACE_ID];
    const setupStore = useWorkspaceSetupStore();
    const applicationStore = useLegendStudioApplicationStore();
    const [projectSearchText, setProjectSearchText] = useState('');
    const goButtonRef = useRef(null);
    //TODO: fix logo loading issue for localhost
    const logoPath = `${applicationStore.config.baseAddress}favicon.ico`;
    const toggleAssistant = () => applicationStore.assistantService.toggleAssistant();
    // projects
    // Build a unified option list: recent projects (that aren't already in the
    // loaded set) are prepended so users can instantly re-open common work
    // without waiting for the SDLC search to round-trip.
    const sandboxProject = setupStore.sandboxProject instanceof Project
        ? setupStore.sandboxProject
        : undefined;
    const sandboxProjectId = sandboxProject?.projectId;
    const loadedProjectOptions = setupStore.projects
        .filter((p) => p.projectId !== sandboxProjectId)
        .map(buildProjectOption)
        .sort(compareLabelFn);
    const loadedProjectIds = new Set(setupStore.projects.map((p) => p.projectId));
    const recentProjectOptions = setupStore.recentProjects
        .filter((r) => !loadedProjectIds.has(r.projectId) &&
        r.projectId !== sandboxProjectId)
        .map((r) => {
        // Rebuild a real Project from the cached metadata; no synthetic
        // fields needed since we persist everything the schema requires.
        const stub = Project.serialization.fromJson({
            projectId: r.projectId,
            name: r.name,
            description: r.description,
            webUrl: r.webUrl,
            tags: r.tags,
        });
        return { label: stub.name, value: stub };
    });
    const projectOptions = [
        // The user's own sandbox project is fetched via a dedicated call
        // (`loadSandboxProject`) and excluded from the main search results, so
        // we surface it here as a labeled option pinned to the top of the list.
        ...(sandboxProject
            ? [
                {
                    label: `${sandboxProject.name} (sandbox)`,
                    value: sandboxProject,
                },
            ]
            : []),
        ...recentProjectOptions,
        ...loadedProjectOptions,
    ];
    const recentProjectIdSet = new Set(setupStore.recentProjects.map((p) => p.projectId));
    const selectedProjectOption = setupStore.currentProject
        ? buildProjectOption(setupStore.currentProject)
        : null;
    const onProjectChange = (val) => {
        if (val) {
            // If the selection corresponds to a recent that hasn't been loaded
            // from search yet, fetch the project before switching.
            const isUnloadedRecent = !loadedProjectIds.has(val.value.projectId) &&
                recentProjectIdSet.has(val.value.projectId);
            if (isUnloadedRecent) {
                flowResult(setupStore.selectRecentProject(val.value.projectId)).catch(applicationStore.alertUnhandledError);
            }
            else {
                flowResult(setupStore.changeProject(val.value)).catch(applicationStore.alertUnhandledError);
            }
        }
        else {
            setupStore.resetProject();
        }
    };
    const showCreateProjectModal = () => setupStore.setShowCreateProjectModal(true);
    const createSandboxProject = () => {
        flowResult(setupStore.createSandboxProject()).catch(applicationStore.alertUnhandledError);
    };
    // project search text
    const debouncedLoadProjects = useMemo(() => debounce((input) => {
        flowResult(setupStore.loadProjects(input)).catch(applicationStore.alertUnhandledError);
    }, 500), [applicationStore, setupStore]);
    const onProjectSearchTextChange = (value) => {
        if (value !== projectSearchText) {
            setProjectSearchText(value);
            debouncedLoadProjects.cancel();
            debouncedLoadProjects(value);
        }
    };
    // workspaces
    // Recent (non-patch) workspaces for the currently selected project are
    // floated to the top of the dropdown so users can re-enter their
    // typical work without scanning the full list.
    const projectIdForRecents = setupStore.currentProject?.projectId;
    const recentWorkspaceKeys = new Set(projectIdForRecents
        ? setupStore.recentWorkspaces
            .filter((w) => w.projectId === projectIdForRecents)
            .map((w) => `${w.workspaceType}::${w.workspaceId}`)
        : []);
    const allWorkspaceOptions = setupStore.workspaces.map(buildWorkspaceOption);
    const recentWorkspaceOptions = allWorkspaceOptions
        .filter((o) => o.value.source === undefined &&
        recentWorkspaceKeys.has(`${o.value.workspaceType}::${o.value.workspaceId}`))
        .sort(compareLabelFn);
    const otherWorkspaceOptions = allWorkspaceOptions
        .filter((o) => o.value.source !== undefined ||
        !recentWorkspaceKeys.has(`${o.value.workspaceType}::${o.value.workspaceId}`))
        .sort(compareLabelFn);
    const workspaceOptions = [
        ...recentWorkspaceOptions,
        ...otherWorkspaceOptions,
    ];
    const selectedWorkspaceOption = setupStore.currentWorkspace
        ? buildWorkspaceOption(setupStore.currentWorkspace)
        : null;
    const onWorkspaceChange = (val) => {
        if (val) {
            setupStore.changeWorkspace(val.value);
            if (!setupStore.currentProjectConfigurationStatus?.isConfigured) {
                applicationStore.notificationService.notifyIllegalState(`Can't edit current workspace as the current project is not configured`);
            }
            goButtonRef.current?.focus();
        }
        else {
            setupStore.resetWorkspace();
        }
    };
    const showCreateWorkspaceModal = () => setupStore.setShowCreateWorkspaceModal(true);
    const handleProceed = () => {
        if (setupStore.currentProject && setupStore.currentWorkspace) {
            applicationStore.navigationService.navigator.goToLocation(generateEditorRoute(setupStore.currentProject.projectId, setupStore.currentWorkspace.source, setupStore.currentWorkspace.workspaceId, setupStore.currentWorkspace.workspaceType));
        }
    };
    useEffect(() => {
        flowResult(setupStore.initialize(projectId, workspaceId, groupWorkspaceId)).catch(applicationStore.alertUnhandledError);
    }, [
        setupStore,
        applicationStore,
        projectId,
        workspaceId,
        groupWorkspaceId,
    ]);
    useEffect(() => {
        flowResult(setupStore.loadProjects('')).catch(applicationStore.alertUnhandledError);
        flowResult(setupStore.loadSandboxProject()).catch(applicationStore.alertUnhandledError);
    }, [setupStore, applicationStore]);
    useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.SETUP);
    return (_jsx("div", { className: "app__page", children: _jsxs("div", { className: "workspace-setup", children: [_jsxs("div", { className: "workspace-setup__body", children: [_jsxs("div", { className: "activity-bar", children: [_jsx(ActivityBarMenu, {}), _jsx("div", { className: "activity-bar__items" }), _jsx(ColorThemeToggle, {})] }), _jsx("div", { className: "workspace-setup__content", "data-testid": LEGEND_STUDIO_TEST_ID.SETUP__CONTENT, children: _jsxs("div", { className: "workspace-setup__content__body", children: [_jsxs("div", { className: "workspace-setup__content__main", children: [_jsxs("div", { className: "workspace-setup__title", children: [_jsx("div", { className: "workspace-setup__logo", children: _jsx("img", { src: logoPath, className: "workspace-setup__logo__icon" }) }), _jsx("div", { className: "workspace-setup__title__header", children: "Welcome to Legend Studio" })] }), _jsx(RecentWorkspacesPanel, { setupStore: setupStore }), _jsx("div", { className: "workspace-setup__selectors", children: _jsxs("div", { className: "workspace-setup__selectors__container", children: [_jsxs("div", { className: "workspace-setup__selector", children: [_jsxs("div", { className: "workspace-setup__selector__header", children: [_jsx("span", { children: "Search for an existing project" }), (setupStore.recentProjects.length > 0 ||
                                                                            setupStore.recentWorkspaces.length > 0) && (_jsx("button", { type: "button", className: "workspace-setup__selector__header__clear-recents", tabIndex: -1, onClick: () => setupStore.clearRecents(), title: "Clear recently-opened projects and workspaces", children: "Clear recents" }))] }), _jsxs("div", { className: "workspace-setup__selector__content", children: [_jsx("div", { className: "workspace-setup__selector__content__icon", title: "project", children: _jsx(SearchIcon, { className: "workspace-setup__selector__content__icon--project" }) }), _jsx(CustomSelectorInput, { className: "workspace-setup__selector__content__input", options: projectOptions, isLoading: setupStore.loadProjectsState.isInProgress ||
                                                                                setupStore.loadSandboxState.isInProgress, onInputChange: onProjectSearchTextChange, inputValue: projectSearchText, onChange: onProjectChange, value: selectedProjectOption, placeholder: "Search for project...", isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService
                                                                                .TEMPORARY__isLightColorThemeEnabled, formatOptionLabel: getProjectOptionLabelFormatter(applicationStore, setupStore.currentProjectConfigurationStatus), optionCustomization: {
                                                                                rowHeight: window.innerHeight * 0.03,
                                                                            } })] })] }), _jsxs("div", { className: "workspace-setup__selector", children: [_jsx("div", { className: "workspace-setup__selector__header", children: "Choose an existing workspace" }), _jsxs("div", { className: "workspace-setup__selector__content", children: [_jsx("div", { className: "workspace-setup__selector__content__icon", title: "workspace", children: _jsx(GitBranchIcon, { className: "workspace-setup__selector__content__icon--workspace" }) }), _jsx(CustomSelectorInput, { className: "workspace-setup__selector__content__input", options: workspaceOptions, onKeyDown: (event) => {
                                                                                if (event.key === 'Enter') {
                                                                                    goButtonRef.current?.focus();
                                                                                    handleProceed();
                                                                                }
                                                                            }, disabled: !setupStore.currentProject ||
                                                                                !setupStore.currentProjectConfigurationStatus ||
                                                                                !setupStore.currentProjectConfigurationStatus
                                                                                    .isConfigured ||
                                                                                setupStore.loadProjectsState.isInProgress ||
                                                                                setupStore.loadWorkspacesState.isInProgress, isLoading: setupStore.loadWorkspacesState.isInProgress, onChange: onWorkspaceChange, formatOptionLabel: formatWorkspaceOptionLabel, value: selectedWorkspaceOption, placeholder: setupStore.loadWorkspacesState.isInProgress
                                                                                ? 'Loading workspaces...'
                                                                                : !setupStore.currentProject
                                                                                    ? 'In order to choose a workspace, a project must be chosen'
                                                                                    : workspaceOptions.length
                                                                                        ? 'Choose an existing workspace'
                                                                                        : 'You have no workspaces. Please create one to proceed...', isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService
                                                                                .TEMPORARY__isLightColorThemeEnabled, optionCustomization: {
                                                                                rowHeight: window.innerHeight * 0.03,
                                                                            } })] })] })] }) }), _jsx("div", { className: "workspace-setup__actions-combo", children: _jsxs("div", { className: "workspace-setup__actions", children: [_jsx("button", { className: "workspace-setup__new-workspace-btn", onClick: showCreateWorkspaceModal, title: "Create a Workspace after choosing one project", disabled: !setupStore.currentProject ||
                                                                !setupStore.currentProjectConfigurationStatus
                                                                    ?.isConfigured, children: `Need to create a new workspace?` }), _jsx("div", { className: "workspace-setup__actions__button", children: _jsxs("button", { className: "workspace-setup__go-btn btn--dark", onClick: handleProceed, ref: goButtonRef, disabled: !setupStore.currentProject ||
                                                                    !setupStore.currentProjectConfigurationStatus ||
                                                                    !setupStore.currentProjectConfigurationStatus
                                                                        .isConfigured ||
                                                                    !setupStore.currentWorkspace ||
                                                                    setupStore.createWorkspaceState.isInProgress ||
                                                                    setupStore.createOrImportProjectState.isInProgress, children: [_jsx("div", { className: "workspace-setup__go-btn__label", children: "Go" }), _jsx(LongArrowRightIcon, { className: "workspace-setup__go-btn__icon" })] }) }), _jsx(DividerWithText, { className: "workspace-setup__divider", children: "OR" }), setupStore.sandboxModal && _jsx(SandboxAccessModal, {}), _jsxs("div", { className: "workspace-setup__actions__button", children: [_jsx("button", { className: "workspace-setup__new-btn btn--dark", onClick: showCreateProjectModal, title: "Create a Project", children: "Create New Project" }), setupStore.sandboxProject === true &&
                                                                    setupStore.initState.hasCompleted &&
                                                                    setupStore.supportsCreatingSandboxProject && (_jsx("button", { className: "workspace-setup__new-btn btn--dark", onClick: createSandboxProject, title: "Create Sandbox Project", children: "Create Sandbox Project" }))] })] }) })] }), _jsxs("div", { className: "workspace-setup__content__cards", children: [_jsx(RuleEngagementCard, {}), _jsx(ShowcaseCard, {}), _jsx(SandboxCard, {}), _jsx(ProductionCard, {})] }), setupStore.showCreateProjectModal && _jsx(CreateProjectModal, {}), setupStore.showCreateWorkspaceModal &&
                                        setupStore.currentProject && (_jsx(CreateWorkspaceModal, { selectedProject: setupStore.currentProject }))] }) })] }), _jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.STATUS_BAR, className: "editor__status-bar", children: [_jsx("div", { className: "editor__status-bar__left" }), _jsx("div", { className: "editor__status-bar__right", children: _jsx("button", { className: clsx('editor__status-bar__action editor__status-bar__action__toggler', {
                                    'editor__status-bar__action__toggler--active': !applicationStore.assistantService.isHidden,
                                }), onClick: toggleAssistant, tabIndex: -1, title: "Toggle assistant", children: _jsx(AssistantIcon, {}) }) })] })] }) }));
}));
//# sourceMappingURL=WorkspaceSetup.js.map