/* eslint-disable @typescript-eslint/no-explicit-any */
import { useState, useRef, useCallback, useEffect, useMemo } from "react";
import TextField from "@mui/material/TextField";
import InputAdornment from "@mui/material/InputAdornment";
import { InputWidgetProps } from "./interface";
import { InvalidMessage } from "@/widgetLibrary/PublicSector/InvalidMessage";
import { getValidateMessageFunc } from "./utils";
import { AutoHeightContainer } from "@/widgetLibrary/PublicSector/AutoHeightContainer";
import { debounce } from "lodash-es";
import { ButtonIcon } from "../IconWidget/utils";
import PhoneInput from "./PhoneInput";
import { getStyleMap } from "@/utils/getStyleMap";
import { useTheme } from "@mui/material";

export const InputWidget = (props: InputWidgetProps) => {
  const {
    isClassTrue = true,
    trueClasses = [],
    falseClasses = [],
    displayName,
    label,
    placeholder,
    variant,
    disabled,
    triggerEventHandler,
    type,
    startAdornmentIconName,
    endAdornmentIconName,
    required = false,
    size = "small",
    multiline = false,
    helperText = "",
    defaultValue,
    value,
    customRule,
    tooltipText,
    minLength,
    maxLength,
    pattern,
    error,
    regex,
    context,
    errorMessage,
    validateMessage,
    updateComponentRuntimeProps,
    deleteComponentRuntimeProps,
    handleUpdateDsl,
    hideValidationMessage,
    handleUpdateMultiExecutionResult,
  } = props;
  const theme = useTheme();
  const inputRef = useRef<HTMLInputElement>(null);
  const [inputValue, setInputValue] = useState(defaultValue);
  const val = useRef(defaultValue);
  useEffect(() => {
    setInputValue(defaultValue);
    handleUpdateMultiExecutionResult([
      {
        displayName,
        value: {
          value: defaultValue || "",
        },
      },
    ]);
  }, [defaultValue, displayName, handleUpdateMultiExecutionResult]);
  const handleValidate = useCallback(
    (value?: string) => {
      const message = getValidateMessageFunc(
        value,
        {
          hideValidationMessage: false,
          pattern: pattern,
          regex: regex,
          minLength: minLength,
          maxLength: maxLength,
          required: required,
        },
        displayName
      );

      val.current = value;
      handleUpdateDsl({
        validateMessage: message,
        defaultValue: value,
      });
      return message;
    },
    [
      displayName,
      handleUpdateDsl,
      maxLength,
      minLength,
      pattern,
      regex,
      required,
    ]
  );
  const renderAdornment = (position: any) => {
    const AdornmentComponent =
      position === "start"
        ? ButtonIcon(startAdornmentIconName)
        : ButtonIcon(endAdornmentIconName);
    return AdornmentComponent ? (
      <InputAdornment position={position}>{AdornmentComponent}</InputAdornment>
    ) : null;
  };
  const debounceOnChange = useRef(
    debounce(
      (
        value: string,
        triggerEventHandler: InputWidgetProps["triggerEventHandler"],
        options?: {
          hideValidationMessage?: InputWidgetProps["hideValidationMessage"];
          pattern?: InputWidgetProps["pattern"];
          regex?: InputWidgetProps["regex"];
          minLength?: InputWidgetProps["minLength"];
          maxLength?: InputWidgetProps["maxLength"];
          required?: InputWidgetProps["required"];
          customRule?: InputWidgetProps["customRule"];
        }
      ) => {
        new Promise((resolve) => {
          const message = getValidateMessageFunc(value, options, displayName);
          handleUpdateMultiExecutionResult([
            {
              displayName,
              value: {
                value: value || "",
                validateMessage: message,
              },
            },
          ]);
          resolve(true);
        }).then(() => {
          triggerEventHandler("change");
        });
      },
      180
    )
  );
  const handleOnChange = useCallback(
    (value: string) => {
      setInputValue(value);
      debounceOnChange.current(value, triggerEventHandler, {
        hideValidationMessage: hideValidationMessage,
        pattern: pattern,
        regex: regex,
        minLength: minLength,
        maxLength: maxLength,
        required: required,
        customRule: customRule,
      });
    },
    [
      customRule,
      hideValidationMessage,
      maxLength,
      minLength,
      pattern,
      regex,
      required,
      triggerEventHandler,
    ]
  );
  const clearValue = useCallback(() => {
    handleOnChange("");
  }, [handleOnChange]);
  useEffect(() => {
    updateComponentRuntimeProps({
      focus: () => {
        inputRef.current?.focus();
      },
      setValue: (value: boolean | string | number | void) => {
        if (typeof value === "string") {
          handleOnChange(value);
        }
      },
      clearValue: () => {
        clearValue();
      },
      validate: () => {
        return handleValidate(value);
      },
      clearValidation: () => {
        handleUpdateDsl({
          validateMessage: "",
        });
      },
    });

    return () => {
      deleteComponentRuntimeProps();
    };
  }, [
    clearValue,
    deleteComponentRuntimeProps,
    handleOnChange,
    handleUpdateDsl,
    handleValidate,
    updateComponentRuntimeProps,
    value,
  ]);
  const style = useMemo(() => {
    return getStyleMap(trueClasses, falseClasses, isClassTrue, context);
  }, [trueClasses, falseClasses, isClassTrue, context]);

  return (
    <div
      key={`${displayName}-wrapper`}
      style={{
        width: "100%",
        height: "100%",
        paddingTop: variant === "outlined" ? "8px" : "none",
      }}
    >
      {type === "phone_no" && (
        <PhoneInput
          value={inputValue}
          disabled={disabled}
          onChange={handleOnChange}
          style={style}
          required={required}
          title={tooltipText}
        />
      )}
      {(type === "text" || type === "number") && (
        <TextField
          // defaultValue={value}
          title={tooltipText}
          multiline={multiline}
          size={size}
          css={style}
          sx={{ color: theme.palette.text.primary }}
          ref={inputRef}
          key={displayName}
          error={error}
          label={label}
          value={inputValue}
          required={required}
          onChange={(e) => {
            handleOnChange(e.target.value);
          }}
          placeholder={placeholder}
          fullWidth
          variant={variant}
          disabled={disabled}
          // sx={styles}
          InputProps={{
            startAdornment: renderAdornment("start"),
            endAdornment: renderAdornment("end"),
          }}
          type={type}
          // color={color}
          helperText={helperText}
        />
      )}
      {!hideValidationMessage && (
        <InvalidMessage
          validateMessage={validateMessage && (errorMessage || validateMessage)}
        />
      )}
    </div>
  );
};

InputWidget.displayName = "InputWidget";
export default InputWidget;
