/* eslint-disable no-unused-vars */
/* eslint-disable no-use-before-define */
/* eslint-disable import/prefer-default-export */
import classNames from 'classnames'
import * as React from 'react'
import { addThousandSeparator } from '../FormatCurrency'

type InputType = 'text' | 'password' | 'tel' | 'number' | 'date' | 'datetime' | 'email' | 'file'

export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string
  labelClassName?: string
  id: string
  dataTestId?: string
  name: string
  value?: string | number
  type: InputType
  placeholder?: string
  errorMessage?: string
  min?: string | number
  max?: string | number
  disabled?: boolean
  leftContent?: React.ReactElement
  rightContent?: React.ReactElement
  customInputStyles?: string
  horizontal?: boolean
  inputWidth?: string
  width?: string
  showOnlyCurrency?: boolean
  center?: boolean
  isBeyondAccess?: boolean
  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
}

const baseClass = 'w-full border placeholder-placeholderColor rounded-md flex items-center h-9'

export const Input = (props: InputProps) => {
  const {
    label,
    labelClassName,
    id,
    dataTestId,
    name,
    defaultValue,
    value,
    type = 'text',
    placeholder,
    errorMessage,
    leftContent,
    rightContent,
    min,
    max,
    disabled,
    customInputStyles,
    onChange,
    horizontal,
    required,
    onBlur,
    className,
    inputWidth,
    width,
    showOnlyCurrency,
    center,
    isBeyondAccess,
  } = props

  const effectiveWidth = inputWidth || width
  const hasValue =
    (value !== undefined && value !== null && value !== '') ||
    (defaultValue !== undefined && defaultValue !== null && defaultValue !== '')

  const inputOrCurrencyDisplay = showOnlyCurrency ? (
    <div
      className={classNames(baseClass, 'bg-base-200', errorMessage && 'input-error', isBeyondAccess && 'bg-warning')}
    >
      {leftContent && <span className="pl-2 text-base-content">{leftContent}</span>}
      <p
        className={classNames(
          'py-2 px-4 w-full focus:outline-none rounded-lg h-9 text-base-content',
          center && 'text-center',
          customInputStyles,
          disabled && 'opacity-80',
          isBeyondAccess && 'bg-warning',
        )}
      >
        {addThousandSeparator(Number(value ?? 0))}
      </p>
    </div>
  ) : (
    <div
      className={classNames(
        baseClass,
        type === 'file' && 'cursor-pointer',
        errorMessage && 'input-error',
        'focus-within:border-slate-400 focus-within:border-opacity-100',
      )}
    >
      {leftContent && (
        <span
          className={classNames('pl-2 flex items-center text-base-content', disabled && 'self-stretch bg-base-200')}
        >
          {leftContent}
        </span>
      )}

      <input
        id={id}
        data-testid={dataTestId || `${name}-input-${id}`}
        name={name}
        type={type}
        defaultValue={defaultValue}
        value={value}
        placeholder={placeholder}
        onChange={onChange}
        onBlur={onBlur}
        className={classNames(
          'input px-2 py-1 text-sm w-full focus:outline-none rounded-md bg-transparent h-9 placeholder:text-gray-500',
          hasValue ? 'text-secondary text-sm' : 'text-gray-400',
          type === 'file' && 'cursor-pointer',
          customInputStyles,
          className,
          isBeyondAccess && 'bg-yellow-300',
        )}
        min={min}
        disabled={disabled}
      />
      {rightContent && (
        <span
          className={classNames('pr-2 flex items-center text-base-content', disabled && 'self-stretch bg-base-200')}
        >
          {rightContent}
        </span>
      )}
    </div>
  )

  return (
    <div
      className={classNames(
        horizontal ? 'w-full' : effectiveWidth || 'w-full',
        horizontal ? 'flex flex-col md:flex-row md:items-center' : 'flex flex-col',
      )}
    >
      {label && (
        <label
          htmlFor={id}
          className={classNames(
            'label capitalize text-secondary text-sm flex justify-start gap-1',
            horizontal && !effectiveWidth && 'md:w-[30%]',
            horizontal && effectiveWidth && 'flex-1',
            labelClassName,
          )}
        >
          {label}
          {required && <span className="text-red-700 ml-1">*</span>}
        </label>
      )}

      <div
        className={classNames(
          horizontal ? effectiveWidth || 'md:w-[70%]' : effectiveWidth || 'w-full',
          'flex flex-col',
        )}
      >
        {inputOrCurrencyDisplay}

        {errorMessage && (
          <label htmlFor={id} className="text-red-500 text-sm">
            {errorMessage}
          </label>
        )}
      </div>
    </div>
  )
}
