var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import React, { forwardRef, useCallback, useEffect, useMemo, useState } from 'react';
import WidgetCard from '../../WidgetCard';
import { RemindersCard } from '../../../../reminders/RemindersCard';
import { FluentButton } from '../../../inputs/buttons/FluentButton';
import { CircularProgress, makeStyles, FormControlLabel, Switch } from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import { useUser } from '../../../../utilities/auth/useUser';
import { getSearchIdentifiers, getSearchObject } from '../../../../utilities/search/SearchUtilities';
import { executeQueryAdHoc, executeQueryWithParameters, getBaseMethod } from '../../../../udp/utilities/methodUtils';
import { LogicalSearchOperatorEnums, UdpEnums, UdpReminderFiledForType } from '../../../../enums/unitySystemEnums';
import { useActionState } from '../../../../hooks/useActions';
import { useHandleAxiosSnackbar } from '../../../../utilities/apiHelpers';
import { FluentIconButton } from '../../../inputs/buttons/FluentIconButton';
import { SortIcon } from '@fluentui/react-icons';
import { Alert } from '@material-ui/lab';
import { v4 as uuid } from 'uuid';
// export const layout = {
//   w: { default: 2, min: 0, max: 4 },
//   h: { default: 2, min: 0, max: 4 }
// };
const useStyles = makeStyles((theme) => ({
    root: {},
    actions: {
        display: 'flex',
        alignItems: 'center',
        width: '100%',
        justifyContent: 'flex-end'
    },
    actionButton: {
        marginRight: theme.spacing(0.25),
        position: 'relative'
    },
    fabProgress: {
        position: 'absolute',
        top: 4,
        left: '35%',
        zIndex: 1
    }
}));
export const RemindersWidget = (props, ref) => {
    const { children, params, setParam } = props, other = __rest(props, ["children", "params", "setParam"]);
    const { onLoadedNodeClick, hideWidgetName, tree, catalogObjects } = params;
    const [sortDirection, setSortDirection] = useState(null);
    const [reminders, setReminders] = useState(null);
    const [loading, setLoading] = useState(false);
    const [allRemindersRequested, setAllRemindersRequested] = useState(false);
    const [buttonProgress, setButtonProgress] = useState(false);
    const [alertWarnings, setAlertWarnings] = useState([]);
    const classes = useStyles(props);
    const actionState = useActionState();
    const { catalogPromotedEntities } = actionState;
    const { handleErrorSnackbar } = useHandleAxiosSnackbar();
    const { t } = useTranslation();
    const user = useUser();
    const reminderFiledForSearchApiMethod = useMemo(() => {
        return getBaseMethod(UdpEnums.Udp_Reminder_Filed_For, 'unityBaseSearchMethod', catalogPromotedEntities);
    }, [catalogPromotedEntities]);
    const updateReminderApiMethod = useMemo(() => {
        return getBaseMethod(UdpEnums.Udp_Reminder, 'unityBaseUpdateMethod', catalogPromotedEntities);
    }, [catalogPromotedEntities]);
    const currentSortDirection = useMemo(() => {
        if (sortDirection === 'asc') {
            return 'desc';
        }
        else if (sortDirection === 'desc') {
            return 'asc';
        }
        else {
            return null;
        }
    }, [sortDirection]);
    const getNodeToLoad = useCallback((reminder) => {
        var _a, _b, _c, _d;
        const nodeToLoad = {};
        const domainObject = reminder === null || reminder === void 0 ? void 0 : reminder.domainObject;
        const entityBusinessKey = (reminder === null || reminder === void 0 ? void 0 : reminder.entityBusinessKey) || '';
        let treeStructureId = '';
        let apiMethodId = '';
        const matchingNode = (_a = tree === null || tree === void 0 ? void 0 : tree.treeStructure) === null || _a === void 0 ? void 0 : _a.find((node) => {
            var _a;
            return ((_a = node.properties) === null || _a === void 0 ? void 0 : _a.catalogReturnObject) === domainObject;
        });
        if (matchingNode) {
            treeStructureId = matchingNode.id;
            if (!matchingNode.parentId) {
                apiMethodId = tree.apiMethodInstance.apiMethodId;
            }
            else {
                const associatedInquiryTree = (_b = matchingNode.properties) === null || _b === void 0 ? void 0 : _b.associatedInquiryTree;
                if (associatedInquiryTree) {
                    apiMethodId =
                        ((_c = associatedInquiryTree.apiMethodInstance) === null || _c === void 0 ? void 0 : _c.apiMethodId) || '';
                }
            }
        }
        nodeToLoad.apiMethodId = apiMethodId;
        const searchIdentifiers = getSearchIdentifiers(catalogObjects, domainObject);
        const filterElements = [];
        const searchValue = (_d = entityBusinessKey.split('|')) === null || _d === void 0 ? void 0 : _d[1];
        const values = searchValue.split(',');
        searchIdentifiers.forEach((searchIdentifier, index) => {
            const searchField = searchIdentifier
                ? searchIdentifier.charAt(0).toUpperCase() + searchIdentifier.slice(1)
                : '';
            filterElements.push({
                searchField: searchField,
                searchOperator: '=',
                searchValue: values[index]
            });
        });
        nodeToLoad.queryPayload = getSearchObject(filterElements, 1, 50, true, LogicalSearchOperatorEnums.And);
        nodeToLoad.nodeDetails = {
            catalogReturnObject: domainObject,
            treeStructureId: treeStructureId
        };
        return nodeToLoad;
    }, [tree, catalogObjects]);
    const getIcon = useCallback((reminder) => {
        var _a, _b;
        const domainObject = reminder === null || reminder === void 0 ? void 0 : reminder.domainObject;
        const matchingNode = (_a = tree === null || tree === void 0 ? void 0 : tree.treeStructure) === null || _a === void 0 ? void 0 : _a.find((node) => {
            var _a;
            return ((_a = node.properties) === null || _a === void 0 ? void 0 : _a.catalogReturnObject) === domainObject;
        });
        return ((_b = matchingNode === null || matchingNode === void 0 ? void 0 : matchingNode.properties) === null || _b === void 0 ? void 0 : _b.defaultIcon) || {};
    }, [tree]);
    const sortByDate = useCallback((reminderList, direction) => {
        const sortedReminders = [...reminderList];
        if (direction === 'asc') {
            sortedReminders.sort((a, b) => new Date(b.reminderDate) - new Date(a.reminderDate));
        }
        else if (direction === 'desc') {
            sortedReminders.sort((a, b) => new Date(a.reminderDate) - new Date(b.reminderDate));
        }
        setReminders(sortedReminders);
    }, []);
    const sort = useCallback(() => {
        sortByDate(reminders, sortDirection || 'desc');
        if (sortDirection === 'desc' || !sortDirection) {
            setSortDirection('asc');
        }
        else if (sortDirection === 'asc') {
            setSortDirection('desc');
        }
    }, [reminders, sortByDate, sortDirection]);
    const getReminders = useCallback(async (allRequested = false, rffSearchApiMethod) => {
        let remindersList = [];
        const warnings = [];
        if (!reminders) {
            setLoading(true);
        }
        let filterElements = [
            {
                searchField: 'Reminder.Acknowledged',
                searchValue: false,
                searchOperator: '=',
                groupId: 1
            },
            {
                searchField: 'Reminder.ReminderDate',
                searchValue: new Date(),
                searchOperator: '<=',
                groupId: 1
            },
            {
                searchField: 'Type',
                searchValue: UdpReminderFiledForType.System,
                searchOperator: '=',
                groupId: 2
            },
            {
                searchField: 'Type',
                searchValue: UdpReminderFiledForType.User,
                searchOperator: '=',
                groupId: 3
            },
            {
                searchField: 'Reminder.UnityUserID',
                searchValue: user.id,
                searchOperator: '=',
                groupId: 3
            }
        ];
        let filterGroups = [
            {
                groupId: 1,
                logicalSearchOperator: LogicalSearchOperatorEnums.And,
                parentGroupId: null
            },
            {
                groupId: 2,
                logicalSearchOperator: LogicalSearchOperatorEnums.Or,
                parentGroupId: null
            },
            {
                groupId: 3,
                logicalSearchOperator: LogicalSearchOperatorEnums.And,
                parentGroupId: 2
            }
        ];
        if (allRequested) {
            filterElements = [
                {
                    searchField: 'Type',
                    searchValue: UdpReminderFiledForType.System,
                    searchOperator: '=',
                    groupId: 2
                },
                {
                    searchField: 'Type',
                    searchValue: UdpReminderFiledForType.User,
                    searchOperator: '=',
                    groupId: 3
                },
                {
                    searchField: 'Reminder.UnityUserID',
                    searchValue: user.id,
                    searchOperator: '=',
                    groupId: 3
                }
            ];
            filterGroups = [
                {
                    groupId: 2,
                    logicalSearchOperator: LogicalSearchOperatorEnums.Or,
                    parentGroupId: null
                },
                {
                    groupId: 3,
                    logicalSearchOperator: LogicalSearchOperatorEnums.And,
                    parentGroupId: 2
                }
            ];
        }
        const searchObject = getSearchObject(filterElements, 1, 200, true, LogicalSearchOperatorEnums.And, filterGroups);
        const data = { data: searchObject };
        if (rffSearchApiMethod) {
            if (!rffSearchApiMethod.apiMethodId) {
                warnings.push({
                    id: uuid(),
                    severity: 'warning',
                    message: t('Search ReminderFiledFor Method Not Promoted')
                });
            }
            else {
                const response = await executeQueryAdHoc(data, rffSearchApiMethod.apiMethodId).catch((e) => {
                    setLoading(false);
                });
                if ((response === null || response === void 0 ? void 0 : response.status) === 200) {
                    const pageList = response.data.pageList;
                    if (pageList === null || pageList === void 0 ? void 0 : pageList.length) {
                        remindersList = pageList.map((item) => (Object.assign(Object.assign({}, item.reminder), { domainObject: item.domainObject, filedToType: item.type, entityBusinessKey: item.entityBusinessKey })));
                    }
                }
                else {
                    warnings.push({
                        id: uuid(),
                        severity: 'error',
                        message: t('Could not retrieve reminders')
                    });
                }
            }
        }
        // Filter for reminders that belong to any of the domains within the tree
        const treeDomains = tree === null || tree === void 0 ? void 0 : tree.treeStructure.map((node) => {
            var _a;
            return (_a = node.properties) === null || _a === void 0 ? void 0 : _a.catalogReturnObject;
        });
        if (treeDomains.length) {
            remindersList = remindersList.filter((reminder) => treeDomains.includes(reminder.domainObject));
        }
        else {
            remindersList = [];
        }
        setAlertWarnings(warnings);
        setLoading(false);
        sortByDate(remindersList, currentSortDirection);
    }, [t, user, reminders, sortByDate, currentSortDirection, tree]);
    const updateRemindersAcknowledgement = useCallback(async (reminders) => {
        if (updateReminderApiMethod) {
            const updatedPromises = [];
            reminders.forEach((reminder) => {
                reminder.acknowledged = reminder.checked;
                const data = {
                    requestBody: Object.assign({}, reminder)
                };
                data['{iD}'] = reminder.id;
                updatedPromises.push(executeQueryWithParameters({ data }, updateReminderApiMethod.apiMethodId));
            });
            await Promise.all(updatedPromises.map((p) => p.catch((e) => e))).then((responses) => {
                responses.forEach((response) => {
                    if (response.status === 200) {
                        const entityBusinessKey = response.data.entityBusinessKey;
                        const matchingReminder = reminders === null || reminders === void 0 ? void 0 : reminders.find((nftu) => nftu.value === entityBusinessKey);
                        if (!matchingReminder) {
                            console.warn(`Reminder not updated for all file to entities`);
                        }
                    }
                });
            });
        }
        else {
            handleErrorSnackbar(null, 'Update Reminder Method Not Promoted');
        }
    }, [updateReminderApiMethod, handleErrorSnackbar]);
    const handleAcknowledgeClick = useCallback(async () => {
        const acknowledgedReminders = reminders === null || reminders === void 0 ? void 0 : reminders.filter((r) => r.checked);
        if (acknowledgedReminders.length) {
            setButtonProgress(true);
            await updateRemindersAcknowledgement(acknowledgedReminders);
            setButtonProgress(false);
            getReminders(allRemindersRequested, reminderFiledForSearchApiMethod);
        }
    }, [
        reminders,
        getReminders,
        updateRemindersAcknowledgement,
        allRemindersRequested,
        reminderFiledForSearchApiMethod
    ]);
    const handleSwitchChange = useCallback((event) => {
        // Only show the spinner if the effect will actually fetch (and therefore
        // clear loading); otherwise it would stick on until the method resolves.
        if (reminderFiledForSearchApiMethod) {
            setLoading(true);
        }
        setAllRemindersRequested(event.target.checked);
    }, [reminderFiledForSearchApiMethod]);
    // getReminders is intentionally omitted from deps because it changes identity
    // on every fetch (depends on `reminders`), which would cause an infinite loop.
    useEffect(() => {
        if (reminderFiledForSearchApiMethod) {
            getReminders(allRemindersRequested, reminderFiledForSearchApiMethod);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [reminderFiledForSearchApiMethod, allRemindersRequested]);
    return (React.createElement(WidgetCard, Object.assign({ ref: ref, 
        // title={'Reminders'}
        hideWidgetName: hideWidgetName, headerActions: React.createElement("div", { className: classes.actions }, React.createElement(FormControlLabel, { control: React.createElement(Switch, { id: "udpRecord-RemindersWidget-Switch", udprecordid: "udpRecord-RemindersWidget-Switch", size: "small", onChange: handleSwitchChange, onMouseDown: (e) => e.stopPropagation() }), label: "All", style: { marginRight: 8 } }), React.createElement(FluentIconButton, { id: "udpRecord-RemindersWidget-Sort", udprecordid: "udpRecord-RemindersWidget-Sort", icon: SortIcon, onClick: sort, style: { marginRight: 4 }, onMouseDown: (e) => e.stopPropagation() }), React.createElement("div", { className: classes.actionButton }, React.createElement(FluentButton, { id: "udpRecord-RemindersWidget-Complete", udprecordid: "udpRecord-RemindersWidget-Complete", variant: "contained", color: "secondary", onClick: handleAcknowledgeClick, onMouseDown: (e) => e.stopPropagation() }, buttonProgress && (React.createElement(CircularProgress, { size: 24, color: "primary", className: classes.fabProgress })), t('Complete')))) }, other), alertWarnings.length ? (alertWarnings.map((warning) => (React.createElement(Alert, { key: warning.id, severity: warning.severity || 'warning' }, warning.message || '')))) : (React.createElement(RemindersCard, { reminders: reminders, setReminders: setReminders, loading: loading, onLoadedNodeClick: onLoadedNodeClick, getNodeToLoad: getNodeToLoad, getIcon: getIcon, updateRemindersAcknowledgement: updateRemindersAcknowledgement })), children));
};
export default forwardRef(RemindersWidget);
//# sourceMappingURL=RemindersWidget.js.map