import { Dispatch, bindActionCreators } from 'redux';
import { FormEditorAction } from './types';
import { connect } from 'react-redux';
import { nanoid } from '@reduxjs/toolkit';
import { useRef } from 'react';
import React, { useState } from 'react';

type TextFieldProps = ReturnType<typeof mapDispatchToProps> & {
  currentValue?: string;
  validate: (value: string) => boolean;
  setValue: (value: string) => void;
  label: string;
  autoFocus?: boolean;
  onBlur?: () => void;
  labelPosition?: 'top' | 'side';
  isHint?: boolean;
  isDefault?: boolean;
  disabled?: boolean;
  isTextArea?: boolean;
};

const TextField: React.FC<TextFieldProps> = (props) => {
  const { validate, setValue, label, autoFocus, disabled, isTextArea } = props;
  const labelPosition = props.labelPosition ?? 'top';
  const currentValue = props.currentValue ?? '';

  function onBlur() {
    processChanges();
    if (props.onBlur) {
      props.onBlur();
    }
  }
  function processChanges() {
    const trimmedInput = inputEl.current.value.trim();
    if (!validate(trimmedInput)) {
      inputEl.current.value = currentValue;
      return;
    }
    if (trimmedInput !== currentValue) {
      setValue(trimmedInput);
    }
  }

  function onKeyDown(event: React.KeyboardEvent) {
    switch (event.key) {
      case 'Enter':
        if (isTextArea) return;
        inputEl.current.blur();
        break;
      case 'Escape':
        inputEl.current.value = currentValue;
        inputEl.current.blur();
        break;
    }
  }
  const DefaultInput = () => {
    return (
      <input
        className={props.isHint ? 'text-field-top-input hint-field' : 'text-field-top-input'}
        type='text'
        ref={inputEl}
        defaultValue={currentValue}
        onBlur={onBlur}
        onKeyDown={onKeyDown}
        autoFocus={autoFocus}
        disabled={disabled}
      />
    );
  };

  const TextAreaInput = () => {
    return (
      <textarea
        style={{ width: '100%', height: '7rem' }}
        className={props.isHint ? 'text-field-top-input hint-field' : 'text-field-top-input'}
        ref={inputEl}
        defaultValue={currentValue}
        onBlur={onBlur}
        onKeyDown={onKeyDown}
        autoFocus={autoFocus}
        disabled={disabled}
      />
    );
  };
  const inputEl = useRef(null);
  const [uuid] = useState('id' + nanoid());
  switch (labelPosition) {
    case 'side':
      return (
        <label className='text-field-side'>
          {label}
          <input
            className={props.isHint ? 'hint-field' : ''}
            type='text'
            ref={inputEl}
            defaultValue={currentValue}
            onBlur={onBlur}
            onKeyDown={onKeyDown}
            autoFocus={autoFocus}
            disabled={disabled}
          />
        </label>
      );
    case 'top':
      return (
        <div>
          <label className='text-field' htmlFor={uuid}>
            {label}
          </label>
          {isTextArea ? <TextAreaInput /> : <DefaultInput />}
        </div>
      );
  }
};

const mapStateToProps = (state) => ({});

function mapDispatchToProps(dispatch: Dispatch<FormEditorAction>) {
  return bindActionCreators({}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(TextField);
