import { observer } from 'mobx-react';
import React, { CSSProperties } from 'react';
import {
  BoxSizeStyles,
  ButtonAppearanceOptions
} from '../../styles/defaults/themes.interface';
import { Button, ButtonProps, ButtonStyles } from '../Button';
import { useApphouse } from '../../context/useApphouse';
import { IconSizes } from '../../styles/defaults/app.token.values';
import { PromptFilename } from '../../templates/PromptFilename';
import { saveContentAs } from '../../utils/file/saveContentAs';
import { getAnimatedDownloadButtonStyles } from '../../styles/getAnimatedDownloadButtonStyles';
import { css } from 'glamor';
import { merge } from '../..';
import { BiDownload } from 'react-icons/bi';

export interface ButtonDownloadStyles {
  /**
   * The styles for the button
   * @optional
   * @default {}
   */
  button?: ButtonStyles;
  /**
   * The styles for the icon
   */
  icon?: CSSProperties;
  /**
   * The styles for the text
   */
  text?: CSSProperties;
}

export interface ButtonDownload extends ButtonProps {
  /**
   * The content of the file
   */
  content: string;
  /**
   * The name you want to save your file as
   * if promptFilename is true, this will be ignored in favor of the user filename
   */
  filename: string;
  /**
   * Variant of the button
   * @default 'primary'
   * @optional
   */
  variant?: ButtonAppearanceOptions;
  /**
   * The size of the icon
   * @default m
   * @optional
   */
  iconSize?: keyof typeof IconSizes;
  /**
   * The content of the button
   */
  children?: React.ReactNode;
  /**
   * If true, the user will be prompted to specify the filename
   * @optional
   * @default false (current date will be used)
   */
  promptFilename?: boolean;
  /**
   * The extension of the file
   * @required if promptFilename is true
   * if not provided, the extension will be txt
   */
  extension?: string;
  size?: keyof BoxSizeStyles;
  /**
   * The width of the button
   * @optional
   * @default 100
   */
  width?: string | number;
  /**
   * if true, all animations and will be reset and the button will be rendered as a simple button
   * @default false
   */
  raw?: boolean;
}
export const ButtonDownload: React.FC<ButtonDownload> = observer(
  ({
    variant = 'primary',
    filename,
    content,
    children = 'Download',
    size,
    title,
    iconSize,
    promptFilename,
    width = 'auto',
    raw = false,
    extension,
    gutters,
    ...rest
  }) => {
    const {
      theme: { styles, tokens },
      alert,
      closePopup,
      openPopup
    } = useApphouse();

    const onConfirm = (userFilename: string) => {
      saveContentAs(
        content,
        `${userFilename || filename || new Date().getTime()}`,
        extension
      );
      alert({
        message: 'Download started',
        variant: 'success'
      });
      closePopup();
    };

    const onButtonClick = () => {
      if (promptFilename) {
        openPopup(<PromptFilename onConfirm={onConfirm} gutters={20} />);
      } else {
        saveContentAs(
          content,
          `${filename || new Date().getTime()}`,
          extension
        );
      }
    };

    const localStyles = merge(
      {},
      { ...styles.boxSize[iconSize || 'm'] },
      {
        ...getAnimatedDownloadButtonStyles({
          width,
          buttonStyles: styles.button,
          variant
        })
      },
      { ...rest.styleOverwrites }
    );

    const _iconSize = tokens.iconSize[size || 'm'] as number;

    return (
      <Button
        title={title}
        variant={variant}
        size={size}
        onClick={onButtonClick}
        className="button"
        gutters={gutters}
        {...css(localStyles.button)}
      >
        {raw ? (
          children
        ) : (
          <>
            <span
              className="ah-button-download-wrapper"
              {...css(localStyles.buttonWrapper)}
              data-style="buttonWrapper"
            >
              <span
                className="ah-text"
                {...css(localStyles.text)}
                data-style="text"
              >
                {children || <BiDownload size={_iconSize} />}
              </span>
              <span
                className="ah-icon"
                {...css(localStyles.icon)}
                data-style="icon"
              >
                {<BiDownload size={_iconSize} />}
              </span>
            </span>
          </>
        )}
      </Button>
    );
  }
);
