import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { apiMutate } from '../../../utilities/useAxiosMutate';
import { IconRenderer } from '../../../UI/templates/ui/renderers/IconRenderer';
import { LayoutUnit } from '../../../layout/LayoutUnit';
import { createTimeline } from '../timeline.ts';
import { SummaryToken } from '../ui/SummaryToken';
import { CardContent, LinearProgress, Typography, makeStyles } from '@material-ui/core';
import Skeleton from '@material-ui/lab/Skeleton';
import { TimelineTopRowFilter } from '../ui/TimelineTopRowFilter';
import { DateWrapper } from '../ui/DateWrapper';
import { CircleButton } from '../ui/CircleButton';
import { RedEyeIcon } from '@fluentui/react-icons';
import { Link } from 'react-router-dom';
import { formatDataWithTimelineCategoryName } from '../functions/mttFunctions';
import { MttYearTag } from '../ui/MttYearTag';
import PropTypes from 'prop-types';
import { v4 as uuid } from 'uuid';
import { ConfigService } from '../../../configService';
const useStyles = makeStyles((theme) => ({
    root: {},
    wrapper: {
        background: theme.palette.common.white,
        borderRadius: theme.spacing(0.5),
        overflow: 'hidden'
    },
    launch: {
        marginLeft: theme.spacing(8)
    }
}));
export const MttSummary = (props) => {
    const { timelineApiMethodInstanceId, insightPath = '/mtt-main', params } = props;
    const [data, setData] = useState([]);
    const [timelineThreads, setTimelineThreads] = useState(null);
    const [timeline, setTimeline] = useState(null);
    const [loading, setLoading] = useState(false);
    const [filters, setFilters] = useState([]);
    const [allFilters, setAllFilters] = useState([]);
    const [compact, setCompact] = useState(true);
    const [filterListGroup, setFilterListGroup] = useState();
    const [filterKey, setFilterKey] = useState(uuid());
    const classes = useStyles();
    const preloadLength = 11;
    const executeQueryInstance = useCallback(async (apiMethodInstanceId, data = {}) => apiMutate(ConfigService.integrationV1ApiUrl, `apimethod/executeQueryInstance/${apiMethodInstanceId}`, {
        method: 'post'
    }, { data: data }), []);
    const summaryThreads = useMemo(() => {
        var _a;
        if (!((_a = timeline === null || timeline === void 0 ? void 0 : timeline.threads) === null || _a === void 0 ? void 0 : _a.length)) {
            return [];
        }
        setData(formatDataWithTimelineCategoryName(timeline.threads.filter((thread) => thread.inSummary)));
        return timeline.threads.filter((thread) => thread.inSummary);
    }, [timeline]);
    const summaryEvents = useMemo(() => {
        if (!summaryThreads.length) {
            return [];
        }
        return summaryThreads.map((st) => st.events).flat();
    }, [summaryThreads]);
    // Get Filter Array
    let filterItems = [];
    summaryThreads &&
        summaryThreads.map((item) => {
            filterItems.push(item.name);
        });
    const addFilter = (filter) => {
        if (filters.includes(filter)) {
            const updatedFilter = filters.filter((e) => e !== filter);
            setFilters(updatedFilter);
        }
        else {
            setFilters([...filters, filter]);
        }
    };
    const clearFilters = useCallback(() => {
        setFilters([]);
    }, []);
    useEffect(() => {
        const fetchTimelineThreads = async () => {
            var _a;
            const timelineResponse = await executeQueryInstance(timelineApiMethodInstanceId);
            if ((timelineResponse === null || timelineResponse === void 0 ? void 0 : timelineResponse.status) === 200) {
                setTimelineThreads(((_a = timelineResponse === null || timelineResponse === void 0 ? void 0 : timelineResponse.data) === null || _a === void 0 ? void 0 : _a.pageList) || []);
            }
        };
        fetchTimelineThreads();
    }, [executeQueryInstance, timelineApiMethodInstanceId]);
    useEffect(() => {
        const fetchThreadEvents = async () => {
            if (!timelineThreads) {
                return null;
            }
            setLoading(true);
            const promises = [];
            const threadList = [];
            timelineThreads.forEach((thread) => {
                promises.push(executeQueryInstance(thread.queryID, Object.assign({}, params)));
            });
            await Promise.all(promises.map((p) => p.catch((e) => {
                setLoading(false);
                return e;
            }))).then((responses) => {
                responses.forEach((response, index) => {
                    var _a;
                    if (response.status === 200) {
                        const timelineThread = timelineThreads[index];
                        if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.pageList) {
                            response.data.pageList.forEach((evt) => (evt.threadId = timelineThread.name));
                            const thread = Object.assign(Object.assign({}, timelineThread), { events: response.data.pageList });
                            threadList.push(thread);
                        }
                    }
                });
                setLoading(false);
            });
            setTimeline(createTimeline(threadList));
            // setData(formatDataWithTimelineCategoryName(threadList))
        };
        fetchThreadEvents();
    }, [executeQueryInstance, timelineThreads, params]);
    useEffect(() => {
        const filterList = summaryEvents &&
            summaryEvents.map((item) => {
                return item.threadId;
            });
        setAllFilters(filterList);
        setFilters(filterList);
    }, [summaryEvents]);
    useEffect(() => {
        const filterListGroup = [];
        summaryEvents &&
            summaryEvents.map((item) => {
                filterListGroup.push({
                    name: item.threadId,
                    icon: item.icon,
                    color: item.color
                });
            });
        const key = 'name';
        const arrayUniqueByKey = [
            ...new Map(filterListGroup.map((item) => [item[key], item])).values()
        ];
        setFilterKey(uuid());
        setFilterListGroup(arrayUniqueByKey);
    }, [summaryEvents]);
    const mappedToDetails = data &&
        data
            .map((item) => item.dates)
            .flat()
            .map((item) => item.details)
            .flat();
    // for Skeleton preloading
    const summaryLength = summaryThreads.length || preloadLength;
    const getMembers = (members) => {
        let events = [];
        return members
            .map((mem) => {
            const m = Object.assign({}, mem);
            if (m.events && m.events.length) {
                events = [...events, ...m.events];
            }
            delete m.events;
            return m;
        })
            .concat(events.length ? getMembers(events) : events);
    };
    getMembers(summaryThreads);
    const dataConvertedFilter = mappedToDetails &&
        mappedToDetails.filter((item) => filters === null || filters === void 0 ? void 0 : filters.includes(item.threadId));
    // Feed dataConvertedFilter into the grouping function (this should filter the array of objects before they are grouped)
    function groupByMonth(object) {
        let finalObject = [];
        object.forEach((el) => {
            let foundFlag = false;
            finalObject.forEach((foEl) => {
                if (foEl.month === el.date.split('/')[0] &&
                    foEl.year === el.date.split('/')[2]) {
                    foEl.details.push(el);
                    foundFlag = true;
                }
            });
            if (!foundFlag) {
                finalObject.push({
                    month: el.date.split('/')[0],
                    year: el.date.split('/')[2],
                    details: [el]
                });
            }
        });
        return finalObject;
    }
    const SkeletonLoading = () => {
        return (React.createElement("div", { style: { marginRight: 48 } }, React.createElement(LayoutUnit, { unit: "nudge" }), React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } }, React.createElement(Skeleton, { variant: "circle", width: 30, height: 30 })), React.createElement(LayoutUnit, { unit: "nudge" }), React.createElement("div", { style: { display: 'flex', justifyContent: 'center' } }, React.createElement(Skeleton, { variant: "rect", width: 1, height: 25 })), React.createElement(Skeleton, { variant: "text" }), React.createElement(Skeleton, { variant: "text" }), React.createElement(LayoutUnit, { unit: "sm" }), React.createElement(Skeleton, { variant: "rect", width: 80, height: 6 })));
    };
    const preLoading = [...Array(summaryLength).keys()].slice(1);
    const dataToSort = data && groupByMonth(dataConvertedFilter);
    const sorted = dataToSort.sort((a, b) => a.year - b.year || a.month - b.month);
    const getYears = [];
    data &&
        dataToSort.map((item) => {
            getYears.push({ year: item.year });
        });
    const uniqueYears = [...new Set(getYears.map((item) => item.year))];
    return (React.createElement("div", null, React.createElement("div", { className: classes.wrapper }, loading && React.createElement(LinearProgress, { color: "secondary" }), React.createElement(CardContent, null, React.createElement("div", { style: {
            display: 'flex',
            position: 'relative'
        } }, React.createElement("div", { style: { flex: 1 } }, React.createElement(Typography, { variant: "h6" }, "Timeline Summary"), React.createElement(LayoutUnit, { unit: "md" })), React.createElement("div", { style: { display: 'flex' } }, React.createElement("div", { key: filterKey }, React.createElement(TimelineTopRowFilter, { compact: compact, setCompact: setCompact, onClose: () => setCompact(!compact), filterCall: (type) => addFilter(type), clear: clearFilters, filterList: filterItems && filterItems, filterListGroup: filterListGroup && filterListGroup })), React.createElement("div", { className: classes.launch }, React.createElement(CircleButton, { component: Link, to: {
            pathname: insightPath,
            state: {
                timelineApiMethodInstanceId: timelineApiMethodInstanceId
            }
        } }, React.createElement(RedEyeIcon, null))))), React.createElement("div", { style: { display: 'flex', overflow: 'scroll', direction: 'rtl' } }, React.createElement("div", { style: { direction: 'ltr', display: 'flex' } }, loading &&
        preLoading.map((item) => {
            return React.createElement(SkeletonLoading, { key: item });
        }), uniqueYears.map((uniqueYear, index) => (React.createElement("div", { style: { display: 'flex' } }, !loading && (React.createElement(MttYearTag, { year: true, count: 12 }, uniqueYear)), summaryEvents &&
        data &&
        sorted.map((item) => {
            if (item.year === uniqueYears[index]) {
                return (React.createElement(DateWrapper, { months: Number(item.month), count: item.details.length }, item.details.map((item) => {
                    return (React.createElement("div", { key: item.id }, React.createElement(SummaryToken, { showMonth: true, months: [item.date], summary: true, icon: React.createElement(IconRenderer
                        //noBorder
                        , { 
                            //noBorder
                            removeMargin: true, value: {
                                color: { hex: '#' + item.color },
                                //name: item.icon ? item.icon : 'MessageIcon',
                                name: item.icon
                            } }), showToken: true, status: item.data1 &&
                            item.data1.toString().trim() !== ''
                            ? null
                            : Number(item.data2), timelineItem: item.transactionType, title: item.shortDescription, date: item.date, dot: false, relative: true, amount: item.data1, month: Number(item.date.charAt(0)), user: item.data3, balance: item.data4, hidebackground: true })));
                })));
            }
            else
                return null;
        }))))))))));
};
MttSummary.propTypes = {
    timelineApiMethodInstanceId: PropTypes.string.isRequired
};
//# sourceMappingURL=MttSummary.js.map