import { h } from 'preact'
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
import cn from 'classnames'

/**
 * @param {{
 *   base?: string
 *   touched?: string
 *   element?: string
 *   label?: string
 * }} styles
 * @returns {import('preact').FunctionComponent<{
 *    autoFocus?: boolean
 *    className?: string
 *    defaultChecked?: boolean
 *    disabled?: boolean
 *    name: string
 *    label?: string
 *    required?: boolean
 * }>}
 */
export default function checkboxFactory(styles) {
  const Checkbox = ({
    autoFocus,
    className,
    defaultChecked,
    disabled,
    name,
    label,
    onChange,
    required,
    style = 'normal',
    value = 'true',
  }) => {
    const [touched, setTouched] = useState(false)
    const checkboxRef = useRef<HTMLInputElement>()

    const onBlur = useCallback(() => setTouched(true), [])

    useEffect(() => {
      const form = checkboxRef.current.form
      const resetTouched = setTouched.bind(null, false)

      form.addEventListener('reset', resetTouched)

      return () => form.removeEventListener('reset', resetTouched)
    }, [])

    useEffect(() => {
      if (autoFocus) checkboxRef.current.focus()
    }, [autoFocus])

    return (
      <label className={cn(styles.base, styles[style], touched && styles.touched, className)}>
        <input
          autoFocus={autoFocus}
          className={styles.element}
          defaultChecked={defaultChecked}
          disabled={disabled}
          name={name}
          onBlur={onBlur}
          onChange={onChange}
          ref={checkboxRef}
          required={required}
          type='checkbox'
          value={value}
        />

        <i />

        {label && <span className={styles.label}>{label}</span>}
      </label>
    )
  }

  return Checkbox
}
