import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Redirect } from 'react-router-dom';
import Page from '../Page';
import { makeStyles, Card, CircularProgress } from '@material-ui/core';
import { Alert } from '@material-ui/lab';
import { PrimaryActionHeader } from '../../UI/utilityDisplay/utilityHeader/PrimaryActionHeader';
import { PageContextProvider } from '../../contexts/PageContext.tsx';
import { useAxiosGet } from '../../utilities/useAxiosGet';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { v4 as uuid } from 'uuid';
import { useTranslation } from 'react-i18next';
import { useSetLocationState } from '../../hooks/useSetLocationState';
import { ConfigService } from '../../configService';
import { useUser } from '../../utilities/auth/useUser';
const useStyles = makeStyles((theme) => ({
    root: {
        marginTop: (props) => (props.disableMargins ? 0 : theme.spacing(3)),
        marginRight: (props) => (props.disableMargins ? 0 : theme.spacing(3)),
        marginLeft: (props) => (props.disableMargins ? 0 : theme.spacing(3)),
        height: (props) => {
            var _a;
            return (_a = props.height) !== null && _a !== void 0 ? _a : '100%';
        },
        overflow: (props) => props.height && 'auto'
    },
    staticRoot: {
        marginTop: 0,
        marginRight: 0,
        marginLeft: 0,
        height: (props) => {
            var _a;
            return (_a = props.height) !== null && _a !== void 0 ? _a : '100%';
        },
        overflow: (props) => props.height && 'auto'
    },
    title: {
        flex: 1,
        marginBottom: theme.spacing(1)
    },
    icon: {
        marginTop: theme.spacing(-2.5)
    },
    loadingContent: {
        flex: 1,
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        height: (props) => props.loadingHeight ? props.loadingHeight : 'calc(100vh - 160px)'
    }
}));
export const PageContainer = (props) => {
    var _a, _b;
    const { widgetParams, redirectSlug, pageData, pageLoading = false, disableMargin = true, location, fromMenu = false, loadingHeight, isHomePage = false, pageId: id, updateLocationState = true, autoHeight, } = props;
    const user = useUser();
    const classes = useStyles(props);
    const [page, setPage] = useState(null);
    const [alertWarnings, setAlertWarnings] = useState([]);
    const params = (_a = location === null || location === void 0 ? void 0 : location.state) === null || _a === void 0 ? void 0 : _a.params;
    const pathPageId = (_b = location === null || location === void 0 ? void 0 : location.pathname) === null || _b === void 0 ? void 0 : _b.replace('/page/', '');
    const pageId = (pathPageId === '/' ? null : pathPageId) || (params === null || params === void 0 ? void 0 : params.PageId) || id;
    const { t } = useTranslation();
    const setLocationState = useSetLocationState();
    const [{ data: pageInfo, loading: pageInfoLoading }] = useAxiosGet(ConfigService.tenantV1ApiUrl, `page/${pageId}`, {}, !!!pageId, false);
    const [{ data: homePage, loading: homePageLoading, error: homePageError }, refetchHomePage] = useAxiosGet(ConfigService.tenantV1ApiUrl, `page/homePage?tenantId=${user === null || user === void 0 ? void 0 : user.currentTenantId}&productId=${ConfigService.config.UNITY_PRODUCT_ID}`, {}, !isHomePage, false);
    const removeWarning = useCallback((id) => {
        setAlertWarnings((prevWarnings) => prevWarnings.filter((warning) => warning.id !== id));
    }, []);
    const getRequiredFieldWarnings = useCallback((requiredFields = '', widgetParams) => {
        const fieldsStr = requiredFields || '';
        if (!fieldsStr.trim()) {
            return;
        }
        const warnings = [];
        const requiredFieldsMap = (widgetParams === null || widgetParams === void 0 ? void 0 : widgetParams.requiredFieldsMap) || {};
        const nodeObj = (widgetParams === null || widgetParams === void 0 ? void 0 : widgetParams.nodeObj) || {};
        const fields = fieldsStr.split(',').map((str) => str.trim());
        const missingRequiredFieldNames = [];
        fields.forEach((fieldName) => {
            const requiredField = requiredFieldsMap[fieldName];
            if (!(requiredField === null || requiredField === void 0 ? void 0 : requiredField.value)) {
                missingRequiredFieldNames.push(fieldName);
            }
            else {
                if (requiredField.type === 'entity' &&
                    (nodeObj[requiredField.value] === undefined ||
                        nodeObj[requiredField.value] === null)) {
                    missingRequiredFieldNames.push(fieldName);
                }
            }
        });
        missingRequiredFieldNames.forEach((name) => {
            warnings.push({
                id: uuid(),
                message: `${name} ${t('field is missing a value')}`
            });
        });
        return warnings;
    }, [t]);
    const pages = useMemo(() => (page === null || page === void 0 ? void 0 : page.widgets) &&
        Object.keys(JSON.parse(page.widgets)).map((key) => {
            // Static Page
            const widgetStr = JSON.parse(page.widgets)[key];
            const widget = widgetStr ? JSON.parse(widgetStr) : null;
            if (widget === null || widget === void 0 ? void 0 : widget.length) {
                widget.forEach((w) => {
                    // Add additional parameters from menu. Will get overwriten if
                    // key exists in page widget parms
                    if (pageId) {
                        w.params = Object.assign({ entityName: params === null || params === void 0 ? void 0 : params.entityName, pbiReportCode: params === null || params === void 0 ? void 0 : params.pbiReportCode, queryId: params === null || params === void 0 ? void 0 : params.queryId, inquiryTreeId: params === null || params === void 0 ? void 0 : params.InquiryTreeId, udpTagId: params === null || params === void 0 ? void 0 : params.udpTagId, requiredFieldsMap: params === null || params === void 0 ? void 0 : params.requiredFieldMapping }, w.params);
                    }
                    if (widgetParams) {
                        w.params = Object.assign(Object.assign({}, w.params), widgetParams);
                    }
                });
            }
            return (React.createElement(DndProvider, { backend: HTML5Backend, key: pageId ? `${key}-${params === null || params === void 0 ? void 0 : params.entityName}` : key }, React.createElement(Page, { user: user, gridConfig: JSON.parse(page.gridProperties)[key], widgetConfig: widget, disableMargin: disableMargin, autoHeight: autoHeight, pageTypeId: page.pageTypeId })));
        }), [
        page,
        user,
        widgetParams,
        disableMargin,
        pageId,
        params,
        autoHeight,
    ]);
    useEffect(() => {
        if (pageId) {
            if (pageInfo) {
                setPage(pageInfo);
            }
        }
        else if (homePage) {
            setPage(homePage);
        }
        else {
            setPage(pageData);
        }
        setAlertWarnings([]);
    }, [pageId, pageInfo, pageData, homePage]);
    useEffect(() => {
        if (page === null || page === void 0 ? void 0 : page.widgets) {
            let warnings = [];
            Object.keys(JSON.parse(page.widgets)).forEach((key) => {
                // Static Page
                const widgetStr = JSON.parse(page.widgets)[key];
                const widget = widgetStr ? JSON.parse(widgetStr) : null;
                if (widget === null || widget === void 0 ? void 0 : widget.length) {
                    widget.forEach((w) => {
                        // Add additional parameters from menu. Will get overwriten if
                        // key exists in page widget parms
                        if (pageId) {
                            w.params = Object.assign({ entityName: params === null || params === void 0 ? void 0 : params.entityName, pbiReportCode: params === null || params === void 0 ? void 0 : params.pbiReportCode, queryId: params === null || params === void 0 ? void 0 : params.queryId, inquiryTreeId: params === null || params === void 0 ? void 0 : params.InquiryTreeId, udpTagId: params === null || params === void 0 ? void 0 : params.udpTagId, requiredFieldsMap: params === null || params === void 0 ? void 0 : params.requiredFieldMapping }, w.params);
                        }
                        if (widgetParams) {
                            w.params = Object.assign(Object.assign({}, w.params), widgetParams);
                        }
                        // Adding condition to compare pageId's
                        if (fromMenu || (page === null || page === void 0 ? void 0 : page.pageId) === (widgetParams === null || widgetParams === void 0 ? void 0 : widgetParams.pageId)) {
                            warnings = getRequiredFieldWarnings(w.requiredParameters, w.params);
                        }
                    });
                }
            });
            setAlertWarnings(warnings);
        }
    }, [page, widgetParams, pageId, params, fromMenu, getRequiredFieldWarnings]);
    // Setting location state label so that if this page was saved to favorites
    // we can determine the bread crumb
    useEffect(() => {
        if (page && updateLocationState) {
            setLocationState({ label: t(page === null || page === void 0 ? void 0 : page.name) });
        }
    }, [setLocationState, t, page, updateLocationState]);
    if (redirectSlug && !pageData) {
        return React.createElement(Redirect, { to: redirectSlug });
    }
    if (pageInfoLoading || pageLoading) {
        return (React.createElement("div", { className: classes.loadingContent }, React.createElement(CircularProgress, { size: loadingHeight || 64 })));
    }
    return (React.createElement(React.Fragment, null, (page === null || page === void 0 ? void 0 : page.showPageName) && (React.createElement(Card, { variant: 'outlined' }, React.createElement(PrimaryActionHeader, { title: page.name, hidePAB: true, single: true }))), React.createElement("div", { className: Number(page === null || page === void 0 ? void 0 : page.pageTypeId) === 1 ? classes.staticRoot : classes.root }, (alertWarnings === null || alertWarnings === void 0 ? void 0 : alertWarnings.length) > 0 &&
        alertWarnings.map((warning) => (React.createElement(Alert, { key: warning.id, onClose: () => removeWarning(warning.id), severity: "warning" }, warning.message || ''))), React.createElement(PageContextProvider, null, pages))));
};
//# sourceMappingURL=PageContainer.js.map