/* eslint-disable */
// @ts-ignore

import { Ref, forwardRef, useImperativeHandle, useState } from "react";
import { useFocus } from "@/hooks";
import { mobileAndTabletCheck } from "@/assets/three/helpers/CameraControl";

import styles from "./styles.module.scss";

export const types = {
  TEXT: "text",
  NAME: "name",
  EMAIL: "email",
  MULTILINE: "multiline",
};

export const errors = {
  EMPTY: "empty",
  TOO_SHORT: "short",
  TOO_LONG: "long",
  INVALID: "invalid",
};

interface InputTextProps {
  type?: string;
  id?: string | "input";
  placeholder?: string;
  tabIndex?: number;
  ariaLabel?: string;
  ariaHidden?: boolean | undefined;
  value: string;
  min?: number;
  max?: number;
  autoComplete?: boolean;
  onChange?: (text: string) => void | undefined;
  onValidate?: (validated: boolean) => void | undefined;
  onError?: (error: string, input: HTMLInputElement) => void | undefined;
  onEnterKey?: () => void | undefined;
}

const InputText = (
  {
    type,
    id,
    placeholder,
    tabIndex,
    ariaLabel,
    ariaHidden,
    value,
    min,
    max,
    autoComplete,
    onChange,
    onValidate,
    onError,
    onEnterKey,
  }: InputTextProps,
  ref: Ref<unknown> | undefined,
) => {
  const [inputRef, setFocus, removeFocus] = useFocus<any>();
  const [isError, setIsError] = useState<boolean>(false);

  const isDesktop = !mobileAndTabletCheck();

  function validateInput(text: string, forceFocus: boolean = false) {
    let error = undefined;

    if (text.trim().length < length.min) {
      error = errors.TOO_SHORT;
    }
    if (text.trim().length > length.max) {
      error = errors.TOO_LONG;
    }
    if (rule) {
      if (!rule.test(text)) {
        error = errors.INVALID;
      }
    }
    if (text.trim().length <= 0) {
      error = errors.EMPTY;
    }

    setIsError(error !== undefined);

    // - Ok?
    if (onValidate) onValidate(!error);
    // -
    if (error && onError) {
      onError(error, inputRef.current as HTMLInputElement);

      if (forceFocus && isDesktop) {
        setTimeout(() => {
          setFocus();
        }, 1000);
      }
    }
  }

  function onChangeHandler(e: any) {
    if (onChange) onChange(e.target.value);
    validateInput(e.target.value);
  }

  function onKeyDownHandler(e: any) {
    if (e.key === "Enter") {
      e.preventDefault();
    }
  }
  function onKeyUpHandler(e: any) {
    e.preventDefault();
    if (e.key === "Enter") {
      if (onEnterKey) onEnterKey();
    }
  }

  function onBlur() {
    if (onChange) onChange(value.trim());
  }

  function autoHeight(e: any) {
    e.target.style.height = "1px";
    //console.log(e.target.scrollHeight);
    e.target.style.height = `${Math.max(Math.min(e.target.scrollHeight, isDesktop ? 78 : 66), 30) * 0.1}rem`;
  }

  useImperativeHandle(ref as Ref<unknown>, () => ({
    validateInput(text: string, forceFocus: boolean = false) {
      validateInput(text, forceFocus);
    },
    setFocus() {
      setFocus();
    },
    removeFocus() {
      removeFocus();
    },
  }));

  let realType: string = types.TEXT;
  const length: any = { min: 0, max: 70 };
  let rule: any = /(?:.*)/i;

  switch (type) {
    case types.NAME:
      realType = types.TEXT;
      length.min = 2;
      length.max = 16;
      //rule = /^[A-zÀ-ú \.,\-&]+$/i;
      break;

    case types.EMAIL:
      realType = types.EMAIL;
      length.min = 6;
      length.max = 50;
      rule = /\b[\w\.-]+@[\w\.-]+\.\w{2,10}\b/i;
      break;

    case types.MULTILINE:
      realType = "textarea";
      length.min = 2;
      break;

    default:
    // Nothing
  }
  if (min) length.min = min;
  if (max) length.max = max;

  return (
    <>
      {realType === "textarea" && (
        <textarea
          ref={inputRef}
          id={id}
          className={styles.inputText}
          placeholder={placeholder}
          minLength={0}
          maxLength={max || length.max}
          value={value}
          aria-label={ariaLabel || placeholder}
          aria-required="true"
          aria-invalid={isError}
          aria-hidden={ariaHidden}
          tabIndex={tabIndex || 0}
          inputMode="text"
          onChange={onChangeHandler}
          onInput={autoHeight}
          onKeyUp={onKeyUpHandler}
          onKeyDown={onKeyDownHandler}
          onBlur={onBlur}
        ></textarea>
      )}

      {realType !== "textarea" && (
        <input
          ref={inputRef}
          id={id}
          className={styles.inputText}
          name="no_search_fill"
          type={realType}
          inputMode={realType === types.EMAIL ? "email" : "text"}
          autoComplete={autoComplete ? "on" : "off"}
          placeholder={placeholder}
          aria-label={ariaLabel || placeholder}
          aria-required="true"
          aria-invalid={isError}
          aria-hidden={ariaHidden}
          autoCorrect="off"
          minLength={0}
          maxLength={max || length.max}
          value={value}
          tabIndex={tabIndex || 0}
          onChange={onChangeHandler}
          onKeyUp={onKeyUpHandler}
          onBlur={onBlur}
        ></input>
      )}
    </>
  );
};

export default forwardRef(InputText);
