import {
  ChangeEventHandler,
  ForwardedRef,
  forwardRef,
  type InputHTMLAttributes,
  ReactElement,
  ReactNode,
  useEffect,
  useRef,
} from 'react'

export interface IPktCheckbox extends InputHTMLAttributes<HTMLInputElement> {
  id: string
  hasTile?: boolean
  disabled?: boolean
  label?: string
  checkHelptext?: ReactNode | ReactNode[] | string
  hasError?: boolean
  defaultChecked?: boolean
  checked?: boolean
  indeterminate?: boolean
  value?: string
  isSwitch?: boolean
  hideLabel?: boolean
  labelPosition?: 'right' | 'left'
  optionalTag?: boolean
  optionalText?: string
  requiredTag?: boolean
  requiredText?: string
  tagText?: string | null
  onChange?: ChangeEventHandler<HTMLInputElement>
}

export const PktCheckbox = forwardRef(
  (
    {
      id,
      hasTile = false,
      disabled = false,
      label,
      checkHelptext,
      hasError = false,
      className,
      isSwitch = false,
      hideLabel = false,
      labelPosition = 'right',
      defaultChecked,
      checked,
      indeterminate,
      optionalTag,
      optionalText = 'Valgfritt',
      requiredTag,
      requiredText = 'Må fylles ut',
      tagText,
      ...props
    }: IPktCheckbox,
    ref: ForwardedRef<HTMLInputElement>,
  ): ReactElement => {
    const internalRef = useRef<HTMLInputElement>(null)

    useEffect(() => {
      if (internalRef.current && indeterminate !== undefined) {
        internalRef.current.indeterminate = indeterminate
      }
    }, [indeterminate])

    useEffect(() => {
      if (typeof ref === 'function') {
        ref(internalRef.current)
      } else if (ref) {
        ref.current = internalRef.current
      }
    }, [ref])

    const classes = [className, 'pkt-input-check'].filter(Boolean).join(' ')

    const labelClasses = [
      'pkt-input-check__input-label',
      disabled ? 'pkt-input-check__input-label--disabled' : '',
      `pkt-input-check__input-label--${labelPosition}`,
      hideLabel ? 'pkt-sr-only' : '',
    ]
      .filter(Boolean)
      .join(' ')

    const inputTileClasses = [
      'pkt-input-check__input',
      hasTile ? 'pkt-input-check__input--tile' : '',
      disabled && hasTile ? 'pkt-input-check__input--tile-disabled' : '',
    ]
      .filter(Boolean)
      .join(' ')

    const tagClasses = ['pkt-tag', 'pkt-tag--small', 'pkt-tag--thin-text'].join(' ')

    const renderTags = () => {
      return (
        <>
          {tagText && <span className={tagClasses + ` pkt-tag--gray`}>{tagText}</span>}
          {optionalTag && <span className={tagClasses + ` pkt-tag--blue-light`}>{optionalText}</span>}
          {requiredTag && <span className={tagClasses + ` pkt-tag--beige`}>{requiredText}</span>}
        </>
      )
    }

    return (
      <div className={classes}>
        <div className={inputTileClasses}>
          {labelPosition === 'left' && (
            <label className={labelClasses} htmlFor={id}>
              {label} {renderTags()}
              {checkHelptext && <div className="pkt-input-check__input-helptext">{checkHelptext}</div>}
            </label>
          )}
          <input
            role={isSwitch ? 'switch' : 'checkbox'}
            ref={internalRef}
            className={`pkt-input-check__input-checkbox ${hasError ? 'pkt-input-check__input-checkbox--error' : ''}`}
            type="checkbox"
            id={id}
            disabled={disabled}
            {...(checked !== undefined ? { checked } : { defaultChecked })}
            {...props}
          />
          {labelPosition === 'right' && (
            <label className={labelClasses} htmlFor={id}>
              {label} {renderTags()}
              {checkHelptext && <div className="pkt-input-check__input-helptext">{checkHelptext}</div>}
            </label>
          )}
        </div>
      </div>
    )
  },
)

PktCheckbox.displayName = 'PktCheckbox'
