import { ThemeProps, themeable } from '../theme';
import React from 'react';
import { InputBoxProps } from './InputBox';
import { uncontrollable } from 'uncontrollable';
import { Icon } from './icons';
import Input from './Input';
import { autobind, isMobile, ucFirst, createObject } from '../utils/helper';
import {
  SchemaNode,
} from '../types';
import { LocaleProps, localeable } from '../locale';
import isPlainObject = require('lodash/isPlainObject');
import Popover from 'antd/lib/popover';
import { copy } from '../renderers/Lion/utils/utils';
import { message } from 'antd';
import { tools } from '../utils/shell/tools';

// 输入框展示结果组件 根据输入result类型进行不通展示

export interface ResultBoxProps
  extends ThemeProps,
  LocaleProps,
  Omit<InputBoxProps, 'result' | 'prefix' | 'onChange' | 'translate'> {
  onChange?: (value: string | any[]) => void;
  onResultClick?: (e: React.MouseEvent<HTMLElement>) => void;
  result?: Array<any> | any;
  itemRender: (value: any) => JSX.Element | string;
  onResultChange?: (value: Array<any>) => void;
  allowInput?: boolean;
  inputPlaceholder: string;
  useMobileUI?: boolean;
  // Jay 多选时，超过多少个折叠
  showCount?: number;
  // 配置支持labelTpl
  labelTpl?: string;
  render?: (region: string, node: SchemaNode, props?: any) => JSX.Element;
  loading?: boolean;
  //是否来自下拉框，样式区分
  // isSelect?: boolean;
}

export class ResultBox extends React.Component<ResultBoxProps> {
  static defaultProps: Pick<
    ResultBoxProps,
    'clearable' | 'placeholder' | 'itemRender' | 'inputPlaceholder'
  > = {
      clearable: false,
      placeholder: 'placeholder.noData',
      inputPlaceholder: 'placeholder.enter',
      itemRender: (option: any) => (
        <span>{`${option.scopeLabel || ''}${option.label}`}</span>
      )
    };

  state = {
    isFocused: false,
    detailPopoverVisible: false,
    // maxTagCount: undefined,
    curResult: [] // 暂态的结果数组保存
  };
  inputRef: React.RefObject<any> = React.createRef();

  containerRef: React.RefObject<HTMLDivElement> = React.createRef()
  divRef: React.RefObject<HTMLDivElement> = React.createRef()

  resizeObserver: ResizeObserver

  get labelTransfer() {
    const { render, labelTpl, result } = this.props;
    if (!labelTpl || !render) return (typeof result === 'object' ? result?.label : result);
    return render(`value`, labelTpl, {
      data: createObject(result)
    })
  }

  focus() {
    this.inputRef.current?.focus();
  }

  blur() {
    this.inputRef.current?.blur();
  }

  @autobind
  clearValue(e: React.MouseEvent<any>) {
    e.preventDefault();
    e.stopPropagation();
    const onResultChange = this.props.onResultChange;
    onResultChange?.([]);
  }

  @autobind
  handleFocus(e: any) {
    const onFocus = this.props.onFocus;
    onFocus && onFocus(e);
    this.setState({
      isFocused: true
    });
  }

  @autobind
  handleBlur(e: any) {
    const onBlur = this.props.onBlur;
    onBlur && onBlur(e);
    this.setState({
      isFocused: false
    });
  }

  @autobind
  removeItem(e: React.MouseEvent<HTMLElement>) {
    e.stopPropagation();
    e.preventDefault();
    const { result, onResultChange } = this.props;
    const index = parseInt(e.currentTarget.getAttribute('data-index')!, 10);
    const newResult = Array.isArray(result) ? result.concat() : [];
    newResult.splice(index, 1);
    onResultChange?.(newResult);
  }

