/** @jsx createElement */
import { createElement, CSSProperties, forwardRef, HTMLAttributes, RaxNode, RefForwardingComponent } from 'rax';
import ScrollView from 'rax-scrollview';
import Image from 'rax-image';
import { StyledComponentProps, useStyles } from '@rax-ui/styles';
import Drawer from '@rax-ui/drawer';
import Icon from '@rax-ui/icon';
import { LocaledComponentProps, useLocale } from '@rax-ui/locale';
import View from 'rax-view';
import Text from 'rax-text';
import StyleProvider from './style';

export interface ActionSheetButtonProps {
  text?: string;
  style?: object;
  textStyle?: object;
  onClick?: (e: any) => void;
  [propName: string]: any;
}

export interface ActionSheetItemProps {
  image?: string;
  icon?: string;
  text?: string;
  style?: CSSProperties;
  textStyle?: CSSProperties;
  mediaStyle?: CSSProperties;
  onClick?: (e: any) => void;
  [propName: string]: any;
}

interface HTMLAttributesWeak extends HTMLAttributes<HTMLElement> {
  onClick?: any;
}

export interface LocaleType {
  cancel?: string;
}

export interface ActionSheetProps extends
  StyledComponentProps<any>,
  LocaledComponentProps<LocaleType>,
  HTMLAttributesWeak {
  visible: boolean;
  title?: string;
  fullWidth?: boolean;
  cancelButton?: ActionSheetButtonProps;
  buttons?: ActionSheetButtonProps[];
  items?: ActionSheetItemProps[][];
  onClick?: (index: number, colIndex?: number, e?: any) => void;
  onUnmount?: () => void;
  onShow?: () => void;
  onHide?: (reason: string) => void;
  renderContent?: () => RaxNode;
  onEnter?: () => void;
  onExit?: () => void;
  onEntering?: () => void;
  onExiting?: () => void;
  onEntered?: () => void;
  onExited?: () => void;
  onClose?: (reason: string, e: any) => void;
}

const ActionSheet: RefForwardingComponent<any, ActionSheetProps> = (props, ref) => {
  const {
    visible,
    title,
    fullWidth,
    renderContent,
    cancelButton = {},
    buttons = [],
    items = [],
    onClick = () => {},
    onUnmount,
    onShow,
    onHide,
    ...others
  } = props;

  const locale = useLocale('ActionSheet', others, { cancel: '取消' });

  const styles = useStyles(StyleProvider, others, (classNames) => {
    return {
      root: classNames(['action-sheet', fullWidth ? 'action-sheet__fullwidth' : null]),
      body: classNames(['action-sheet__body', fullWidth ? 'action-sheet__body__fullwidth' : null]),
      footer: classNames(['action-sheet__footer', fullWidth ? 'action-sheet__footer__fullwidth' : null]),
      drawer: fullWidth ? classNames('action-sheet__fullwidth_drawer') : null,
      title: classNames('action-sheet__title'),
      titleText: classNames('action-sheet__title__text'),
      content: classNames('action-sheet__content'),
      button: classNames('action-sheet__button'),
      buttonFirst: classNames('action-sheet__button--first'),
      buttonText: classNames('action-sheet__button__text'),
      gallery: classNames('action-sheet__gallery'),
      galleryContainer: classNames('action-sheet__gallery__container'),
      galleryItem: classNames('action-sheet__gallery__item'),
      galleryItemCell: classNames('action-sheet__gallery__item-cell'),
      galleryItemIcon: classNames('action-sheet__gallery__item-icon'),
      galleryItemText: classNames('action-sheet__gallery__item-text'),
      cancel: classNames(['action-sheet__button', 'action-sheet__button--first', 'action-sheet__cancel']),
      cancelText: classNames(['action-sheet__button__text', 'action-sheet__cancel__text']),
      active: classNames('action-sheet__button--active'),
    };
  });

  const handleClick = (...args) => {
    // @ts-ignore
    onClick(...args);
    // @ts-ignore
    onHide('buttonClick');
  };

  return (
    <Drawer
      {...others}
      visible={visible}
      placement="bottom"
      onHide={onHide}
      onShow={onShow}
      bgTransparent
      onUnmount={onUnmount}
      ref={ref}
      styles={{
        'drawer--bottom': styles.drawer,
      }}
    >
      <View style={styles.root}>
        <View style={styles.body}>
          {title ? (
            <View style={styles.title}>
              <Text style={styles.titleText}>{title}</Text>
            </View>
          ) : null}
          <View style={styles.content}>
            {
              renderContent ?
                renderContent() :
                  items && items.length > 0 ?
                    items.map((array, i) => {
                      return (
                        <ScrollView horizontal style={styles.gallery} contentContainerStyle={styles.galleryContainer}>
                          {
                            array.map((item, j) => {
                              return (
                                <View onClick={(e) => {
                                  if (item.onClick) {
                                    item.onClick(e);
                                  }
                                  handleClick(i, j, e);
                                }} style={styles.galleryItem}>
                                  <View style={{...styles.galleryItemCell, ...(item.style || {})}}>
                                    {
                                      item.image ? (
                                        <Image
                                          source={{ uri: item.image}}
                                          style={{
                                            width: styles.galleryItemCell.width,
                                            height: styles.galleryItemCell.height,
                                            ...(item.mediaStyle || {}),
                                          }}
                                        />
                                      ) : (
                                        <Icon
                                          name={item.icon}
                                          style={{
                                            ...styles.galleryItemIcon,
                                            ...(item.mediaStyle || {}),
                                          }}
                                        />
                                      )
                                    }
                                  </View>
                                  {
                                    item.text  ? (
                                      <Text
                                        style={{
                                          ...styles.galleryItemText,
                                          ...item.textStyle,
                                        }}
                                      >{item.text}</Text>
                                    ) : null
                                  }
                                </View>
                              );
                            })
                          }
                        </ScrollView>
                      );
                    }) :
                    buttons.map((button, i) => (
                      <View
                        key={i}
                        style={{
                          ...styles.button,
                          ...i ? null : styles.buttonFirst,
                          ...button.style,
                        }}
                        onClick={(e) => {
                          if (!!button.onClick) {
                            button.onClick(e);
                          }
                          handleClick(i, e);
                        }}
                      >
                        <Text
                          style={{
                            ...styles.buttonText,
                            ...button.textStyle,
                          }}
                        >
                          {button.text}
                        </Text>
                      </View>
                    ))
              }
          </View>
        </View>
        <View style={styles.footer}>
          <View
            style={{
              ...styles.cancel,
              ...cancelButton.style,
            }}
            onClick={() => onHide('cancelClick')}
          >
            <Text
              style={{
                ...styles.cancelText,
                ...cancelButton.textStyle,
              }}
            >
              {cancelButton.text || locale.cancel}
            </Text>
          </View>
        </View>
      </View>
    </Drawer>
  );
};

export default forwardRef<any, ActionSheetProps>(ActionSheet);
