import React, { ComponentProps, CSSProperties, useEffect, useState } from 'react';
import classNames from 'clsx';
import type { TypographyVariant } from '@mui/material';

import { SIZE_MEDIUM } from '@/mui/constants';

import { getInputStyleCssVariables, useInputStyles } from '../helpers';

import Autocomplete from '../../../Autocomplete/Autocomplete';
import TextField from '../../../TextField/TextField';

import styles from './Autocomplete.module.scss';

type Props = ComponentProps<typeof Autocomplete> & {
  readOnly?: boolean;
  editable?: boolean;
  placeholder?: string;
  variant: TypographyVariant;
  fontWeight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
  error?: boolean;
  helperText?: string;
};

function InlineEditAutocomplete({
  disabled,
  readOnly,
  editable,
  placeholder,
  variant,
  fontWeight,
  error,
  helperText,
  options,
  optionLabelKey,
  optionValueKey,
  onOpen,
  onClose,
  onInputChange,
  ...props
}: Props) {
  const canBeEdit = !disabled && !readOnly;
  const [stateEditable, setEditState] = useState(editable && canBeEdit);
  const [symbols, setSymbols] = useState(placeholder?.length || 0);
  const { fontSize, fontWeight: stateFontWeight, lineHeight, letterSpacing } = useInputStyles(variant, fontWeight);

  useEffect(() => setEditState(editable && canBeEdit), [disabled, editable, readOnly]);

  const style = {
    ...getInputStyleCssVariables(fontSize, stateFontWeight, lineHeight, letterSpacing),
    '--internal-min-symbols': !stateEditable ? `${symbols}ch` : 'auto',
  } as CSSProperties;

  return (
    <Autocomplete
      fullWidth={false}
      disabled={disabled}
      readOnly={readOnly}
      options={options}
      optionLabelKey={optionLabelKey}
      optionValueKey={optionValueKey}
      {...props}
      size="medium"
      style={style}
      classes={{
        root: styles.TextFieldWrapper,
        inputRoot: styles.TextFieldInputWrapper,
        endAdornment: styles.EndAdornment,
        clearIndicator: styles.ActionButton,
        popupIndicator: styles.ActionButton,
      }}
      blurOnSelect
      onOpen={(...args) => {
        if (canBeEdit) {
          if (onOpen) {
            onOpen(...args);
          }
          setEditState(true);
        }
      }}
      onClose={(...args) => {
        if (onClose) {
          onClose(...args);
        }
        setEditState(false);
      }}
      onInputChange={(event, newValue, reason) => {
        setSymbols(newValue.length || placeholder?.length || 0);
        if (onInputChange) {
          onInputChange(event, newValue, reason);
        }
      }}
      renderInput={(params) => (
        <TextField
          {...params}
          error={error}
          helperText={helperText}
          InputProps={{
            ...params.InputProps,
            size: SIZE_MEDIUM,
            classes: {
              root: classNames(styles.InputRoot, {
                [styles.InputRoot___readOnly]: !canBeEdit,
                [styles.InputRoot___view]: !stateEditable,
              }),
              input: styles.Input,
            },
            endAdornment: stateEditable ? params.InputProps.endAdornment : null,
          }}
          placeholder={placeholder}
          size="medium"
          variant="filled"
        />
      )}
    />
  );
}

export default InlineEditAutocomplete;
