import React from 'react';
import { RendererProps, Renderer, render as renderAmis } from '../../factory';
import QuickEdit from '../QuickEdit';
import Copyable from '../Copyable';
import PopOverable from '../PopOver';
import { inject, observer } from 'mobx-react';
import omit = require('lodash/omit');
import { evalExpression, filter } from '../../utils/tpl';
import { Badge } from '../../components/Badge';
import { IColumn } from '../../store/table';

import { linkJump, ModleHandleClick } from '../../utils/utils';
import { isMobile } from '../../utils/helper';

export interface TableCellProps extends RendererProps {
  wrapperComponent?: React.ReactType;
  tdVisialbe: boolean;
  column: object;
}

export class TableCell extends React.Component<RendererProps> {
  static defaultProps = {
    wrapperComponent: 'td'
  };

  static propsList: Array<string> = [
    'type',
    'label',
    'column',
    'body',
    'tpl',
    'rowSpan',
    'remark'
  ];
  state = {
    tdVisialbe: false
  }

  tdRef = React.createRef<HTMLElement>()
  intersection: {
    preIntersectionRatio?: number;
    curIntersectionRatio?: number;
    observer?: any
  } = {} // 元素可见性观察器

  constructor(props: RendererProps) {
    super(props)
    this.state.tdVisialbe = false
  }

  // componentDidMount() {
  //   // 自动聚焦观察器

  //   // 如果需要保持focus状态 - 再元素第一次发生 不可见-> 可见状态时自动聚焦
  //   if (this.props.style?.position !== 'fixed')
  //     this.intersection.observer = new IntersectionObserver(([entry]) => {

  //       // this.intersection.preIntersectionRatio = this.intersection.curIntersectionRatio || 0 // 默认值适用
  //       // this.intersection.curIntersectionRatio = entry.intersectionRatio
  //       // 意为出现了部分元素聚焦 并且没有定时器 适用自动聚焦
  //       console.log(this.tdRef, entry)
  //       if (entry.isIntersecting) {
  //         // 如果需要持续聚焦，只要没有值就取消聚焦-可见状态才适用聚焦
  //         this.setState({ tdVisialbe: true })
  //       } else {
  //         this.setState({ tdVisialbe: false })
  //       }
  //     })
  //   if (this.tdRef.current)
  //     this.intersection.observer.observe(this.tdRef.current)
  // }

  // componentWillUnmount() {
  //   // 用完销毁
  //   if (this.intersection.observer) this.intersection.observer?.disconnect?.()
  // }

