var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
import React, { useCallback, useEffect, useRef, useState } from 'react';
import ReactResizeDetector from 'react-resize-detector';
import i18n from 'ui-i18n';
import { isNil, uniqBy, prop, identity } from 'ramda';
import classnames from 'classnames';
import { getEntity, Mode, getCrosswalkType } from '@reltio/mdm-sdk';
import Button from '@mui/material/Button';
import { HistoryRow } from '../HistoryRow';
import { HistoryGraph } from '../HistoryGraph';
import { LinearLoadIndicator } from '../../../LinearLoadIndicator';
import { useMdmAction, useMdmIsEditableMode, useMdmMetadata } from '../../../contexts/MdmModuleContext';
import { useStyles } from './styles';
export var HistoryTree = function (_a) {
    var _b;
    var historyData = _a.historyData, isLoading = _a.isLoading, canLoadMore = _a.canLoadMore, onLoadMore = _a.onLoadMore, entityUri = _a.entityUri, historyEvent = _a.historyEvent, findPreviousChange = _a.findPreviousChange;
    var styles = useStyles();
    var _c = useState({ historyLanes: {}, rows: [] }), graphData = _c[0], setGraphData = _c[1];
    var _d = useState(false), isScrollable = _d[0], setIsScrollable = _d[1];
    var _e = useState(-1), selectedIndex = _e[0], setSelectedIndex = _e[1];
    var setHistoryEvent = useMdmAction('setHistoryEvent');
    var clearHistoryEvent = useMdmAction('clearHistoryEvent');
    var modeUpdateRequested = useMdmAction('modeUpdateRequested');
    var metadata = useMdmMetadata();
    var isEditableMode = useMdmIsEditableMode();
    useEffect(function () {
        if (isNil(historyEvent)) {
            setSelectedIndex(0);
            return;
        }
        var isCurrentEventChange = function (change) {
            return (change === null || change === void 0 ? void 0 : change.uri) === ((historyEvent === null || historyEvent === void 0 ? void 0 : historyEvent.overrideUri) || entityUri) && (change === null || change === void 0 ? void 0 : change.timestamp) === (historyEvent === null || historyEvent === void 0 ? void 0 : historyEvent.aStamp);
        };
        var selectedChangeByIndex = selectedIndex !== -1 ? historyData.rows[selectedIndex] : null;
        var currentEventChangeIndex = historyData.rows.findIndex(function (change) { return isCurrentEventChange(change); });
        setSelectedIndex(isCurrentEventChange(selectedChangeByIndex) ? selectedIndex : currentEventChangeIndex);
    }, [historyData.rows, historyEvent]);
    var graphRef = useRef(null);
    var rowsRef = useCallback(function (node) {
        var _a;
        if (!isNil(node)) {
            var rows = (_a = historyData.rows) === null || _a === void 0 ? void 0 : _a.map(function (item, i) { var _a; return (__assign(__assign({}, item), { height: (_a = node.childNodes[i]) === null || _a === void 0 ? void 0 : _a.clientHeight })); });
            setGraphData({ historyLanes: historyData.historyLanes, rows: rows });
        }
    }, [historyData]);
    var handleGraphScroll = function () {
        var _a = (graphRef === null || graphRef === void 0 ? void 0 : graphRef.current) || {}, scrollWidth = _a.scrollWidth, clientWidth = _a.clientWidth, scrollLeft = _a.scrollLeft;
        setIsScrollable(scrollLeft < scrollWidth - clientWidth);
    };
    var handleHistoryCircleMouseOver = function (uri, timestamp, index) {
        if (isNil(graphData.rows[index].label)) {
            var options = { time: timestamp, select: 'crosswalks' };
            getEntity(uri, options)
                .then(function (_a) {
                var crosswalks = _a.crosswalks;
                var label = crosswalks
                    ? uniqBy(prop('type'), crosswalks)
                        .map(function (cw) {
                        var crosswalkType = getCrosswalkType(metadata, cw.type);
                        return crosswalkType ? crosswalkType.label : null;
                    })
                        .filter(identity)
                        .join(', ')
                    : i18n.text('No data');
                setGraphData(function (prevGraphData) { return (__assign(__assign({}, prevGraphData), { rows: prevGraphData.rows.map(function (row) { return (row.index === index ? __assign(__assign({}, row), { label: label }) : row); }) })); });
            })
                .catch(function (error) {
                console.warn(error);
            });
        }
    };
    var handleHistoryRowClick = function (index, change, isSelected, isCurrent) {
        if (isEditableMode) {
            modeUpdateRequested(Mode.Viewing);
        }
        if ((isCurrent && !isSelected) || (!isCurrent && isSelected)) {
            clearHistoryEvent();
            setSelectedIndex(0);
        }
        else if (!isCurrent && !isSelected) {
            var aChange = findPreviousChange(index - 1, change.uri || entityUri);
            var bChange = findPreviousChange(index, change.uri || entityUri);
            var aStamp = aChange === null || aChange === void 0 ? void 0 : aChange.timestamp;
            var bStamp = bChange === null || bChange === void 0 ? void 0 : bChange.timestamp;
            var overrideUri = (change === null || change === void 0 ? void 0 : change.uri) === entityUri ? null : change === null || change === void 0 ? void 0 : change.uri;
            setHistoryEvent({ aStamp: aStamp, bStamp: bStamp, overrideUri: overrideUri });
            setSelectedIndex(index);
        }
    };
    return (React.createElement("div", { className: styles.historyTree, "data-reltio-id": "history-tree" },
        isLoading && React.createElement(LinearLoadIndicator, null),
        React.createElement("div", { className: classnames(styles.graph, (_b = {}, _b[styles.shadow] = isScrollable, _b)), onScroll: handleGraphScroll, ref: graphRef },
            React.createElement(HistoryGraph, { onHistoryCircleMouseOver: handleHistoryCircleMouseOver, graphData: graphData }),
            React.createElement(ReactResizeDetector, { handleWidth: true, onResize: handleGraphScroll })),
        React.createElement("div", { ref: rowsRef, className: styles.history }, historyData.rows.map(function (change, i) {
            var isSelected = i === selectedIndex;
            var isCurrent = i === 0;
            return (React.createElement(HistoryRow, { key: "row-".concat(i), change: change, isCurrent: isCurrent, isSelected: isSelected, onClick: function () { return handleHistoryRowClick(i, change, isSelected, isCurrent); } }));
        })),
        canLoadMore && (React.createElement("div", { className: styles.buttonContainer },
            React.createElement(Button, { color: "primary", onClick: function () { return onLoadMore(); } }, i18n.text('Show more'))))));
};
