import React, { useMemo, useCallback, useEffect } from 'react';
import { makeStyles, Divider, Typography } from '@material-ui/core';
import { FluentTextFieldAutoComplete } from '../../UI/inputs/textField/FluentTextFieldAutoComplete';
import { SearchOperators } from '../../models/SearchOperator.ts';
import clsx from 'clsx';
import { v4 as uuid } from 'uuid';
import { PropertyTypeEnum } from '../../enums/propertyTypeEnums.ts';
import { PropertyField } from '../../UI/property/PropertyFields';
import { LookupTypeEnums } from '../../enums/unitySystemEnums.ts';
import { csvStrToArrayOfObjects } from '../../utilities/input/SelectUtilities';
import { useForm } from 'react-final-form';
const useStyles = makeStyles((theme) => ({
    root: {
        marginRight: theme.spacing(1),
        marginLeft: theme.spacing(1),
        overflowX: 'auto'
    },
    fieldRow: { display: 'flex', alignItems: 'center' },
    dividerContainer: {
        display: 'flex',
        justifyContent: 'space-between',
        alignItems: 'center',
        width: '100%'
    },
    divider: { width: '100%', marginTop: theme.spacing(1) },
    autocompleteRoot: {
        width: '38%',
        marginRight: theme.spacing(1)
    }
}));
export const InquiryAdvancedSearchForm = (props) => {
    const { advancedSearchFields, selectedSearchOperators, setSelectedSearchOperators, catalogProperties, entityType, lookupPropertyNames, classes: classProps, executeQueryWithParameters, setForm } = props;
    const { root } = classProps || {};
    const classes = useStyles();
    const form = useForm();
    const handleSearchOperatorChange = useCallback((value, fieldName) => {
        if (fieldName) {
            let updatedSelectedSearchOps = {};
            if (selectedSearchOperators) {
                updatedSelectedSearchOps = Object.assign({}, selectedSearchOperators);
            }
            updatedSelectedSearchOps[fieldName] = value;
            setSelectedSearchOperators(updatedSelectedSearchOps);
        }
    }, [selectedSearchOperators, setSelectedSearchOperators]);
    const getPropertyWidgetType = (type, useLookup) => {
        if (!type) {
            return null;
        }
        let propertyWidgetType = '';
        switch (type) {
            case PropertyTypeEnum.Int:
            case PropertyTypeEnum.Long:
                propertyWidgetType = 'IntegerWidget';
                break;
            case PropertyTypeEnum.DateTime:
                propertyWidgetType = 'DateTimeWidget';
                break;
            case PropertyTypeEnum.Boolean:
                propertyWidgetType = 'BooleanWidget';
                break;
            default:
                propertyWidgetType = 'TextWidget';
        }
        if (useLookup === LookupTypeEnums.Api ||
            useLookup === LookupTypeEnums.Csv) {
            propertyWidgetType = 'AutoCompleteWidget';
        }
        return propertyWidgetType;
    };
    const getPropertyTypeSearchOperators = useCallback((type) => {
        if (!type) {
            return [];
        }
        switch (type) {
            case PropertyTypeEnum.Boolean:
                return SearchOperators.filter((operator) => operator.value === '=');
            default:
                return SearchOperators;
        }
    }, []);
    const fieldRows = useMemo(() => {
        if (!advancedSearchFields || !catalogProperties) {
            return [];
        }
        const keys = Object.keys(advancedSearchFields);
        const arrayOfFields = keys.reduce((list, key) => {
            const groupedItems = advancedSearchFields[key];
            let groupHeader = '';
            const foundGroupItem = groupedItems.find((item) => !!item.groupHeader);
            if (foundGroupItem) {
                groupHeader = foundGroupItem.groupHeader;
            }
            list.push({ groupHeader: groupHeader, isDivider: true, id: uuid() });
            groupedItems.forEach(async (item) => {
                var _a, _b, _c, _d, _e;
                const foundProperty = catalogProperties.find((property) => property.name === item.name);
                const propertyWidgetType = getPropertyWidgetType(foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.type, (_a = foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.extendedProperties) === null || _a === void 0 ? void 0 : _a.useLookup);
                let apiLookupOptions = null;
                if (!item.searchable &&
                    !((_b = foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.extendedProperties) === null || _b === void 0 ? void 0 : _b.searchable)) {
                    return;
                }
                if (lookupPropertyNames.includes(foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.name) &&
                    ((_c = foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.extendedProperties) === null || _c === void 0 ? void 0 : _c.useLookup) === LookupTypeEnums.Api) {
                    // TODO: handle getting lookup data with api call
                    // const response = await executeQueryWithParameters(
                    //   'aa5d1fe1-1128-4d08-9ddb-58ad4fcf00e4'
                    // );
                    // console.log(response?.data);
                }
                list.push(Object.assign(Object.assign({}, item), { isDivider: false, type: foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.type, propertyWidgetType: propertyWidgetType, useLookup: (_d = foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.extendedProperties) === null || _d === void 0 ? void 0 : _d.useLookup, lookup: (_e = foundProperty === null || foundProperty === void 0 ? void 0 : foundProperty.extendedProperties) === null || _e === void 0 ? void 0 : _e.lookup, apiLookupOptions: apiLookupOptions }));
            });
            return list;
        }, []);
        return arrayOfFields;
    }, [advancedSearchFields, catalogProperties, lookupPropertyNames]);
    const getPropertyFields = useCallback((config) => {
        var _a;
        const searchOperator = selectedSearchOperators
            ? (_a = selectedSearchOperators[config === null || config === void 0 ? void 0 : config.name]) === null || _a === void 0 ? void 0 : _a.value
            : null;
        let options = [];
        if ((config === null || config === void 0 ? void 0 : config.useLookup) === LookupTypeEnums.Csv) {
            options = csvStrToArrayOfObjects(config === null || config === void 0 ? void 0 : config.lookup);
        }
        if (searchOperator === 'BETWEEN') {
            return (React.createElement("div", { style: { display: 'block', width: '100%' } }, React.createElement(PropertyField, { propertyType: entityType, property: {
                    key: config === null || config === void 0 ? void 0 : config.name,
                    label: `${config === null || config === void 0 ? void 0 : config.columnName} (From)`,
                    type: config === null || config === void 0 ? void 0 : config.propertyWidgetType,
                    options: options || [],
                    valueName: 'value'
                } }), React.createElement(PropertyField, { propertyType: entityType, property: {
                    key: `${config === null || config === void 0 ? void 0 : config.name}:between`,
                    label: `${config === null || config === void 0 ? void 0 : config.columnName} (To)`,
                    type: config === null || config === void 0 ? void 0 : config.propertyWidgetType,
                    options: options || [],
                    valueName: 'value'
                } })));
        }
        return (React.createElement(PropertyField, { propertyType: entityType, property: {
                key: config === null || config === void 0 ? void 0 : config.name,
                label: config === null || config === void 0 ? void 0 : config.columnName,
                type: config === null || config === void 0 ? void 0 : config.propertyWidgetType,
                options: options || [],
                valueName: 'value'
            } }));
    }, [entityType, selectedSearchOperators]);
    const fieldComponents = useMemo(() => {
        if (!fieldRows || !fieldRows.length) {
            return null;
        }
        return fieldRows.map((config) => {
            return (React.createElement("div", { key: config === null || config === void 0 ? void 0 : config.id }, !(config === null || config === void 0 ? void 0 : config.isDivider) && (React.createElement("div", { className: classes.fieldRow }, React.createElement(FluentTextFieldAutoComplete, { id: "udpRecord-InquiryAdvancedSearchForm-Text", udprecordid: "udpRecord-InquiryAdvancedSearchForm-Text", label: "Operator", name: "searchOperator", variant: "outlined", margin: "dense", size: "small", options: getPropertyTypeSearchOperators(config === null || config === void 0 ? void 0 : config.type) || [], optionKey: "label", value: (selectedSearchOperators &&
                    selectedSearchOperators[config === null || config === void 0 ? void 0 : config.name]) ||
                    '', onChange: (value) => handleSearchOperatorChange(value, config === null || config === void 0 ? void 0 : config.name), classes: { autocompleteRoot: classes.autocompleteRoot } }), getPropertyFields(config))), (config === null || config === void 0 ? void 0 : config.isDivider) && (React.createElement("div", { className: classes.dividerContainer }, React.createElement("div", { className: classes.divider }, React.createElement(Divider, { orientation: "horizontal" })), (config === null || config === void 0 ? void 0 : config.groupHeader) && (React.createElement("div", { style: {
                    marginRight: 8,
                    marginLeft: 8,
                    textAlign: 'center',
                    whiteSpace: 'nowrap'
                } }, React.createElement(Typography, { variant: "caption" }, config === null || config === void 0 ? void 0 : config.groupHeader))), React.createElement("div", { className: classes.divider }, React.createElement(Divider, { orientation: "horizontal" }))))));
        });
    }, [
        fieldRows,
        classes,
        handleSearchOperatorChange,
        selectedSearchOperators,
        getPropertyTypeSearchOperators,
        getPropertyFields
    ]);
    useEffect(() => {
        if (form) {
            setForm(form);
        }
    }, [form, setForm]);
    return React.createElement("div", { className: clsx(classes.root, root) }, fieldComponents);
};
//# sourceMappingURL=InquiryAdvancedSearchForm.js.map