import React, { useEffect, useState } from "react";
import { useDispatch } from "../FinsembleProvider";
import { FinsembleToggleButtonBar } from "../common/FinsembleToggleButtonBar";
import { Button } from "../common/Button";
import { Dropdown } from "../common/Dropdown";
import { FEAGlobals } from "../../../common/Globals";
import { Checkbox } from "../common/Checkbox";
import { actions } from "../../../platform/services/window/modules/actions";
import "./ResolverDialog.css";
/**
 * The showScrim/hideScrim logic is unconventional because of the UX needs. In order to display a scrim on top of AOT windows
 * it is necessary to temporarily bring the scrim to the front of the z-index order. When that occurs, this resolver window
 * loses its focus, trigging onmouseout events. This means that we cannot hide a window with a simple onmouseout event. Instead,
 * we use an onmouseout event on the _surrounding_ DIV to trigger the hideScrim (i.e. if the user moves their mouse outside
 * of a valid selection then a hideScrim event will trigger).
 *
 * The window service's redux store contains the back end for scrim management.
 */
export const ResolverDialog = ({ intentRaiser, onSend, onCancel, resolutionList = [], showRememberCheckbox, }) => {
    var _a, _b;
    const dispatch = useDispatch();
    const [intentNumber, setIntentNumber] = useState(0);
    const [openNewApp, setOpenNewApp] = useState(false);
    const [rememberChoice, setRememberChoice] = useState(false);
    const receivingApps = ((_a = resolutionList[intentNumber]) === null || _a === void 0 ? void 0 : _a.launchableApps) || [];
    const openApps = (((_b = resolutionList[intentNumber]) === null || _b === void 0 ? void 0 : _b.openApps) || []).map((app, key) => {
        return {
            ...app,
            index: key,
        };
    });
    /**
     * Calculates what text to display in the UX. AppD prefers `title` when available. However, in the future we may
     * expand this to use data that is proprietary to Finsemble, such as the window's current title.
     */
    const displayName = (app) => {
        var _a, _b;
        let name = (_b = (_a = app.meta.title) !== null && _a !== void 0 ? _a : app.meta.name) !== null && _b !== void 0 ? _b : app.meta.appId;
        if (app.meta.desktopAgent) {
            name = `${name} (DesktopAgent ${app.meta.desktopAgent})`;
        }
        return name;
    };
    const reset = () => {
        setIntentNumber(0);
        setOpenNewApp(false);
    };
    const cancel = () => {
        onCancel();
        reset();
    };
    const showScrim = (e, windowName) => {
        e === null || e === void 0 ? void 0 : e.stopPropagation();
        e === null || e === void 0 ? void 0 : e.preventDefault();
        if (!windowName)
            return;
        // @ts-ignore
        dispatch(actions.showScrim(windowName));
    };
    const hideScrim = () => {
        // @ts-ignore
        dispatch(actions.hideScrim());
    };
    const pickExistingApp = (item) => {
        var _a, _b;
        hideScrim();
        onSend({
            intent: (_b = (_a = resolutionList[intentNumber]) === null || _a === void 0 ? void 0 : _a.intent) === null || _b === void 0 ? void 0 : _b.name,
            selectedApp: {
                name: item.meta.name,
                appId: item.appId,
                instanceId: item.uuid,
                desktopAgent: item.meta.desktopAgent,
            },
            windowName: item.windowName,
            rememberChoice,
        });
        reset();
    };
    const pickNewApp = (item) => {
        var _a, _b;
        onSend({
            intent: (_b = (_a = resolutionList[intentNumber]) === null || _a === void 0 ? void 0 : _a.intent) === null || _b === void 0 ? void 0 : _b.name,
            selectedApp: {
                appId: item.appId,
                desktopAgent: item.meta.desktopAgent,
            },
            rememberChoice,
        });
        reset();
    };
    useEffect(() => {
        var _a, _b;
        setOpenNewApp(((_b = (_a = resolutionList === null || resolutionList === void 0 ? void 0 : resolutionList[intentNumber]) === null || _a === void 0 ? void 0 : _a.openApps) === null || _b === void 0 ? void 0 : _b.length) === 0);
        setRememberChoice(false);
    }, [intentNumber, resolutionList]);
    // test harness, allows Live Mocha to remotely trigger onSend().
    useEffect(() => {
        var _a, _b, _c, _d, _e, _f;
        (_c = (_b = (_a = FEAGlobals.FSBL) === null || _a === void 0 ? void 0 : _a.TestHooks) === null || _b === void 0 ? void 0 : _b.TestPoint) === null || _c === void 0 ? void 0 : _c.onAction("fdc3.UIresolver.selectNewApp", (params) => {
            onSend({
                intent: params.intentName,
                selectedApp: {
                    appId: params.appId,
                },
            });
        });
        (_f = (_e = (_d = FEAGlobals.FSBL) === null || _d === void 0 ? void 0 : _d.TestHooks) === null || _e === void 0 ? void 0 : _e.TestPoint) === null || _f === void 0 ? void 0 : _f.onAction("fdc3.UIresolver.selectByWindow", (params) => {
            onSend({
                intent: params.intentName,
                windowName: params.windowName,
            });
        });
    }, [onSend]);
    const resolutionOptions = resolutionList.map((item, index) => {
        var _a;
        return {
            value: String(index),
            label: (_a = item.intent.displayName) !== null && _a !== void 0 ? _a : item.intent.name,
        };
    });
    return (React.createElement("div", { className: "resolverDialog", onMouseOver: hideScrim },
        React.createElement("h1", null, "FDC3 Intent Resolver"),
        React.createElement("p", null,
            "The app ",
            intentRaiser,
            " requested an action. There are several apps on your smart desktop that can perform this action, and you need to choose one."),
        resolutionList.length === 1 && (React.createElement("div", { className: "heading" },
            "App action: ",
            resolutionList[intentNumber].intent.name)),
        resolutionList.length > 1 && (React.createElement("div", { className: "action-picker" },
            React.createElement("label", { htmlFor: "action-dropdown", className: "heading" }, "Pick an action"),
            React.createElement(Dropdown, { selected: String(intentNumber), options: resolutionOptions, onChange: (newValue) => setIntentNumber(+newValue) }))),
        React.createElement("div", { className: "heading" }, "Which app do you want to perform the action?"),
        React.createElement(FinsembleToggleButtonBar, { selected: openNewApp, options: [
                {
                    label: "Pick an open app",
                    value: false,
                    disabled: openApps.length === 0,
                },
                {
                    label: "Launch a new app",
                    value: true,
                },
            ], onChange: (newValue) => {
                setOpenNewApp(newValue);
            } }),
        showRememberCheckbox && resolutionList.length === 1 && (React.createElement(Checkbox, { label: "Remember choice", checked: rememberChoice, onClick: () => setRememberChoice(!rememberChoice) })),
        !openNewApp && (React.createElement("div", { className: "app-list open-apps" },
            React.createElement("ol", null, openApps.map((item, index) => (React.createElement("li", { key: index, tabIndex: 0, onMouseOver: (e) => showScrim(e, item.windowName), onFocus: () => showScrim(null, item.windowName), onBlur: () => hideScrim(), onKeyDown: (e) => {
                    if (e.key === "Enter") {
                        pickExistingApp(item);
                    }
                }, onClick: () => {
                    pickExistingApp(item);
                } }, displayName(item))))))),
        openNewApp && (React.createElement("div", { className: "app-list new-apps" },
            React.createElement("ol", null, receivingApps.map((item, index) => (React.createElement("li", { key: index, tabIndex: 0, onKeyDown: (e) => {
                    if (e.key === "Enter") {
                        pickNewApp(item);
                    }
                }, onClick: () => {
                    pickNewApp(item);
                } }, displayName(item))))))),
        React.createElement("div", { className: "action-row" },
            React.createElement(Button, { className: "cancel-button", fashion: "hollow", text: "Cancel", onClick: cancel }))));
};
//# sourceMappingURL=ResolverDialog.js.map