import { useCallback, useMemo } from 'react';
import Debug from 'debug';

import type { WithSpacingProps } from '~/src/lib/hocs/withSpacing';
import type { TextareaHTMLAttributes } from 'react';

import useTheme from '~/src/hooks/useTheme';
import withSpacing from '~/src/lib/hocs/withSpacing';
import debounce from '~/src/lib/utils/debounce';
import { stripNonDomProps } from '~/src/lib/utils/stripNonDomProps';
import { TEXT_INPUT_DEFAULT_FONT_SIZE } from '../TextInput';

const debug = Debug('songwhip/MultilineTextInput');

interface MultilineTextInputProps
  extends Omit<WithSpacingProps, 'children'>,
    Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> {
  fontSize?: string | number;
  onChange?: (params: { value: string; event: InputEvent }) => void;
  onInputEnd?: (params: { value: string; event: InputEvent }) => void;
  placeholder?: string;
  maxLength?: number;
  testId?: string;
  backgroundColor?: string;
  borderColor?: string;
  noWrap?: boolean;
}

const DEBOUNCE_TIMEOUT = 300;

const MultilineTextInput = withSpacing<MultilineTextInputProps>(
  ({
    style,
    fontSize = TEXT_INPUT_DEFAULT_FONT_SIZE,
    className = '',
    onChange,
    onInputEnd,
    testId,
    backgroundColor,
    borderColor,
    noWrap,
    ...textareaProps
  }) => {
    const theme = useTheme();

    const onChangeDebounced = useMemo(
      () =>
        debounce(({ value, event }) => {
          debug('on change debounced', value);
          if (onInputEnd) onInputEnd({ value, event });
        }, DEBOUNCE_TIMEOUT),
      [onInputEnd]
    );

    const onChangeInternal = useCallback(
      (event) => {
        const {
          target: { value },
        } = event;

        if (onChange) onChange({ value, event });
        onChangeDebounced({ value, event });
      },
      [onChange]
    );

    return (
      <div
        style={{
          ...style,
          border: `solid 1px ${borderColor || theme.textInputBorderColor}`,
          background: backgroundColor || theme.textInputBackground,
          borderRadius: theme.borderRadius,
          fontWeight: 300,
        }}
        className={`${className} root`}
      >
        <textarea
          {...stripNonDomProps(textareaProps, { stripChildren: true })}
          data-testid={testId}
          onChange={onChangeInternal}
          style={{
            display: 'block',
            padding: '0.6em 0.7em',
            height: '100%',
            minHeight: style?.minHeight || '10rem',
            width: '100%',
            font: 'inherit',
            fontSize,
            lineHeight: '1.35em',
            letterSpacing: '0.01em',
            background: 'none',
            color: 'currentcolor',
            border: 0,
            resize: 'vertical',
            whiteSpace: noWrap ? 'nowrap' : 'normal',
          }}
        />
        <style jsx>{`
          .root:focus-within {
            border-color: #666 !important;
          }

          textarea::placeholder {
            color: inherit;
            opacity: 0.4;
            letter-spacing: 0.02em;
          }
        `}</style>
      </div>
    );
  }
);

export default MultilineTextInput;
