"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TeamSharingModule = void 0;
const tslib_1 = require("tslib");
const AdaptableModuleBase_1 = require("./AdaptableModuleBase");
const ModuleConstants = tslib_1.__importStar(require("../Utilities/Constants/ModuleConstants"));
const TeamSharingRedux_1 = require("../Redux/ActionsReducers/TeamSharingRedux");
const TeamSharingRedux = tslib_1.__importStar(require("../Redux/ActionsReducers/TeamSharingRedux"));
const isEqual_1 = tslib_1.__importDefault(require("../Utilities/utils/isEqual"));
const LayoutRedux_1 = require("../Redux/ActionsReducers/LayoutRedux");
const SharedEntityObjectView_1 = require("../View/TeamSharing/SharedEntityObjectView");
const TeamSharingApplyButton_1 = require("../View/TeamSharing/TeamSharingApplyButton");
const SharedEntityDependencies_1 = require("../View/TeamSharing/SharedEntityDependencies");
const ArrayExtensions_1 = tslib_1.__importDefault(require("../Utilities/Extensions/ArrayExtensions"));
const flatten_1 = tslib_1.__importDefault(require("../Utilities/utils/flatten"));
const AdaptableHelper_1 = tslib_1.__importDefault(require("../Utilities/Helpers/AdaptableHelper"));
class TeamSharingModule extends AdaptableModuleBase_1.AdaptableModuleBase {
    SKIP_TEAMSHARING_UPDATE_ACTIONS = [
        TeamSharingRedux_1.TEAMSHARING_GET,
        TeamSharingRedux_1.TEAMSHARING_SET,
        TeamSharingRedux_1.TEAMSHARING_SHARE,
        TeamSharingRedux_1.TEAMSHARING_IMPORT_ITEM,
        TeamSharingRedux_1.TEAMSHARING_PROCESS_IMPORT,
        TeamSharingRedux_1.TEAMSHARING_REMOVE_ITEM,
        TeamSharingRedux_1.TEAMSHARING_LINK_ITEM,
        TeamSharingRedux_1.TEAMSHARING_UPDATE_ITEM,
    ];
    constructor(api) {
        super(ModuleConstants.TeamSharingModuleId, ModuleConstants.TeamSharingFriendlyName, 'folder-shared', 'TeamSharingPopup', 'Team Sharing allows users to share - at run-time - Adaptable Objects between colleagues.', api);
    }
    onAdaptableReady() {
        if (this.api.teamSharingApi.isTeamSharingAvailable()) {
            // make sure there is no zombie import process remaining (in case a previous import crashed)
            this.api.internalApi.dispatchReduxAction(TeamSharingRedux.TeamSharingCommitImport());
            this.api.teamSharingApi.refreshTeamSharing();
        }
        this.api.eventApi.on('AdaptableStateChanged', (adaptableStateChangedInfo) => this.handleStateChanged(adaptableStateChangedInfo));
    }
    isModuleEnabled() {
        const teamSharingOptions = this.api.optionsApi.getTeamSharingOptions();
        return (teamSharingOptions?.enableTeamSharing &&
            typeof teamSharingOptions?.loadSharedEntities === 'function' &&
            typeof teamSharingOptions?.persistSharedEntities === 'function');
    }
    isModuleObjectsShareable() {
        return false;
    }
    getPopupMaxWidth() {
        return 1000;
    }
    handleStateChanged(adaptableStateChangedInfo) {
        // check if TeamSharing is activated
        if (!this.api.teamSharingApi.isTeamSharingAvailable()) {
            return;
        }
        // skip all teamsharing actions, otherwise we could get in an infinite loop
        if (this.SKIP_TEAMSHARING_UPDATE_ACTIONS.includes(adaptableStateChangedInfo.action.type)) {
            return;
        }
        // check if there is any changed adaptable object
        const changedAdaptableObject = this.extractAdaptableObjectFromAction(adaptableStateChangedInfo.action);
        if (!changedAdaptableObject) {
            return;
        }
        // check if the changed adaptable object is active in TeamSharing
        const activeSharedEntity = this.api.internalApi.getState().TeamSharing.ActiveSharedEntityMap[changedAdaptableObject.Uuid];
        if (!activeSharedEntity) {
            return;
        }
        // handle special case of LAYOUT_SAVE which might be called redundantly without actually changing the state
        const isLayoutStateUnchanged = adaptableStateChangedInfo.action.type === LayoutRedux_1.LAYOUT_SAVE &&
            (0, isEqual_1.default)(adaptableStateChangedInfo.oldState.Layout, adaptableStateChangedInfo.newState.Layout);
        if (isLayoutStateUnchanged) {
            return;
        }
        this.api.internalApi.dispatchReduxAction((0, TeamSharingRedux_1.TeamSharingUpdateItem)(changedAdaptableObject, adaptableStateChangedInfo.userName));
    }
    extractAdaptableObjectFromAction(action) {
        // this implementation is based on the assumption that any action which mutates an AdaptableObject has
        // at most one(1) property which has an 'Uuid:TypeUuid' defined (and that is the AdaptableObject, of course)
        if (!action) {
            return;
        }
        return Object.values(action).find((actionPropertyValue) => AdaptableHelper_1.default.isAdaptableObject(actionPropertyValue));
    }
    isAdaptableObjectPresentInLocalState(sharedEntity) {
        return !!this.api.internalApi
            .getModuleService()
            .getModuleById(sharedEntity.Module)
            ?.getModuleAdaptableObjects()
            .find((adaptableObject) => adaptableObject.Uuid === sharedEntity.Entity.Uuid);
    }
    isSharedEntityADependency(sharedEntity) {
        const allSharedEntries = this.api.teamSharingApi.getLoadedAdaptableSharedEntities();
        return allSharedEntries.some((sharedEntryCandidate) => {
            return sharedEntryCandidate?.EntityDependencyIds?.includes(sharedEntity.Uuid);
        });
    }
    isStaleAndActive(sharedEntity) {
        const staleActiveEntities = this.api.internalApi
            .getTeamSharingService()
            .getStaleActiveSharedEntities();
        return (this.isAdaptableObjectPresentInLocalState(sharedEntity) &&
            !!staleActiveEntities[sharedEntity.Uuid]);
    }
    getDependencies(sharedEntity) {
        if (!Array.isArray(sharedEntity.EntityDependencyIds) ||
            sharedEntity.EntityDependencyIds.length === 0) {
            return [sharedEntity];
        }
        const allSharedEntities = this.api.teamSharingApi.getLoadedAdaptableSharedEntities();
        const dependencies = sharedEntity.EntityDependencyIds.map((dependencyUuid) => allSharedEntities.find((entity) => entity.Uuid === dependencyUuid));
        return (0, flatten_1.default)(dependencies.map((dependency) => this.getDependencies(dependency)));
    }
    getStaleDependencies(sharedEntity) {
        return this.getDependencies(sharedEntity).filter((dependency) => dependency.Uuid !== sharedEntity.Uuid && this.isStaleAndActive(dependency));
    }
    toView(sharedEntity) {
        const isDependency = this.isSharedEntityADependency(sharedEntity);
        const staleDependencies = this.getStaleDependencies(sharedEntity);
        const staleDependenciesViewItems = [];
        if (staleDependencies?.length) {
            staleDependenciesViewItems.push({
                name: 'Stale Deps',
                view: (0, SharedEntityObjectView_1.getSharedEntityStaleDepsItemView)(staleDependencies),
            });
        }
        const sharedViewItems = [];
        const isStaleAndActive = this.isStaleAndActive(sharedEntity);
        if (!isDependency || isStaleAndActive) {
            sharedViewItems.push({
                name: 'Shared',
                view: (0, SharedEntityObjectView_1.getSharedEntityActiveStatusObjectView)(isDependency),
            });
        }
        return {
            items: [
                !isDependency &&
                    sharedEntity.Description && {
                    name: 'Name',
                    values: [sharedEntity.Description],
                },
                !isDependency && {
                    name: 'Share Mode',
                    values: [sharedEntity.Type],
                },
                ...sharedViewItems,
                {
                    name: 'Type',
                    view: SharedEntityObjectView_1.SharedEntityTypeItemView,
                },
                ...staleDependenciesViewItems,
                ArrayExtensions_1.default.IsNotNullOrEmpty(sharedEntity.EntityDependencyIds) && {
                    name: 'Dependencies',
                    isLabelInline: true,
                    view: SharedEntityDependencies_1.SharedEntityDependencies,
                },
            ].filter(Boolean),
            abObject: sharedEntity,
        };
    }
    toViewAll() {
        return ((this.api.teamSharingApi.getLoadedAdaptableSharedEntities() ?? [])
            // only top level
            .filter((sharedEntity) => !this.isSharedEntityADependency(sharedEntity))
            .map((item) => this.toView(item)));
    }
    getViewProperties() {
        return {
            actions: [TeamSharingApplyButton_1.TeamSharingApplyButton],
            onMount: () => {
                this.api.teamSharingApi.refreshTeamSharing();
            },
            getDeleteAction: (sharedEntity) => {
                return TeamSharingRedux.TeamSharingRemoveItem(sharedEntity.Uuid);
            },
            emptyView: 'Shared Items will appear here when available.',
        };
    }
}
exports.TeamSharingModule = TeamSharingModule;
