import React, { ReactElement, ChangeEvent } from 'react';
import css from '../../utils/css';

import Icon, { IconName } from '../Icon';
import {
  StyledWrapper,
  StyledInputWrapper,
  StyledInput,
  StyledSlider,
  StyledIconWrapper,
  StyledLoadingIconWrapper,
} from './StyledSwitch';

import { CommonProps } from '../common';

export interface SwitchProps extends Omit<CommonProps, 'id'> {
  /**
   * Control whether the switch is checked
   */
  checked?: boolean;
  /**
   * Whether the switch is disabled
   */
  disabled?: boolean;
  /**
   * Specify the icon will be shown inside the checked switch
   */
  icon?: IconName;
  /**
   * Id of <input> element.
   */
  id?: string;
  /**
   * Whether the switch is loading
   */
  loading?: boolean;
  /**
   * Name of <input> element, is used to refer to the form data for submission.
   */
  name?: string;
  /**
   * Change event handler. Use `event.target.checked` to see whether the switch will be changed to checked.
   */
  onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
  /**
   * Size of the switch
   */
  size?: 'small' | 'medium';
}

const Switch = ({
  size = 'medium',
  icon,
  loading = false,
  disabled = false,
  checked,
  onChange,
  name,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: SwitchProps): ReactElement => {
  const showIcon = disabled === true ? 'unavailable' : icon;

  return (
    <StyledWrapper
      themeLoading={loading}
      className={className}
      style={{ ...style, ...css(sx) }}
      data-test-id={dataTestId}
    >
      <StyledInputWrapper themeSize={size}>
        <StyledInput
          themeDisabled={disabled}
          themeSize={size}
          type="checkbox"
          checked={checked}
          onChange={onChange}
          disabled={disabled}
          name={name}
          id={id}
        />
        <StyledSlider themeDisabled={disabled} themeSize={size} />
        {showIcon !== undefined && (
          <StyledIconWrapper
            themeDisabled={disabled}
            themeChecked={checked}
            themeSize={size}
          >
            <Icon icon={showIcon} data-test-id="switch-icon" />
          </StyledIconWrapper>
        )}
        {loading === true && (
          <StyledLoadingIconWrapper themeDisabled={disabled} themeSize={size}>
            <Icon icon="loading-2" spin data-test-id="loading-icon" />
          </StyledLoadingIconWrapper>
        )}
      </StyledInputWrapper>
    </StyledWrapper>
  );
};

export default Switch;
