/* eslint-disable @typescript-eslint/no-explicit-any */
import {
  FC,
  useCallback,
  useEffect,
  useLayoutEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { handleValidateCheck } from "@/widgetLibrary/PublicSector/InvalidMessage/utils";
import Autocomplete from "@mui/material/Autocomplete";
import { TextField } from "@mui/material";
import { formatSelectOptions } from "../SelectWidget/formSelectOptions";
import { isArray, isEmpty } from "lodash";
import { InvalidMessage } from "../PublicSector/InvalidMessage";

export const WrappedMultiSelect: FC<any> = (props) => {
  const {
    // showClear,
    value,
    options,
    placeholder,
    label,
    disabled,
    loading,
    readOnly,
    defaultValue,
    helperText,
    variant,
    required,
    handleUpdateMultiExecutionResult,
    handleOnChange,
    getValidateMessage,
    displayName,
  } = props;
  const [valueWithLabel, setValueWithLabel] = useState(defaultValue);
  const onChangeMultiSelectValue = useCallback(
    (paramValue: unknown) => {
      new Promise((resolve) => {
        const message = getValidateMessage(paramValue);
        handleUpdateMultiExecutionResult([
          {
            displayName,
            value: {
              value: paramValue || [],
              validateMessage: message,
            },
          },
        ]);
        resolve(true);
      }).then(() => {
        handleOnChange?.();
       
      });
    },
    [
      displayName,
      getValidateMessage,
      handleOnChange,
      handleUpdateMultiExecutionResult,
    ]
  );
  const valueWithLAbelSetter = useCallback(
    (value: any[]) => {
      if (!isEmpty(value) && isArray(value)) {    
        const actualValues = options.filter((e) => {
          return value.includes(e.value) || value.includes(e.label);
        });
        setValueWithLabel(actualValues);
      } else {
        setValueWithLabel([]);
      }
    },
    [options]
  );
  const getDefaultValueWithLabel = useCallback(
    (value: any) => {
      const updatedValue = options.filter((e) => {
        return value?.includes(e.value) || value?.includes(e.label);
      });
      return updatedValue;
    },
    [options]
  );
  useEffect(() => {
    if (Array.isArray(defaultValue)) {
      setValueWithLabel(getDefaultValueWithLabel(defaultValue));
    }
  }, [defaultValue, getDefaultValueWithLabel, options]);
  return (
    <div
      style={{
        paddingTop: variant === "outlined" ? "5px" : "none",
        width: "100%",
      }}
    >
      <Autocomplete
        fullWidth
        options={options}
        isOptionEqualToValue={()=>true}
        value={valueWithLabel}
        disabled={disabled}
        sx={{ fontSize: "6px", width: "100%" }}
        defaultValue={valueWithLabel}
        loading={loading}
        multiple={true}
        readOnly={readOnly}
        size="small"
        onChange={(_e, val) => {
          const multiOptions = val?.map((e) => {
            return e.value || [];
          });
          valueWithLAbelSetter(multiOptions);
          onChangeMultiSelectValue(multiOptions);
        }}
        renderInput={(params) => (
          <TextField
            {...params}
            size="small"
            placeholder={placeholder}
            label={label}
            variant={variant || "filled"}
            helperText={helperText}
            required={required}
          />
        )}
      />
    </div>
  );
};

WrappedMultiSelect.displayName = "WrappedMultiSelect";

export const MultiSelectWidget: FC<any> = (props) => {
  const {
    value,
    optionConfigureMode,
    mappedOption,
    manualOptions,
    handleUpdateDsl,
    updateComponentRuntimeProps,
    deleteComponentRuntimeProps,
    required,
    customRule,
    hideValidationMessage,
    dynamicHeight,
    updateComponentHeight,
    validateMessage,
    triggerEventHandler,
  } = props;
  const containerRef = useRef<HTMLDivElement | null>(null);
  const finalOptions = useMemo(() => {
    return formatSelectOptions(
      optionConfigureMode,
      manualOptions,
      mappedOption
    );
  }, [optionConfigureMode, manualOptions, mappedOption]);
  const getValidateMessage = useCallback(
    (value: unknown) => {
      if (!hideValidationMessage) {
        const message = handleValidateCheck({
          value,
          required,
          customRule,
        });
        const showMessage = message && message.length > 0;
        return showMessage ? message : "";
      }
      return "";
    },
    [customRule, hideValidationMessage, required]
  );
  const handleValidate = useCallback(
    (value: unknown) => {
      const message = getValidateMessage(value);
      handleUpdateDsl({
        validateMessage: message,
      });
      return message;
    },
    [getValidateMessage, handleUpdateDsl]
  );
  useEffect(() => {
    updateComponentRuntimeProps({
      setSelectedValue: (value: any) => {
        handleUpdateDsl({ value });
      },
      clearValue: () => {
        handleUpdateDsl({ value: undefined });
      },
      validate: () => {
        return handleValidate(value);
      },
      clearValidation: () => {},
    });
    return () => {
      deleteComponentRuntimeProps();
    };
  }, [
    updateComponentRuntimeProps,
    handleUpdateDsl,
    deleteComponentRuntimeProps,
    handleValidate,
    value,
  ]);
  const handleOnChange = useCallback(() => {
    triggerEventHandler("change");
  }, [triggerEventHandler]);

  const handleOnFocus = useCallback(() => {
    triggerEventHandler("focus");
  }, [triggerEventHandler]);

  const handleOnBlur = useCallback(() => {
    triggerEventHandler("blur");
  }, [triggerEventHandler]);
  const enableAutoHeight =
    dynamicHeight !== "fixed" && dynamicHeight != undefined;
  useLayoutEffect(() => {
    const containerDOM = containerRef.current;
    const observerRef = new ResizeObserver((entries) => {
      if (!updateComponentHeight) return;
      const height = entries[0].contentRect.height;
      updateComponentHeight?.(height);
    });
    if (observerRef && containerDOM && enableAutoHeight) {
      observerRef.unobserve(containerDOM);
      observerRef.observe(containerDOM);
    }

    return () => {
      if (containerDOM && enableAutoHeight) {
        observerRef.unobserve(containerDOM);
      }
    };
  }, [enableAutoHeight, updateComponentHeight]);
  return (
    <
    >
      <WrappedMultiSelect
        {...props}
        options={finalOptions}
        validateMessage={validateMessage}
        getValidateMessage={getValidateMessage}
        handleOnChange={handleOnChange}
        handleOnBlur={handleOnBlur}
        handleOnFocus={handleOnFocus}
      />
      {!hideValidationMessage && (
        <div>
          <InvalidMessage validateMessage={validateMessage} />
        </div>
      )}
    </>
  );
};

MultiSelectWidget.displayName = "MultiSelectWidget";
export default MultiSelectWidget;
