import * as React from 'react';
import * as ButtonBase from '@tesseract-design/web-base-button';
import * as CheckControlBase from '@tesseract-design/web-base-checkcontrol';

export type CheckboxProps = Omit<React.HTMLProps<HTMLInputElement>, 'size' | 'type' | 'style'> & {
  /**
   * Size of the component.
   */
  size?: ButtonBase.ButtonSize,
  /**
   * Variant of the component.
   */
  variant?: ButtonBase.ButtonVariant,
  /**
   * Should the component display a border?
   */
  border?: boolean,
  /**
   * Should the component occupy the whole width of its parent?
   */
  block?: boolean,
  /**
   * Style of the component.
   */
  style?: ButtonBase.ButtonStyle,
  /**
   * Does the component need to conserve space?
   */
  compact?: boolean,
  /**
   * Complementary content of the component.
   */
  subtext?: React.ReactNode,
  /**
   * Short complementary content displayed at the edge of the component.
   */
  badge?: React.ReactNode,
  /**
   * Appearance of the component.
   */
  appearance?: CheckControlBase.CheckControlAppearance,
  /**
   * Does the component have indeterminate check state?
   */
  indeterminate?: boolean,
}

/**
 * Component for performing an action upon activation (e.g. when clicked).
 *
 * This component functions as a regular button.
 */
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
  (
    {
      size = ButtonBase.ButtonSize.MEDIUM,
      variant = ButtonBase.ButtonVariant.OUTLINE,
      border = false,
      children,
      block = false,
      style = ButtonBase.ButtonStyle.DEFAULT,
      disabled = false,
      compact = false,
      subtext,
      badge,
      appearance = CheckControlBase.CheckControlAppearance.DEFAULT,
      indeterminate = false,
      className: _className,
      as: _as,
      ...etcProps
    }: CheckboxProps,
    ref,
  ) => {
    const styleProps = React.useMemo<ButtonBase.ButtonBaseArgs & CheckControlBase.CheckControlBaseArgs>(() => ({
      size,
      block,
      variant,
      border,
      style,
      compact,
      menuItem: false,
      disabled,
      appearance,
      type: 'checkbox',
    }), [size, block, variant, border, style, compact, disabled, appearance]);
    const defaultRef = React.useRef<HTMLInputElement>(null);
    const theRef = (ref ?? defaultRef) as React.MutableRefObject<HTMLInputElement>;

    React.useEffect(() => {
      if (!(indeterminate && theRef.current)) {
        return;
      }
      theRef.current.indeterminate = indeterminate;
    }, [theRef, indeterminate]);

    const checkIndicatorCommon = (
      <span
        className={CheckControlBase.CheckIndicatorArea(styleProps)}
      >
        <span
          className={CheckControlBase.CheckIndicatorWrapper(styleProps)}
        >
          <svg
            className={CheckControlBase.CheckIndicator(styleProps)}
            viewBox="0 0 24 24"
            role="presentation"
          >
            <polyline
              points="20 6 9 17 4 12"
            />
          </svg>
          <svg
            className={CheckControlBase.CheckIndicator(styleProps)}
            viewBox="0 0 24 24"
            role="presentation"
          >
            <polyline
              points="20 12 4 12"
            />
          </svg>
        </span>
      </span>
    )

    return (
      <div
        className={CheckControlBase.ClickAreaWrapper(styleProps)}
      >
        <label
          className={CheckControlBase.ClickArea()}
        >
          <input
            {...etcProps}
            disabled={disabled}
            type="checkbox"
            ref={theRef}
            className={CheckControlBase.CheckStateContainer(styleProps)}
          />
          {
            appearance === CheckControlBase.CheckControlAppearance.DEFAULT
            && (
              <span>
                <span />
                {checkIndicatorCommon}
                <span>
                  {children}
                  {
                    subtext
                    && (
                      <>
                        <br />
                        <span
                          className={CheckControlBase.Subtext()}
                        >
                          {subtext}
                        </span>
                      </>
                    )
                  }
                </span>
                {
                  badge
                  && (
                    <>
                      {' '}
                      <span
                        className={ButtonBase.BadgeContainer(styleProps)}
                      >
                        {badge}
                      </span>
                    </>
                  )
                }
              </span>
            )
          }
          {
            appearance === CheckControlBase.CheckControlAppearance.BUTTON
            && (
              <span
                className={ButtonBase.Button(styleProps)}
              >
                <span
                  className={ButtonBase.Border(styleProps)}
                />
                {checkIndicatorCommon}
                <span
                  className={ButtonBase.Label(styleProps)}
                >
                  <span
                    className={ButtonBase.MainText()}
                  >
                    <span
                      className={ButtonBase.OverflowText()}
                    >
                      {children}
                    </span>
                  </span>
                  {
                    subtext
                    && (
                      <>
                        {' '}
                        <span
                          className={ButtonBase.Subtext()}
                        >
                          <span
                            className={ButtonBase.OverflowText()}
                          >
                            {subtext}
                          </span>
                        </span>
                      </>
                    )
                  }
                </span>
                {
                  badge
                  && (
                    <>
                      {' '}
                      <span
                        className={ButtonBase.BadgeContainer(styleProps)}
                      >
                        {badge}
                      </span>
                    </>
                  )
                }
              </span>
            )
          }
          {
            appearance === CheckControlBase.CheckControlAppearance.SWITCH
            && (
              <span>
                <span />
                {checkIndicatorCommon}
                <span>
                  {children}
                  {
                    subtext
                    && (
                      <>
                        <br />
                        <span
                          className={CheckControlBase.Subtext()}
                        >
                          {subtext}
                        </span>
                      </>
                    )
                  }
                </span>
                {
                  badge
                  && (
                    <>
                      {' '}
                      <span
                        className={ButtonBase.BadgeContainer(styleProps)}
                      >
                        {badge}
                      </span>
                    </>
                  )
                }
              </span>
            )
          }
        </label>
      </div>
    );
  },
);

Checkbox.displayName = 'ActionButton';
