import { FormControlLabel, TextField } from '@material-ui/core';
import React, { useCallback } from 'react';
import { apiMutate } from '../utilities/useAxiosMutate';
import { DateTimeField } from '../UI/inputs/datetimes/DateTimeField';
import { Field } from '../utilities/form';
import { FluentTextFieldAutoComplete } from '../UI/inputs/textField/FluentTextFieldAutoComplete';
import { FluentToggle } from '../UI/inputs/toggle/FluentToggle';
import { PropertyTypeEnum } from '../enums/propertyTypeEnums';
import { InputFieldType } from '../enums/InputFieldTypeEnums';
import { toLowerFirstChar } from '../utilities/input/StringUtilities';
import { toTitleCase } from '../utilities/input/StringUtilities';
import { FluentColorPicker } from '../UI/inputs/pickers/FluentColorPicker';
import { getSanitizedName } from '../utilities/entities/entityUtilities';
import { ConfigService } from '../configService';
export function useCrudActions() {
    const renderInputByForeignKey = useCallback((foreignKeyData, setFkData, crudTableFormData, schemaAttribute, index, isNewEntry, entityData, label = '', manyToManyPropertyList = new Set()) => {
        var _a;
        const foreignKeyAttributeName = toLowerFirstChar(schemaAttribute.name);
        if (!foreignKeyData) {
            return;
        }
        let attributeData = (_a = foreignKeyData.find((fkd) => fkd.fieldName === foreignKeyAttributeName)) === null || _a === void 0 ? void 0 : _a.data;
        //This onChange is trying to prevent duplicate entries but does not consider a 3 way many to many
        // const onChange = (value) => {
        //   let newFKData = [...foreignKeyData];
        //   const fieldName = schemaAttribute.name;
        //   const existingEntityData = [...entityData].filter(
        //     (ed) => ed[fieldName] === value?.id
        //   );
        //   if (manyToManyPropertyList.has(fieldName?.toLowerCase())) {
        //     newFKData.forEach((fkd) => {
        //       // omit comparing selected entity
        //       if (fkd.fieldName !== fieldName) {
        //         // compare existing data and remove any used options
        //         existingEntityData.forEach((eData) => {
        //           fkd.data = fkd.data.filter(
        //             (data) => data.id !== eData[fkd.fieldName]
        //           );
        //         });
        //       }
        //     });
        //   }
        //   setFkData && setFkData(newFKData);
        // };
        return ((!schemaAttribute.extendedProperties.identifier || isNewEntry) && (React.createElement(Field, { component: FluentTextFieldAutoComplete, id: `${schemaAttribute.name}${index}`, initialValue: attributeData
                ? attributeData.find((d) => d.id === crudTableFormData[foreignKeyAttributeName])
                : 0, label: toTitleCase(label), name: foreignKeyAttributeName, fullWidth: true, variant: "outlined", margin: "normal", options: attributeData || [], optionKey: 'name', required: !(schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.nullable), style: { marginTop: 8 }, 
            //additionalOnChangeAction={onChange}
            disabled: schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.disabled })));
    }, []);
    const renderInputByFieldType = useCallback((schemaAttribute, index, attributes, fieldInfo, foreignKeyData, setFkData, crudTableFormData, classes, isNewEntry, entityData, manyToManyPropertyList) => {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
        const NUMBER_TYPE = [
            PropertyTypeEnum.Int,
            PropertyTypeEnum.Long,
            PropertyTypeEnum.Double
        ];
        //dont render clusterId
        if ((schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.name) === 'clusterId') {
            return;
        }
        //Get list of child entities
        const ceAttributes = attributes.filter((ea) => ea.extendedProperties.childEntity);
        //If bool field not set, set to false
        if (schemaAttribute.type === 'bool' &&
            crudTableFormData[toLowerFirstChar(schemaAttribute.name)] === '') {
            crudTableFormData[toLowerFirstChar(schemaAttribute.name)] = false;
        }
        //finding if any child entity
        const attribute = ceAttributes.find((ceAttr) => {
            var _a;
            return Object.keys(((_a = ceAttr === null || ceAttr === void 0 ? void 0 : ceAttr.extendedProperties) === null || _a === void 0 ? void 0 : _a.childEntityAssoc) || {})
                .length &&
                ceAttr.extendedProperties.childEntityAssoc.Keys.find((a) => {
                    const fieldId = a.split(',')[0];
                    return ((/^[A-Z]*$/.test(fieldId)
                        ? fieldId.toLowerCase()
                        : toLowerFirstChar(fieldId)) ===
                        toLowerFirstChar(schemaAttribute.name));
                });
        });
        //If schemaAttribute is used as a foreign key, render field as foreign field
        //schemaAttribute must be a foreign key to another table and if its manytomany, it has to be the joining table. No one to many
        if (((schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.isForeignKey) || attribute) &&
            !(!((_b = (_a = attribute === null || attribute === void 0 ? void 0 : attribute.extendedProperties) === null || _a === void 0 ? void 0 : _a.childEntityAssoc) === null || _b === void 0 ? void 0 : _b.IsJoiningObject) &&
                ((_d = (_c = attribute === null || attribute === void 0 ? void 0 : attribute.extendedProperties) === null || _c === void 0 ? void 0 : _c.childEntityAssoc) === null || _d === void 0 ? void 0 : _d.Cardinality) === 2) &&
            ((_f = (_e = attribute === null || attribute === void 0 ? void 0 : attribute.extendedProperties) === null || _e === void 0 ? void 0 : _e.childEntityAssoc) === null || _f === void 0 ? void 0 : _f.Cardinality) !== 3) {
            const label = ((_g = fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.properties) === null || _g === void 0 ? void 0 : _g.displayName)
                ? fieldInfo.properties.displayName
                : (attribute === null || attribute === void 0 ? void 0 : attribute.reference)
                    ? getSanitizedName(attribute.reference)
                    : '';
            console.log(label);
            return renderInputByForeignKey(foreignKeyData, setFkData, crudTableFormData, schemaAttribute, index, isNewEntry, entityData, label, manyToManyPropertyList);
        }
        const maintainenceConfig = (_h = fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.properties) === null || _h === void 0 ? void 0 : _h.maintainenceConfig;
        const displayLabel = toTitleCase(((_j = fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.properties) === null || _j === void 0 ? void 0 : _j.displayName) || schemaAttribute.name);
        const defaultFieldType = schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.type;
        const disabled = (schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.disabled) ||
            (maintainenceConfig === null || maintainenceConfig === void 0 ? void 0 : maintainenceConfig.readOnly) ||
            ((_k = schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.extendedProperties) === null || _k === void 0 ? void 0 : _k.readOnly);
        let fieldIsNumberType = (maintainenceConfig === null || maintainenceConfig === void 0 ? void 0 : maintainenceConfig.renderAs) === InputFieldType.Number;
        const required = !(schemaAttribute === null || schemaAttribute === void 0 ? void 0 : schemaAttribute.nullable) ||
            ((fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.isPrimaryKey) && !disabled) ||
            disabled;
        const DefaultTextField = (React.createElement(Field, { component: TextField, id: `${schemaAttribute.name}${index}`, name: toLowerFirstChar(schemaAttribute.name), label: displayLabel, initialValue: crudTableFormData[toLowerFirstChar(schemaAttribute.name)] !== null
                ? crudTableFormData[toLowerFirstChar(schemaAttribute.name)]
                : '', type: fieldIsNumberType && 'number', fullWidth: true, variant: "outlined", size: "small", required: required, margin: "dense", InputProps: {
                classes: {
                    root: classes === null || classes === void 0 ? void 0 : classes.input,
                    input: classes === null || classes === void 0 ? void 0 : classes.formTextInput
                }
            }, inputProps: {
                udprecordid: `udpRecord-crudActions-${schemaAttribute.name}${index}`
            }, InputLabelProps: {
                classes: {
                    root: classes === null || classes === void 0 ? void 0 : classes.labelRoot
                }
            }, disabled: disabled }));
        const DefaultFluentToggle = (React.createElement(FormControlLabel, { control: React.createElement(Field, { component: FluentToggle, type: "checkbox", id: `${schemaAttribute.name}${index}`, disabled: disabled, classes: { root: classes === null || classes === void 0 ? void 0 : classes.switchRoot }, name: toLowerFirstChar(schemaAttribute.name), color: "secondary", inputProps: { 'aria-label': 'Active condition' }, initialValue: typeof crudTableFormData[toLowerFirstChar(schemaAttribute.name)] === 'boolean'
                    ? crudTableFormData[toLowerFirstChar(schemaAttribute.name)]
                    : crudTableFormData[toLowerFirstChar(schemaAttribute.name)] === 'true'
                        ? true
                        : false }), label: displayLabel, labelPlacement: "start", style: { marginLeft: 4 } }));
        const DefaultFluentDatePicker = (React.createElement(Field, { disabled: disabled, component: DateTimeField, id: `${schemaAttribute.name}${index}`, name: toLowerFirstChar(schemaAttribute.name), label: displayLabel, initialValue: crudTableFormData[toLowerFirstChar(schemaAttribute.name)]
                ? new Date(crudTableFormData[toLowerFirstChar(schemaAttribute.name)])
                : '', fullWidth: true, variant: "outlined", size: "small", required: required, style: { marginTop: 8 } }));
        const DefaultFluentColorPicker = (React.createElement(FormControlLabel, { control: React.createElement(Field, { component: FluentColorPicker, id: `${schemaAttribute.name}${index}`, name: toLowerFirstChar(schemaAttribute.name), initialValue: crudTableFormData[toLowerFirstChar(schemaAttribute.name)] || '', fullWidth: true, variant: "outlined", size: "small", required: required, margin: "dense", InputProps: {
                    classes: {
                        root: classes === null || classes === void 0 ? void 0 : classes.input,
                        input: classes === null || classes === void 0 ? void 0 : classes.formTextInput
                    }
                }, InputLabelProps: {
                    classes: {
                        root: classes === null || classes === void 0 ? void 0 : classes.labelRoot
                    }
                }, disabled: disabled }), label: displayLabel, labelPlacement: "start", style: { marginLeft: 4 } }));
        if (maintainenceConfig === null || maintainenceConfig === void 0 ? void 0 : maintainenceConfig.hiddenForm)
            return null;
        switch (maintainenceConfig === null || maintainenceConfig === void 0 ? void 0 : maintainenceConfig.renderAs) {
            case InputFieldType.Text:
            case InputFieldType.Number:
                return DefaultTextField;
            case InputFieldType.Toggle:
                return DefaultFluentToggle;
            case InputFieldType.DateTime:
                return DefaultFluentDatePicker;
            case InputFieldType.ColorPicker:
                return DefaultFluentColorPicker;
            case InputFieldType.Default:
            default:
                fieldIsNumberType = NUMBER_TYPE.includes(defaultFieldType);
                switch (defaultFieldType) {
                    case PropertyTypeEnum.Int:
                    case PropertyTypeEnum.Long:
                    case PropertyTypeEnum.Double:
                    case PropertyTypeEnum.String:
                    case PropertyTypeEnum.String_Uuid:
                        return DefaultTextField;
                    case PropertyTypeEnum.Boolean:
                        return DefaultFluentToggle;
                    case PropertyTypeEnum.DateTime:
                        return DefaultFluentDatePicker;
                    default:
                        return null;
                }
        }
    }, [renderInputByForeignKey]);
    const getFKData = useCallback(async (fkMethods, setForeignKeyData, enqueueSnackbar, displayToasts) => {
        let fkData = [];
        let promises = [];
        let promiseDetails = [];
        fkMethods.forEach((method) => {
            var _a, _b, _c, _d, _e;
            if (method && ((_a = method === null || method === void 0 ? void 0 : method.entity) === null || _a === void 0 ? void 0 : _a.unityBaseGetAllMethod)) {
                promiseDetails.push({
                    url: ConfigService.integrationV1ApiUrl +
                        `/apimethod/executeQueryWithParameters/${(_c = (_b = method === null || method === void 0 ? void 0 : method.entity) === null || _b === void 0 ? void 0 : _b.unityBaseGetAllMethod) === null || _c === void 0 ? void 0 : _c.apiMethodId}`,
                    fieldName: method.fkName,
                    name: method.entity.entityName
                });
                promises.push(apiMutate(ConfigService.integrationV1ApiUrl, `apimethod/executeQueryWithParameters/${(_e = (_d = method === null || method === void 0 ? void 0 : method.entity) === null || _d === void 0 ? void 0 : _d.unityBaseGetAllMethod) === null || _e === void 0 ? void 0 : _e.apiMethodId}`, {
                    method: 'post'
                }, { data: {} }));
            }
            else {
                if (displayToasts) {
                    enqueueSnackbar(`${method.entity.entityName}'s Get-All method needs to be promoted`, {
                        variant: 'error',
                        anchorOrigin: {
                            vertical: 'top',
                            horizontal: 'center'
                        }
                    });
                }
                else {
                    console.warn(`${method.entity.entityName}'s Get-All method needs to be promoted`);
                }
            }
        });
        Promise.all(promises).then((resp) => {
            resp.forEach((response, index) => {
                if (response.status === 200) {
                    if (response === null || response === void 0 ? void 0 : response.data) {
                        let respData = [];
                        response.data.forEach((d) => {
                            var _a;
                            respData.push({ id: d.id, name: (_a = d.name) !== null && _a !== void 0 ? _a : d.id });
                        });
                        const promiseDetail = promiseDetails.find((p) => {
                            var _a;
                            return p.url === ((_a = response === null || response === void 0 ? void 0 : response.config) === null || _a === void 0 ? void 0 : _a.url);
                        });
                        fkData.push({
                            fieldName: promiseDetail.fieldName,
                            name: promiseDetail.fieldName,
                            data: respData
                        });
                    }
                }
            });
            setForeignKeyData(fkData);
        });
    }, []);
    return {
        renderInputByForeignKey,
        renderInputByFieldType,
        getFKData
    };
}
//# sourceMappingURL=crudActions.js.map