import { getSearchObject } from '../../utilities/search/SearchUtilities';
import { FilterOperators } from '../../models/SearchOperator.ts';
import { SearchGroupingType, SearchSortDirection, LogicalSearchOperatorEnums } from '../../enums/unitySystemEnums.ts';
export const InquirySearchDatasource = (queryData, apiMethodId, searchFilterElements, logicalSearchOperator = LogicalSearchOperatorEnums.And, executeQuery, searchFilterGroups) => {
    return {
        async getRows(params) {
            var _a;
            const { startRow, endRow, rowGroupCols, groupKeys, valueCols, filterModel, sortModel } = params.request;
            const page = endRow / 20;
            const searchObject = getSearchObject(searchFilterElements, page, null, false, logicalSearchOperator, searchFilterGroups);
            // handle server-side sorting on ag-grid
            if (sortModel.length) {
                const orderElements = searchObject.orderElements;
                sortModel.forEach((sortItem) => {
                    const formattedPropertyName = sortItem.colId.charAt(0).toUpperCase() + sortItem.colId.slice(1);
                    const element = orderElements.find((element) => element.sortColumn === formattedPropertyName);
                    if (element) {
                        element.sortDirection = sortItem.sort.toUpperCase();
                    }
                    else {
                        orderElements.push({
                            sortColumn: formattedPropertyName,
                            sortDirection: sortItem.sort.toUpperCase()
                        });
                    }
                });
            }
            // handle server-side filtering on ag-grid
            if (Object.keys(filterModel).length) {
                const filterElements = searchObject.filterElements;
                Object.keys(filterModel).forEach((key) => {
                    const filterItem = filterModel[key];
                    const formattedPropertyName = key.charAt(0).toUpperCase() + key.slice(1);
                    const element = filterElements.find((element) => element.searchField === formattedPropertyName);
                    if (element) {
                        element.searchValue = filterItem.filter;
                        element.searchOperator = FilterOperators[filterItem.type];
                    }
                    else {
                        filterElements.push({
                            searchField: formattedPropertyName,
                            searchValue: filterItem.filter,
                            searchOperator: FilterOperators[filterItem.type]
                        });
                    }
                });
            }
            // construct search for initial grouping
            if (rowGroupCols.length && !groupKeys.length) {
                const formattedPropertyName = rowGroupCols[0].field.charAt(0).toUpperCase() +
                    rowGroupCols[0].field.slice(1);
                searchObject.groupingType = SearchGroupingType.Distinct;
                if (!searchObject.groupProperty.includes(formattedPropertyName)) {
                    searchObject.groupProperty.push(formattedPropertyName);
                    const orderElements = searchObject.orderElements;
                    const element = orderElements.find((element) => element.sortColumn === formattedPropertyName);
                    if (!element) {
                        orderElements.push({
                            sortColumn: formattedPropertyName,
                            sortDirection: SearchSortDirection.Asc
                        });
                    }
                }
            }
            // construct the filter for grouped columns
            if (groupKeys.length) {
                // construct search for last grouped element
                if (groupKeys.length === rowGroupCols.length) {
                    searchObject.groupingType = '';
                    const filterElements = searchObject.filterElements;
                    groupKeys.forEach((key, index) => {
                        const rowGroupCol = rowGroupCols[index];
                        const formattedPropertyName = rowGroupCol.field.charAt(0).toUpperCase() +
                            rowGroupCol.field.slice(1);
                        const element = filterElements.find((element) => element.searchField === formattedPropertyName);
                        if (element) {
                            element.searchValue = key;
                            element.searchOperator = '=';
                        }
                        else {
                            filterElements.push({
                                searchField: formattedPropertyName,
                                searchValue: key,
                                searchOperator: '='
                            });
                        }
                    });
                }
                else {
                    // construct search for the next grouped element
                    groupKeys.forEach((key, index) => {
                        const formattedPropertyNameForSearch = rowGroupCols[index].field.charAt(0).toUpperCase() +
                            rowGroupCols[index].field.slice(1);
                        searchObject.filterElements.push({
                            searchField: formattedPropertyNameForSearch,
                            searchValue: key,
                            searchOperator: '='
                        });
                    });
                    searchObject.groupingType = SearchGroupingType.Distinct;
                    const searchIndex = groupKeys.length;
                    const rowGroupCol = rowGroupCols[searchIndex];
                    const formattedPropertyName = rowGroupCol.field.charAt(0).toUpperCase() +
                        rowGroupCol.field.slice(1);
                    if (!searchObject.groupProperty.includes(formattedPropertyName)) {
                        searchObject.groupProperty.push(formattedPropertyName);
                        const orderElements = searchObject.orderElements;
                        const element = orderElements.find((element) => element.sortColumn === formattedPropertyName);
                        if (!element) {
                            orderElements.push({
                                sortColumn: formattedPropertyName,
                                sortDirection: SearchSortDirection.Asc
                            });
                        }
                    }
                }
            }
            if (!startRow &&
                rowGroupCols.length === 0 &&
                !sortModel.length &&
                !Object.keys(filterModel).length &&
                !groupKeys.length &&
                queryData) {
                if (queryData.pageList && queryData.pageList) {
                    params.successCallback(queryData.pageList, queryData.total);
                }
                else {
                    // TODO: add an overlay to display no rows
                    params.successCallback([], 0);
                }
            }
            else {
                let response = null;
                if (executeQuery) {
                    const data = { data: searchObject };
                    response = await executeQuery(data, apiMethodId);
                }
                const rowData = response === null || response === void 0 ? void 0 : response.data;
                if (rowData) {
                    if (((_a = rowData === null || rowData === void 0 ? void 0 : rowData.pageList) === null || _a === void 0 ? void 0 : _a.length) > 0) {
                        params.successCallback(rowData.pageList, rowData.total);
                    }
                    else {
                        params.successCallback([], 0);
                    }
                }
                else {
                    params.successCallback([], 0);
                }
            }
        }
    };
};
//# sourceMappingURL=InquirySearchDatasource.js.map