/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable import/prefer-default-export */
import classNames from 'classnames'
import { DetailedHTMLProps, OptionHTMLAttributes, ReactElement, SelectHTMLAttributes, useMemo } from 'react'
import { useTranslationData } from 'translation'
import './loader.css'

export interface OptionProps extends DetailedHTMLProps<OptionHTMLAttributes<HTMLOptionElement>, HTMLOptionElement> {
  label: string
  value: string | number
  optionStyle?: string
}

export interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
  label?: string
  errorMessage?: string
  leftContent?: ReactElement
  rightContent?: ReactElement
  options: OptionProps[]
  isLoading?: boolean
  placeholderoption?: string
  showplaceholder?: boolean
  horizontal?: boolean
  selectWidth?: string
  customStyle?: string
  OptionStyle?: string
  skipTranslation?: boolean
}

const baseClass = 'w-full input-bordered border rounded-md flex items-center gap-2 h-9'

export const Select = (props: SelectProps) => {
  const { t } = useTranslationData()

  const {
    label,
    errorMessage,
    id,
    leftContent,
    rightContent,
    options,
    isLoading,
    showplaceholder,
    placeholderoption,
    horizontal,
    required,
    selectWidth,
    customStyle,
    OptionStyle,
    skipTranslation,
    ...restProps
  } = props

  const translatedOptions = useMemo(() => {
    if (!Array.isArray(options)) return []

    return options.map((item) => ({
      ...item,
      label: skipTranslation ? item.label : String(t(item.label)),
    }))
  }, [options, t, skipTranslation])

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

      <div className={classNames(horizontal ? selectWidth || 'md:w-[70%]' : selectWidth || 'w-full', 'flex flex-col')}>
        <div
          className={classNames(
            baseClass,
            errorMessage && 'input-error',
            'focus-within:border-slate-400 focus-within:border-opacity-100',
          )}
        >
          {leftContent && <span className="text-placeholderColor">{leftContent}</span>}

          {isLoading && (
            <div className="lds-ring--input">
              <div />
              <div />
              <div />
              <div />
            </div>
          )}

          <select
            id={id}
            className={classNames(
              'py-2 px-1 w-full text-sm focus:outline-none rounded-md border-0 bg-transparent capitalize focus:ring-0',
              restProps.value === '' || restProps.value === undefined ? 'text-gray-500' : 'text-secondary',
              customStyle,
            )}
            {...restProps}
          >
            {showplaceholder && (
              <option value="">
                {placeholderoption || 'Select an option'}
              </option>
            )}

            {Array.isArray(translatedOptions) &&
              translatedOptions.map((item: OptionProps) => {
                const { label: optLabel, optionStyle, ...nativeOptionProps } = item

                return (
                  <option
                    key={String(item.value)}
                    className={classNames('capitalize', OptionStyle, optionStyle)}
                    {...nativeOptionProps}
                  >
                    {optLabel}
                  </option>
                )
              })}
          </select>

          {rightContent && <span className="pr-2">{rightContent}</span>}
        </div>

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