  render() {

    let {
      classnames: cx,
      className,
      classNameExpr,
      render,
      style,
      wrapperComponent: Component,
      column,
      value,
      data,
      children,
      width,
      align,
      innerClassName,
      label,
      tabIndex,
      onKeyUp,
      rowSpan,
      body: _body,
      tpl,
      remark,
      prefixContent,
      affix,
      isHead,
      rowIndex,
      colIndex,
      row,
      showBadge,
      itemBadge,
      $path,
      ellipsis,
      fold,
      // showContextMenu,
      name,
      setBorder,
      defaultOpen,
      linkUrl,
      linkId,
      quickEdit,
      tableLayout,
      tableCtxMenuStore,
      tableId,
      // store,
      ...rest
    } = this.props;

    const schema = {
      ...column,
      className: innerClassName,
      type: (column && column.type) || 'plain'
    };

    // 如果本来就是 type 为 button，不要删除，其他情况下都应该删除。
    if (schema.type !== 'button' && schema.type !== 'dropdown-button') {
      delete schema.label;
    }

    // Jay
    // 对于input-table-dynamic组件的原始数据做判断
    const isInputTableDynamic = /(input-table-dynamic)/.test($path)
    const isOrigin = data.isOrigin && isInputTableDynamic
    const domicile = {
      column,
      data,
      label,
    }


    let body = children
      ? children
      :
      render('field', schema, {
        fold,
        ...omit(rest, Object.keys(schema)),
        // inputOnly: true,
        style: {},
        value,
        data,
        // Jay
        // data.isOrigin是针对于input-table-dynamic组件的原始数据不能修改
        inputOnly: data.isOrigin ? !isOrigin : true,
        disabled: isOrigin,
        className: cx(innerClassName, { 'text-secondary': isOrigin }),
        domicile
      });


    //字段分组
    if (column.group?.length) {
      body = column.group.map((item: IColumn & {
        body?: IColumn[], hideLabel?: boolean, align?: any, format?: string, textRow?: number, linkId?: string, linkUrl?: string, jumpDisabledOn?: string
      }) => {
        let ass = renderAmis({
          type: item.type ?? '',
          name: item.name,
          body: item?.body
        }, { data })
        const showTitle = !!data[item.name ?? ''] && typeof data[item.name ?? ''] === ('string' || 'number')
        const canJump = linkJump(item.linkId ?? '', data, item.jumpDisabledOn)
        const textRowStyle = item.textRow ? {
          overflow: 'hidden',
          textOverflow: 'ellipsis',
          display: '-webkit-box',
          '-webkit-box-orient': 'vertical',
          'WebkitLineClamp': item.textRow + '',
        } : {}

        return (<div
          key={item.name}
          className={`group-field-container ${item.linkUrl && canJump ? 'is-linkUrl' : ''}`}
          title={showTitle ? data[item.name ?? ''] : null}
          style={{ textAlign: item.align, whiteSpace: item.format === 'autoHeight' ? 'pre-wrap' : undefined, ...textRowStyle }}
          onClick={e => {
            if (canJump) {
              e.stopPropagation()
              ModleHandleClick({ ...this.props, ...item }, e.target)
            }
          }}
        >
          {item?.hideLabel ? '' : item.label + '：'}
          {item.type ? ass : data[item.name ?? '']}
        </div>)
      })
    }

    if (width) {
      style = {
        ...style,
        width: (style && style.width) || width
      };

      if (!/%$/.test(String(style.width))) {
        body = (
          <div className={ellipsis ? 'ellipsis' : ''}>
            {prefixContent}
            {body}
            {affix}
          </div>
        );
        prefixContent = null;
        affix = null;
        // delete style.width;
      }
    }

    if ((!width || !column.type) && column.type !== 'operation') {
      style = {
        ...style,
        maxWidth: (isMobile() && tableLayout && tableLayout == 'vertical') ? '' : 200
      }
    }

    if (align) {
      style = {
        ...style,
        textAlign: (isMobile() && tableLayout && tableLayout == 'vertical') ? "left" : align
      };
    }

    if (!Component) {
      return body as JSX.Element;
    }

    if (isHead) {
      Component = 'th';
    }

    const canJumpUrl = linkJump(linkId, data, column.jumpDisabledOn)

    return (<>
      {/*  chencicsy 用于执行复制操作 */}
      {
        <Component
          // ref={this.tdRef}
          table-name={this.props.tableName ?? this.props.crudName}
          column-name={name}
          onContextMenu={(e: any) => {
            e.preventDefault()
            tableCtxMenuStore.showContextMenu(rowIndex, name || column.name, tableId);
          }}
          rowSpan={rowSpan > 1 ? rowSpan : undefined}
          style={style}
          className={cx(
            className,
            column.classNameExpr ? filter(column.classNameExpr, data) : null,
            setBorder ? 'td-border' : '',
            linkUrl && canJumpUrl ? 'is-linkUrl' : '',
          )}
          // onMouseLeave={() => {
          //   setTimeout(() => { (this.props.store as any)?.removeVisitMap?.(`${rowIndex}/${colIndex}`) }, 200)
          // }}
          tabIndex={tabIndex}
          onKeyUp={onKeyUp}
          // title={!defaultOpen ? null : (data[column.name || ''] || null)}
          onClick={(e: any) => {
            if (canJumpUrl) {
              e.stopPropagation()
              !quickEdit && ModleHandleClick(this.props, e.target)
            }
          }}
        >
          {/* 可见 fixed的不检查可见性 或者是表头的都是默认渲染 */}
          {/* {this.state.tdVisialbe ? <> */}
          {showBadge ? (
            <Badge
              classnames={cx}
              badge={{
                ...itemBadge,
                className: cx(`Table-badge`, itemBadge?.className)
              }}
              data={row.data}
            />
          ) : null}
          {prefixContent}
          {body}
          {affix}
          {/* </> : null} */}
        </Component>
      }
    </>
    );
  }
}


@Renderer({
  type: 'simple-table-cell',
  name: 'simple-table-cell'
})
@inject('tableCtxMenuStore')
@observer
export class SimpleTableCellRenderer extends TableCell {
  static propsList = TableCell.propsList
}

@Renderer({
  test: /(^|\/)(table|cross|lion-bi-table|field-table-horizontal)\/(?:.*\/)?cell$/,
  name: 'table-cell'
})
@QuickEdit()
@PopOverable({
  targetOutter: true
})
@Copyable()
@observer
export class TableCellRenderer extends TableCell {
  static propsList = [
    'quickEdit',
    'quickEditEnabledOn',
    'popOver',
    'copyable',
    'inline',
    ...TableCell.propsList
  ];
}

@Renderer({
  type: 'field',
  name: 'field'
})
@PopOverable()
@Copyable()
export class FieldRenderer extends TableCell {
  static defaultProps = {
    ...TableCell.defaultProps,
    wrapperComponent: 'div'
  };
}