  @autobind
  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    const { onChange } = this.props;
    onChange?.(e.currentTarget.value);
  }

  renderMultipeTags(tags: any[]) {
    const {
      itemRender,
      classnames: cx,
      translate: __
    } = this.props;

    return (
      <Popover
        trigger={'hover'}
        placement='top'
        className={cx('ResultBox-popover-value')}
        getPopupContainer={() => document.getElementById('amis-modal-container')! || document.body}
        overlayClassName={cx('ResultBox-overflow-overlay')}
        content={
          tools.isPc ? <div className={cx('ResultBox-overflow-wrapper')}>
            {tags?.length && tags?.length > 2 && <div className={cx('ResultBox-value')} key={'tags'}>
              <span className={cx('ResultBox-valueLabel')}>{tags?.length}</span>
            </div>}
            {tags.map((item, index) => (
              <div className={cx('ResultBox-value ResultBox-value-background')} key={index}>
                <span className={cx('ResultBox-valueLabel')} data-index={index} onClick={this.removeItem}>{
                  itemRender(item)
                }</span>
              </div>
            ))}
            <span onClick={async (e) => {
              e.stopPropagation();
              e.preventDefault();
              await copy(tags.map(item => item.label).join(','))
              message.success(__('System.copy'))
            }}>
              <Icon icon="copy" className="icon" />
            </span>
          </div> : null
        }
      >
        {tags.map((item, index) => <>
          {itemRender(item)} {tags.length - 1 !== index && ","}
        </>)}
      </Popover>
    )
    // return tags.map((item, index) => (
    //   <div className={cx('ResultBox-value')} key={index}>
    //     <span className={cx('ResultBox-valueLabel')}>{itemRender(item)}</span>
    //     {!isMobile() && <a data-index={index} onClick={this.removeItem}>
    //       <Icon icon="close" className="icon" />
    //     </a>}
    //   </div>
    // ));
  }

  render() {
    const {
      className,
      classnames: cx,
      classPrefix,
      clearable,
      disabled,
      hasError,
      result,
      value,
      placeholder,
      children,
      itemRender,
      allowInput,
      inputPlaceholder,
      labelTpl,
      onResultChange,
      onChange,
      onResultClick,
      translate: __,
      locale,
      onKeyPress,
      onFocus,
      onBlur,
      render,
      borderMode,
      useMobileUI,
      loading,
      // isSelect,
      ...rest
    } = this.props;

    const isFocused = this.state.isFocused;
    const mobileUI = useMobileUI && isMobile();
    return (
      <div
        className={cx('ResultBox', className, {
          'is-focused': isFocused,
          'is-disabled': disabled,
          'is-error': hasError,
          'is-clickable': onResultClick,
          'is-mobile': mobileUI,
          [`ResultBox--border${ucFirst(borderMode)}`]: borderMode
        })}
        onClick={onResultClick}
        tabIndex={!allowInput && !disabled && onFocus ? 0 : -1}
        onKeyPress={allowInput ? undefined : onKeyPress}
        onFocus={allowInput ? undefined : onFocus}
        onBlur={allowInput ? undefined : onBlur}
        ref={this.containerRef}
      >
        <div ref={this.divRef} className={cx('ResultBox-value-wrap')}>
          {Array.isArray(result) && result.length ? (
            this.renderMultipeTags(result)
          ) : result && !Array.isArray(result) ? (
            <span className={cx('ResultBox-singleValue')}>
              {isPlainObject(result) ? itemRender(result) : result}
            </span>
          ) : allowInput && !disabled ? null : (
            <span className={cx('ResultBox-placeholder')}>
              {__(placeholder || 'placeholder.noData')}
            </span>
          )}

          {allowInput && !disabled ? (
            <Input
              {...rest}
              className={cx('ResultBox-value-input')}
              onKeyPress={onKeyPress}
              ref={this.inputRef}
              value={value || ''}
              onChange={this.handleChange}
              placeholder={__(
                /** 数组模式下输入内容后将不再展示placeholder */
                Array.isArray(result)
                  ? result.length > 0
                    ? inputPlaceholder
                    : placeholder
                  : result
                    ? ''
                    : placeholder
              )}
              onFocus={this.handleFocus}
              onBlur={this.handleBlur}
            />
          ) : null}


        </div>
        {children}

        {clearable &&
          !disabled && !mobileUI &&
          (Array.isArray(result) ? result.length : result) ? (
          <a onClick={this.clearValue} className={cx('ResultBox-clear')}>
            <Icon icon="close" className="icon" />
          </a>
        ) : null}
        {!allowInput && mobileUI ? (
          <span className={cx('ResultBox-arrow arrow-bold')}>
            <Icon icon="right-arrow-bold" className="icon" style={{ fontSize: '10px', color: "#0003" }} />
          </span>
        ) : null}
      </div>
    );
  }
}

export default themeable(
  localeable(
    uncontrollable(ResultBox, {
      value: 'onChange',
      result: 'onResultChange'
    })
  )
);
