import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import {} from '@finos/legend-art';
import { PRIMITIVE_TYPE, V1_AppliedProperty, V1_CBoolean, V1_CDateTime, V1_CDecimal, V1_CFloat, V1_CInteger, V1_CLatestDate, V1_Collection, V1_CStrictDate, V1_CString, V1_EnumValue, V1_observe_AppliedProperty, V1_observe_ValueSpecification, V1_PackageableType, V1_PrimitiveValueSpecification, } from '@finos/legend-graph';
import { csvStringify, guaranteeNonNullable, guaranteeType, isNonNullable, } from '@finos/legend-shared';
import React, { forwardRef } from 'react';
import { BooleanPrimitiveInstanceValueEditor, CollectionValueInstanceValueEditor, DateInstanceValueEditor, EnumInstanceValueEditor, NumberPrimitiveInstanceValueEditor, StringPrimitiveInstanceValueEditor, } from './BasicValueSpecificationEditor.js';
import { V1_AppliedProperty_setProperty, V1_Collection_setValues, V1_PrimitiveValue_setValue, } from '../../stores/shared/V1_ValueSpecificationModifierHelper.js';
import { buildV1PureAdjustDateFunction, buildV1PureDateFunctionExpression, CustomDateOption, CustomFirstDayOfOption, CustomPreviousDayOfWeekOption, DatePickerOption, } from './CustomDatePickerHelper.js';
import { _elementPtr, _primitiveValue, _property, isPrimitiveType, } from '@finos/legend-data-cube';
import { V1_stringifyValueSpecification, isValidV1_ValueSpecification, } from '../../stores/shared/V1_ValueSpecificationEditorHelper.js';
import { useApplicationStore } from '@finos/legend-application';
// Placeholder for unsupported value specifications
const V1_UnsupportedValueSpecificationEditor = (props) => (_jsxs("div", { className: "value-spec-editor--unsupported", children: ["Unsupported V1 type: ", props.type] }));
// Helper functions for collection values
const V1_stringifyValue = (values) => {
    if (values.length === 0) {
        return '';
    }
    return csvStringify([
        values
            .map((val) => {
            if (val instanceof V1_PrimitiveValueSpecification) {
                if (!(val instanceof V1_CLatestDate)) {
                    return val.value;
                }
                else {
                    return val;
                }
            }
            else if (val instanceof V1_EnumValue) {
                return val.value;
            }
            else if (val instanceof V1_AppliedProperty) {
                return val.property;
            }
            return undefined;
        })
            .filter(isNonNullable),
    ]).trim();
};
// Main component
export const V1_BasicValueSpecificationEditor = forwardRef(function V1_BasicValueSpecificationEditor(props, ref) {
    const { className, valueSpecification, multiplicity, typeCheckOption, setValueSpecification, resetValue, handleBlur, handleKeyDown, enumeration, selectorConfig, lightMode, readOnly, } = props;
    const applicationStore = useApplicationStore();
    const errorChecker = (_valueSpecification) => !isValidV1_ValueSpecification(_valueSpecification, multiplicity);
    // Handle non-collection editors
    if (multiplicity.upperBound !== undefined) {
        if (typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.STRING) {
            return (_jsx(StringPrimitiveInstanceValueEditor, { valueSpecification: guaranteeType(valueSpecification, V1_CString), valueSelector: (val) => val.value, updateValueSpecification: (_valueSpecification, value) => {
                    V1_PrimitiveValue_setValue(_valueSpecification, value ?? '');
                    setValueSpecification(_valueSpecification);
                }, className: className, resetValue: resetValue, ref: ref, handleBlur: handleBlur, handleKeyDown: handleKeyDown, errorChecker: errorChecker, selectorConfig: selectorConfig, lightMode: lightMode, readOnly: readOnly }));
        }
        else if (typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.BOOLEAN) {
            return (_jsx(BooleanPrimitiveInstanceValueEditor, { valueSpecification: guaranteeType(valueSpecification, V1_CBoolean), valueSelector: (val) => val.value, updateValueSpecification: (_valueSpecification, value) => {
                    V1_PrimitiveValue_setValue(_valueSpecification, value);
                    setValueSpecification(_valueSpecification);
                }, className: className, resetValue: resetValue, readOnly: readOnly }));
        }
        else if (typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.BINARY ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.BYTE ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.DECIMAL ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.FLOAT ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.INTEGER ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.NUMBER) {
            const numericValueSpecification = typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.INTEGER
                ? guaranteeType(valueSpecification, V1_CInteger)
                : typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.DECIMAL
                    ? guaranteeType(valueSpecification, V1_CDecimal)
                    : guaranteeType(valueSpecification, V1_CFloat);
            return (_jsx(NumberPrimitiveInstanceValueEditor, { valueSpecification: numericValueSpecification, valueSelector: (val) => val.value, isInteger: valueSpecification instanceof V1_CInteger, updateValueSpecification: (_valueSpecification, value) => {
                    V1_PrimitiveValue_setValue(_valueSpecification, value);
                    setValueSpecification(_valueSpecification);
                }, className: className, resetValue: resetValue, ref: ref, handleBlur: handleBlur, handleKeyDown: handleKeyDown, errorChecker: errorChecker, readOnly: readOnly }));
        }
        else if (typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.DATE ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.STRICTDATE ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.DATETIME ||
            typeCheckOption.expectedType.fullPath === PRIMITIVE_TYPE.LATESTDATE) {
            const dateValueSelector = (_valueSpecification) => _valueSpecification instanceof V1_CDateTime ||
                _valueSpecification instanceof V1_CStrictDate ||
                _valueSpecification instanceof V1_CString
                ? _valueSpecification.value
                : '';
            const dateUpdateValueSpecification = (_valueSpecification, value, options) => {
                if (value instanceof CustomDateOption) {
                    setValueSpecification(buildV1PureAdjustDateFunction(value));
                }
                else if (value instanceof CustomFirstDayOfOption) {
                    setValueSpecification(buildV1PureDateFunctionExpression(value));
                }
                else if (value instanceof CustomPreviousDayOfWeekOption) {
                    setValueSpecification(buildV1PureDateFunctionExpression(value));
                }
                else if (value instanceof DatePickerOption) {
                    setValueSpecification(buildV1PureDateFunctionExpression(value));
                }
                else {
                    const _type = guaranteeNonNullable(options?.primitiveTypeEnum);
                    setValueSpecification(_primitiveValue(_type, value));
                }
            };
            return (_jsx(DateInstanceValueEditor, { valueSpecification: valueSpecification, valueSelector: dateValueSelector, updateValueSpecification: dateUpdateValueSpecification, typeCheckOption: typeCheckOption, resetValue: resetValue, className: className, errorChecker: errorChecker, readOnly: readOnly }));
        }
        // Enum editors should have enumeration passed in the props
        if (enumeration) {
            const options = enumeration.values.map((enumValue) => ({
                label: enumValue.value,
                value: enumValue.value,
            }));
            return (_jsx(EnumInstanceValueEditor, { valueSpecification: guaranteeType(valueSpecification, V1_AppliedProperty), valueSelector: (val) => val.property, options: options, className: className, resetValue: resetValue, updateValueSpecification: (_valueSpecification, value) => {
                    V1_AppliedProperty_setProperty(_valueSpecification, guaranteeNonNullable(value));
                    setValueSpecification(_valueSpecification);
                }, handleBlur: handleBlur, errorChecker: errorChecker, selectorConfig: selectorConfig, lightMode: lightMode, readOnly: readOnly }));
        }
    }
    else {
        // Handle collection editors
        const collectionValueSpecification = guaranteeType(valueSpecification, V1_Collection);
        const updateValueSpecification = (_collectionValueSpecification, valueSpecifications) => {
            V1_Collection_setValues(_collectionValueSpecification, valueSpecifications);
            setValueSpecification(_collectionValueSpecification);
        };
        const stringifyCollectionValueSpecification = (_collectionValueSpecification) => {
            return V1_stringifyValue(_collectionValueSpecification.values);
        };
        const convertValueSpecificationToText = (_valueSpecification) => {
            return V1_stringifyValueSpecification(_valueSpecification, applicationStore);
        };
        const convertTextToValueSpecification = (_type, text) => {
            const packageableType = guaranteeType(_type, V1_PackageableType, 'Cannot convert text to V1_ValueSpecification. Expected type to be a V1_PackageableType');
            if (isPrimitiveType(packageableType.fullPath)) {
                const primitiveVal = _primitiveValue(packageableType.fullPath, text, true);
                return V1_observe_ValueSpecification(primitiveVal);
            }
            else {
                // If not a primitive, assume it is an enum
                const typeParam = _elementPtr(packageableType.fullPath);
                return V1_observe_AppliedProperty(_property(text, [typeParam]));
            }
        };
        const enumOptions = enumeration?.values.map((enumValue) => ({
            label: enumValue.value,
            value: enumValue.value,
        }));
        return (_jsx(CollectionValueInstanceValueEditor, { valueSpecification: collectionValueSpecification, updateValueSpecification: updateValueSpecification, expectedType: typeCheckOption.expectedType, stringifyCollectionValueSpecification: stringifyCollectionValueSpecification, convertValueSpecificationToText: convertValueSpecificationToText, convertTextToValueSpecification: convertTextToValueSpecification, enumOptions: enumOptions, errorChecker: errorChecker, className: className, selectorConfig: selectorConfig, lightMode: lightMode, readOnly: readOnly }));
    }
    // Default case for unsupported value specifications
    return (_jsx(V1_UnsupportedValueSpecificationEditor, { type: typeCheckOption.expectedType.fullPath }));
});
//# sourceMappingURL=V1_BasicValueSpecificationEditor.js.map