import flatten from 'lodash/flatten';
import * as React from 'react';
import HelpBlock from '../../../../components/HelpBlock';
import { Icon } from '../../../../components/icons';
import { DataSource, InfiniteTableGrid, } from '../../../../components/InfiniteTable';
import { Tag } from '../../../../components/Tag';
import { useAdaptable } from '../../../AdaptableContext';
import { AdaptablePopover } from '../../../AdaptablePopover';
import UIHelper from '../../../UIHelper';
const tableDOMProps = {
    style: {
        height: '100%',
        minWidth: '10rem',
        minHeight: 300,
        flex: 1,
    },
};
const getRowErrors = (errors, primaryKeyValue) => {
    if (!errors) {
        return null;
    }
    if (!errors[primaryKeyValue]) {
        return null;
    }
    return errors[primaryKeyValue];
};
const getCellError = (errors, primaryKeyValue, columnId) => {
    return getRowErrors(errors, primaryKeyValue)?.find((e) => e.columnId === columnId) ?? null;
};
export const DataPreview = (props) => {
    const adaptable = useAdaptable();
    const dataImportOptions = adaptable.api.optionsApi.getDataImportOptions();
    if (!props.data) {
        return (React.createElement(HelpBlock, { color: 'var(--ab-color-error)' },
            "No Data has been Imported. Go to ",
            React.createElement(Tag, null, "Upload"),
            " step and provide Data"));
    }
    const primaryKey = adaptable.api.optionsApi.getPrimaryKey();
    const columns = React.useMemo(() => {
        const mappedAdaptableColumns = props.columnsMap?.filter((map) => map.include && map.abColumn);
        const mapDataType = (dataType) => {
            switch (dataType) {
                case 'boolean':
                    return 'boolean';
                case 'date':
                    return 'date';
                case 'number':
                    return 'number';
                case 'text':
                    return 'string';
            }
            return dataType;
        };
        const getPrimaryKeyValue = (rowData) => {
            if (typeof dataImportOptions._getPrimaryKeyValue === 'function') {
                return dataImportOptions._getPrimaryKeyValue({
                    ...adaptable.api.internalApi.buildBaseContext(),
                    rowData,
                });
            }
            return rowData[primaryKey];
        };
        const infiniteColumns = mappedAdaptableColumns.reduce((acc, colMap) => {
            const isPrimaryKey = colMap?.abColumn?.columnId === primaryKey;
            let editable = !isPrimaryKey;
            if (props.editable !== undefined && !isPrimaryKey) {
                editable = props.editable;
            }
            const abColumn = colMap.abColumn;
            acc[colMap.field] = {
                field: colMap.field,
                header: adaptable.api.columnApi.getFriendlyNameForColumnId(colMap.abColumn.columnId),
                dataType: mapDataType(abColumn.dataType),
                defaultEditable: editable,
                valueGetter: (params) => {
                    if (abColumn.dataType === 'boolean') {
                        return params.data[colMap.field] ? 'True' : 'False';
                    }
                    else {
                        return params.data[colMap.field];
                    }
                },
            };
            return acc;
        }, {});
        infiniteColumns['valid'] = {
            header: 'Valid',
            maxWidth: 100,
            minWidth: 90,
            align: 'center',
            renderValue: (params) => {
                const cellErrors = getRowErrors(props.errors, getPrimaryKeyValue(params.data));
                const successColor = UIHelper.getColorByMessageType('Success');
                if (!cellErrors || cellErrors.length === 0) {
                    return React.createElement(Icon, { name: "check", style: { color: successColor, fill: 'currentColor' } });
                }
                const errorsStr = cellErrors.map((e) => e.error).join(', ');
                return (React.createElement(AdaptablePopover, { popoverMinWidth: 200, showEvent: "mouseenter", hideEvent: "mouseleave", headerText: 'Validation Error', bodyText: [errorsStr], MessageType: 'Error' }));
            },
        };
        infiniteColumns['type'] = {
            header: 'Type',
            maxWidth: 100,
            minWidth: 90,
            renderValue: (params) => {
                try {
                    const isExistingRow = adaptable.api.gridApi.getRowNodeForPrimaryKey(getPrimaryKeyValue(params.data));
                    return isExistingRow ? 'Update' : 'New';
                }
                catch (error) {
                    // empty
                }
                return React.createElement(React.Fragment, null);
            },
        };
        return infiniteColumns;
    }, [props.data]);
    const getCellErrorStyle = (columnId, primaryKeyValue) => {
        const cellError = getCellError(props.errors, primaryKeyValue, columnId);
        if (!cellError) {
            return {};
        }
        return {
            border: 'var(--ab-Dataimport-validation-error__border)',
        };
    };
    return (React.createElement(DataSource, { data: props.data, primaryKey: primaryKey, onDataMutations: (params) => {
            const newRowData = [...props.data];
            const mutationsList = flatten(Array.from(params.mutations.values()));
            if (!mutationsList.length) {
                return;
            }
            mutationsList.forEach((mutation) => {
                const index = newRowData.findIndex((row) => row[primaryKey] === mutation.primaryKey);
                if (index !== -1) {
                    newRowData[index] = { ...newRowData[index], ...mutation.data };
                }
            });
            props.onDataChange(newRowData);
        } },
        React.createElement(InfiniteTableGrid, { columnPinning: {
                valid: 'end',
                type: 'end',
            }, columnTypes: {
                default: {
                    style: (params) => {
                        return getCellErrorStyle(params.column.id, params.rowInfo.id);
                    },
                    minWidth: 100,
                    defaultFlex: 1,
                },
            }, domProps: tableDOMProps, columns: columns })));
};
