import React from 'react'
import RS, { type ReactSwitchProps } from 'react-switch'

import styles from './_switch.module.scss'
import ConfirmationButton, {
  type ConfirmationItem,
} from '../Button/ButtonComponents/ConfirmationButton'
import FormLabel, { type FormLabelProps } from '../FormLabel/FormLabel'
import { type PopoverProps } from '../Popover/Popover'

type SwitchBaseProps = {
  /** Checked value of the Switch - boolean */
  checked: ReactSwitchProps['checked']
  /** Disabled state of the Switch - boolean */
  disabled?: ReactSwitchProps['disabled']
  /** Optional class for the Switch */
  className?: string
  /** Set as an attribute to the embedded checkbox. This is useful for the associated label, which can point to the id in its htmlFor attribute. */
  customId?: ReactSwitchProps['id']
  /** Optionally add a label for the Switch */
  formLabelProps?: Omit<FormLabelProps, 'rightLabel' | 'disabled' | 'error'>
  /** Optional prop to add a test id to the Switch for QA testing */
  qaTestId?: string
}

type WithConfirmation = SwitchBaseProps & {
  /** Confirmation to appear when switching the Switch value */
  confirmation: ConfirmationItem
  /** Optional props for the Popover when using confirmation  */
  popoverProps?: PopoverProps
  callout?: never
}

type WithoutConfirmation = SwitchBaseProps & {
  /** function to be executed when the checked status change */
  callout: (checked: boolean) => void
  confirmation?: never
  popoverProps?: never
}

export type SwitchProps = WithConfirmation | WithoutConfirmation

const Switch = ({
  checked,
  callout,
  className = '',
  customId = '',
  disabled,
  confirmation,

  popoverProps,
  formLabelProps,
  qaTestId = 'switch',
}: SwitchProps): React.JSX.Element => {
  const rsProps = {
    checked,
    disabled,
    onChange: (value: boolean) => callout?.(value),
    handleDiameter: 16,
    checkedIcon: false,
    uncheckedIcon: false,
    activeBoxShadow: '0px 0px 1px 6px rgba(0, 0, 0, 0.2)',
    height: 12,
    width: 32,
    className: `${styles.switch} ${checked ? styles.on : ''} ${className}`,
    id: customId,
  }

  return (
    <div className={styles.switchContainer} qa-test-id={qaTestId}>
      {confirmation ? (
        <ConfirmationButton
          confirmation={confirmation}
          buttonProps={{
            children: (
              <RS
                {...rsProps}
                onChange={() => {
                  // We want to prevent the Switch `callout` from being called when the confirmation is visible.
                  return
                }}
              />
            ),
            disabled,
            className: styles.unstyled,
          }}
          popoverProps={{
            ...popoverProps,
            position: popoverProps?.position ? popoverProps.position : 'top',
          }}
        />
      ) : (
        <RS {...rsProps} />
      )}
      {formLabelProps ? (
        <FormLabel {...formLabelProps} disabled={disabled} />
      ) : null}
    </div>
  )
}

export default Switch
