/* eslint jsx-a11y/no-noninteractive-tabindex: warn */
import clsx from 'clsx';
import React, { useEffect, useState } from 'react';
import { usePress } from 'react-aria';
import { twMerge } from 'tailwind-merge';

interface SwitchProps {
  label?: string;
  labelClassName?: string;
  containerClassName?: string;
  wrapperClassName?: string;
  thumbClassName?: string;
  checked?: boolean | null;
  onChange?: (checked: boolean) => void;
  disabled?: boolean;
  small?: boolean;
}

const Switch: React.FC<SwitchProps> = ({
  label,
  labelClassName,
  containerClassName,
  wrapperClassName,
  thumbClassName,
  checked = false,
  onChange,
  disabled = false,
  small = false,
}) => {
  const [isChecked, setIsChecked] = useState(checked);

  useEffect(() => {
    setIsChecked(checked);
  }, [checked]);

  const { pressProps } = usePress({
    onPress: () => {
      if (!disabled) {
        setIsChecked(!isChecked);
        if (onChange) {
          onChange(!isChecked);
        }
      }
    },
  });

  return (
    <div className={twMerge('flex items-center space-x-2', wrapperClassName)}>
      <div
        aria-label={label}
        tabIndex={0}
        className={twMerge(
          clsx(
            'relative inline-flex items-center rounded-full ring-1 transition-colors duration-300 ease-in-out',
            {
              'h-4 w-7': small,
              'h-6 w-10': !small,
              'bg-foreground-primary ring-foreground-tertiary': isChecked,
              'bg-background-tertiary ring-foreground-tertiary/20': !isChecked,
              'cursor-not-allowed opacity-50': disabled,
              'cursor-pointer': !disabled,
            }
          ),
          containerClassName
        )}
        {...pressProps}
      >
        <span
          className={twMerge(
            clsx(
              'absolute top-0.5 left-0.5 rounded-full border',
              'transform transition-transform duration-300 ease-in-out',
              {
                'h-3 w-3': small,
                'h-5 w-5': !small,
                'border-foreground-tertiary/20 bg-background-tertiary':
                  isChecked,
                'bg-foreground-primary/75': !isChecked,
                'translate-x-3': isChecked && small,
                'translate-x-4': isChecked && !small,
              }
            ),
            thumbClassName
          )}
        />
      </div>
      {label && (
        <span
          className={twMerge(
            clsx('font-sans text-sm font-normal select-none', {
              'text-foreground-tertiary': disabled,
              'text-foreground-primary': !disabled,
            }),
            labelClassName
          )}
        >
          {label}
        </span>
      )}
    </div>
  );
};

export default Switch;
