import { CSSProperties, css } from 'glamor';
import { observer } from 'mobx-react';
import React from 'react';
import { ApphouseComponent } from './component.interfaces';
import { useLocalStyles } from '../styles/defaults/useLocalStyles';
import { useApphouse } from '../context/useApphouse';
/**
 * Interface for styles to be applied to the ToggleThemeButton component
 */
export interface ToggleThemeButtonStyles {
  container?: CSSProperties;
  label?: CSSProperties;
  checkbox?: CSSProperties;
  slider?: CSSProperties;
}
/**
 * Interface for the ToggleThemeButton component
 */
export interface ToggleThemeButtonProps
  extends ApphouseComponent<ToggleThemeButtonStyles> {
  /**
   * The label of the button
   * @default 'Toggle theme'
   * @example 'Toggle theme'
   */
  label?: string;
  /**
   * The callback function to be executed when the button is clicked.
   * If provided, the user will control the theme switching
   * @example () => { console.log('clicked') }
   */
  onClick?: () => void;
  /**
   * if true, the theme will be set to dark
   * @default false
   */
  checked?: boolean;
  /**
   * if true, the button will be small
   * @default false
   */
  small?: boolean;
}
/**
 * It toggles the light/dark theme default from apphouse.
 * If onClick is provided, the user will be responsible for switching the theme
 */
export const ToggleThemeButton: React.FC<ToggleThemeButtonProps> = observer(
  (props) => {
    const { styleOverwrites, onClick, checked, small = false } = props;
    const { app, theme } = useApphouse();
    const colors = {
      light: theme.colors.background,
      dark: theme.colors.onBackground
    };
    let size = 50;
    if (small) {
      size = 30;
    }

    const borderRadius = size / 1.5;
    const dim = `${size}px`;
    const bRadius = `${borderRadius}px`;
    const componentStyles: ToggleThemeButtonStyles = {
      container: {
        position: 'relative',
        width: `${size * 2}`,
        height: dim
      },
      label: {
        position: 'absolute',
        width: '100%',
        height: dim,
        backgroundColor: colors.dark,
        borderRadius: bRadius,
        cursor: 'pointer',
        border: `3px solid ${colors.dark}`
      },
      checkbox: {
        position: 'absolute',
        display: 'none',
        ':checked ~ .slider': {
          backgroundColor: colors.light
        },
        ':checked ~ .slider::before': {
          transform: `translateX(${dim})`,
          backgroundColor: colors.dark,
          boxShadow: 'none'
        }
      },
      slider: {
        position: 'absolute',
        width: '100%',
        height: '100%',
        borderRadius: `${borderRadius - 3}px`,
        transition: '0.3s',

        ':before': {
          content: "''",
          position: 'absolute',
          top: `${size / 5}px`,
          left: `${size / 5}px`,
          width: `${size / 2}px`,
          height: `${size / 2}px`,
          borderRadius: '50%',
          boxShadow: `inset 12px -4px 0px 0px ${colors.light}`,
          backgroundColor: `${colors.dark}`,
          transition: '0.3s'
        }
      }
    };

    const localStyles = useLocalStyles<ToggleThemeButtonStyles>(
      componentStyles,
      styleOverwrites
    );

    let isChecked = checked;
    if (isChecked === undefined) {
      const currentTheme = app.settings.theme.id;
      isChecked = currentTheme === 'light';
    }
    return (
      <div {...css(localStyles.container)}>
        <label {...css(localStyles.label)}>
          <input
            type="checkbox"
            checked={isChecked}
            onChange={() => {
              if (onClick) {
                onClick();
              } else {
                const currentTheme = app.settings.theme.id;
                if (currentTheme === 'light') {
                  app.settings.setThemeId('dark');
                } else {
                  app.settings.setThemeId('light');
                }
              }
            }}
            {...css(localStyles.checkbox)}
          />
          <span className="slider" {...css(localStyles.slider)}></span>
        </label>
      </div>
    );
  }
);
