import { forwardRef } from 'react';
import { Pressable, View } from 'react-native';
import { mergeDataAttributes, type IUseSwitchReturn } from '@cdx-ui/primitives';
import { cn, composeEventHandlers } from '@cdx-ui/utils';
import {
  switchThumbVariants,
  switchTrackVariants,
  switchWebTrackColorVariants,
  type SwitchVariantProps,
} from './styles';

export interface BaseSwitchProps {
  switchState: IUseSwitchReturn;
  className?: string;
  size?: SwitchVariantProps['size'];
  accessibilityLabel?: string;
  onFocus?: () => void;
  onBlur?: () => void;
}

/**
 * Web host for `Switch`. Renders a custom `Pressable` + `View` toggle (preserving
 * the existing visual contract) wired to the resolved state in `switchState`.
 *
 * `role="switch"` + `aria-checked` + keyboard semantics satisfy the same a11y
 * contract that an `<input type="checkbox" role="switch">` would provide, without
 * the visual rework an input swap would require (see spike notes in PR).
 */
export const BaseSwitch = forwardRef<View, BaseSwitchProps>(
  ({ switchState, className, size = 'md', accessibilityLabel, onFocus, onBlur, ...props }, ref) => {
    return (
      <Pressable
        ref={ref}
        role="switch"
        aria-checked={switchState.checked}
        aria-disabled={switchState.isDisabled}
        accessibilityLabel={accessibilityLabel}
        disabled={switchState.isDisabled}
        onPress={() => switchState.setChecked(!switchState.checked)}
        onFocus={composeEventHandlers(onFocus, switchState.focusProps.onFocus as () => void)}
        onBlur={composeEventHandlers(onBlur, switchState.focusProps.onBlur as () => void)}
        onHoverIn={switchState.hoverProps.onHoverIn as () => void}
        onHoverOut={switchState.hoverProps.onHoverOut as () => void}
        tabIndex={0}
        className={cn(
          switchTrackVariants({ size }),
          switchWebTrackColorVariants({
            isChecked: switchState.checked,
            isInvalid: switchState.isInvalid,
          }),
          className,
        )}
        {...props}
        {...mergeDataAttributes(props, switchState.dataAttrs)}
      >
        <View className={cn(switchThumbVariants({ size, isChecked: switchState.checked }))} />
      </Pressable>
    );
  },
);

BaseSwitch.displayName = 'BaseSwitch';
