
import * as React from "react";
import { grey400, grey800, grey50, white, black } from "../theme/colors";
import {
    NativeModules,
    Platform,
    StyleProp,
    Switch as NativeSwitch,
    ViewStyle,
} from "react-native";
import setColor from "color";
import { DefaultTheme, ThemeContext } from "styled-components";

const version = NativeModules.PlatformConstants
    ? NativeModules.PlatformConstants.reactNativeVersion
    : undefined;

type Props = React.ComponentPropsWithRef<typeof NativeSwitch> & {
    /**
     * Disable toggling the switch.
     */
    disabled?: boolean;
    /**
     * Value of the switch, true means 'on', false means 'off'.
     */
    value?: boolean;
    /**
     * Custom color for switch.
     */
    color?: string;
    /**
     * Callback called with the new value when it changes.
     */
    onValueChange?: (val?) => void;
    style?: StyleProp<ViewStyle>;
    /**
     * @optional
     */
    theme?: DefaultTheme;
};

/**
 * Switch is a visual toggle between two mutually exclusive states — on and off.
 *
 * <div class="screenshots">
 *   <figure>
 *     <img src="screenshots/switch-enabled.android.png" />
 *     <figcaption>Android (enabled)</figcaption>
 *   </figure>
 *   <figure>
 *     <img src="screenshots/switch-disabled.android.png" />
 *     <figcaption>Android (disabled)</figcaption>
 *   </figure>
 *   <figure>
 *     <img src="screenshots/switch-enabled.ios.png" />
 *     <figcaption>iOS (enabled)</figcaption>
 *   </figure>
 *   <figure>
 *     <img src="screenshots/switch-disabled.ios.png" />
 *     <figcaption>iOS (disabled)</figcaption>
 *   </figure>
 * </div>
 *
 * ## Usage
 * ```js
 * import * as React from 'react';
 * import Switch from 'react-native-simple-elements/components/Switch';
 *
 * const MyComponent = () => {
 *   const [isSwitchOn, setIsSwitchOn] = React.useState(false);
 *
 *   const onToggleSwitch = () => setIsSwitchOn(!isSwitchOn);
 *
 *   return <Switch value={isSwitchOn} onValueChange={onToggleSwitch} />;
 * };
 *
 * export default MyComponent;
 * ```
 */
const Switch = ({
    value,
    disabled,
    onValueChange,
    color,
    ...rest
}: Props) => {
    const theme = React.useContext(ThemeContext);
    const checkedColor = color || theme.colors.accent;

    const onTintColor =
        Platform.OS === "ios"
            ? checkedColor
            : disabled
                ? theme.dark
                    ? setColor(white).alpha(0.1).rgb().string()
                    : setColor(black).alpha(0.12).rgb().string()
                : setColor(checkedColor).alpha(0.5).rgb().string();

    const thumbTintColor =
        Platform.OS === "ios"
            ? undefined
            : disabled
                ? theme.dark
                    ? grey800
                    : grey400
                : value
                    ? checkedColor
                    : theme.dark
                        ? grey400
                        : grey50;

    const props =
        version && version.major === 0 && version.minor <= 56
            ? {
                onTintColor,
                thumbTintColor,
            }
            : Platform.OS === "web"
                ? {
                    activeTrackColor: onTintColor,
                    thumbColor: thumbTintColor,
                    activeThumbColor: checkedColor,
                }
                : {
                    thumbColor: thumbTintColor,
                    trackColor: {
                        true: onTintColor,
                        false: "",
                    },
                };

    return (
        <NativeSwitch
            value={value}
            disabled={disabled}
            onValueChange={disabled ? undefined : onValueChange}
            {...props}
            {...rest}
        />
    );
};

export default Switch;
