'use client';

import {
  ChangeEventHandler,
  FocusEventHandler,
  HTMLInputTypeAttribute,
  ReactNode,
} from 'react';

import { cn } from '@/lib/helper';

export interface TextInputProps {
  type?: HTMLInputTypeAttribute;
  label?: string;
  bottomLabel?: string;
  name: string;
  value?: string | number;
  placeholder?: string;
  className?: {
    wrapper?: string;
    label?: string;
    inputWrapper?: string;
    input?: string;
  };
  isError?: boolean;
  isValid?: boolean;
  disabled?: boolean;
  readOnly?: boolean;
  required?: boolean;
  isLoading?: boolean;
  errorMessage?: string;
  startAdornment?: ReactNode;
  endAdornment?: ReactNode;
  onChange?: ChangeEventHandler<HTMLInputElement>;
  onBlur?: FocusEventHandler<HTMLInputElement>;
}

const TextInput = ({
  type = 'text',
  label,
  bottomLabel,
  name,
  value,
  placeholder,
  className,
  isError,
  isValid,
  errorMessage,
  startAdornment,
  endAdornment,
  disabled = false,
  required = false,
  onChange,
  onBlur,
  readOnly = false,
  isLoading = false,
}: TextInputProps) => {
  return (
    <div
      className={cn(
        'w-full flex flex-col gap-2 text-start',
        className?.wrapper
      )}
    >
      {label && (
        <label
          htmlFor={name}
          className={cn(
            'w-full text-sm font-normal leading-5',
            {
              'text-error': isError,
            },
            className?.label
          )}
        >
          {label}
          {required && (
            <>
              {' '}
              <span className='tooltip tooltip-error' data-tip='required'>
                <span className='text-error'> *</span>
              </span>
            </>
          )}
        </label>
      )}

      <div
        className={cn(
          'input h-12 px-4 py-2 text-base font-normal leading-6 w-full rounded outline-none! transition-all duration-200',
          {
            'border-error': isError,
            'border-success!': isValid,
          },
          className?.inputWrapper
        )}
      >
        {startAdornment && startAdornment}

        <input
          type={type}
          id={name}
          name={name}
          placeholder={placeholder}
          value={value}
          onChange={onChange}
          onBlur={onBlur}
          disabled={disabled}
          className={cn('grow', className?.input)}
          readOnly={readOnly}
        />

        {(isLoading || endAdornment) && (
          <div className='flex flex-row gap-2'>
            {isLoading && <span className='loading loading-spinner' />}

            {endAdornment && endAdornment}
          </div>
        )}
      </div>

      {!isError && bottomLabel && (
        <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
      )}
      {isError && errorMessage && (
        <p className='w-full text-sm text-error'>{errorMessage}</p>
      )}
    </div>
  );
};

export default TextInput;
