/**
 * @file 滚动加载组件
 */

import React from 'react'
import { themeable, ThemeProps } from '../../../../theme'
import { localeable, LocaleProps, TranslateFn } from '../../../../locale'
import './index.scss'
import { Loading } from '../../../../components/ScrollMB/Loading';

interface InfinteSrollProps extends ThemeProps, LocaleProps {
  loadMore: () => void;
  hasMore: boolean;
  threshold?: number;
  hasData: boolean;
  tableRotate?: boolean;
  ns?: string;
  autoFillHeight?: boolean;
  loadmoreLoading?: boolean;
  tableLayout?: string
  loadDataOnce?: boolean
}


const InfiniteScrollContent = (props: { hasMore: boolean, translate: TranslateFn, loadMore: () => void, hasData: boolean, tableRotate?: boolean, loadmoreLoading?: boolean }) => {
  const { hasMore, translate: __, loadmoreLoading } = props;
  const renderContent = () => {
    return <>
      {hasMore ?
        loadmoreLoading && <div>
          <Loading />
          <span> 加载中...</span>
        </div>
        : (
          <span>{__('NoMore')}</span>
        )}
    </>
  }
  return renderContent()
}

function isElement(node: Element) {
  const ELEMENT_NODE_TYPE = 1
  return node.nodeType === ELEMENT_NODE_TYPE
}

const getScrollParent = (
  el: Element,
  root: any = window
) => {
  let node = el
  const overflowScrollReg = /scroll|auto|overlay/i

  while (node && node !== root && isElement(node)) {
    const { overflowY } = window.getComputedStyle(node)
    if (overflowScrollReg.test(overflowY)) {
      return node
    }
    node = node.parentNode as Element
  }

  return root
}

export class InfinteSroll extends React.Component<InfinteSrollProps, object> {
  static defaultProps = {
    hasMore: true,
    threshold: 250
  }
  elRef: any
  emptyRef: any
  parent: any
  checkTimer: any
  startY = 0
  scroll = true
  onMove = false
  offsetY = 0
  originWidth = 0

  constructor(props: InfinteSrollProps) {
    super(props)
    this.elRef = React.createRef()
    this.emptyRef = React.createRef()
  }

  componentDidUpdate(prevProps: InfinteSrollProps) {
    if (prevProps.loadmoreLoading === true && this.props.loadmoreLoading === false) {
      this.startLoading = false
    }
    if (prevProps.tableRotate !== this.props.tableRotate) {
      const element = this.elRef.current as HTMLDivElement;
      if (!element) return;
      element.style.width = this.props.tableRotate ? '100vh' : this.originWidth + 'px'
    }
  }

  startLoading = false;
  handleTouchstart = (e: any) => {
    const { hasMore } = this.props
    if (this.scroll) {
      if (!hasMore) {
        this.scroll = false
        this.onMove = true
      } else {
        this.onMove = false
      }
      this.offsetY = 0
    }
  }

  handleTouchend = (e: any) => {
    this.scroll = true
    if (this.offsetY === 0) return
    setTimeout(() => {
      this.emptyRef.current.style.height = '0px'
      this.emptyRef.current.style.transition = 'height 0.5s'
      this.offsetY = 0
    })
  }

  handleTouchmove = (e: any) => {
    if (this.offsetY == 0) {
      this.offsetY = e.touches[0].clientY
    }
    if (this.onMove && this.offsetY !== 0) {
      const height = this.offsetY - e.touches[0].clientY
      this.emptyRef.current.style.height = (height > 200 ? 200 : height) + 'px'
      this.emptyRef.current.style.transition = 'none'
    }
  }

  handleCheck = (e: any) => {
    const { loadMore, hasMore, loadmoreLoading, tableLayout, loadDataOnce } = this.props
    if (!loadMore || loadmoreLoading) return
    if (this.scroll && (tableLayout !== 'horizontal' || !loadDataOnce)) {
      if (e.target.scrollHeight - e.target.offsetHeight == this.parent.scrollTop && !hasMore) {
        this.scroll = false
        this.onMove = true
      } else {
        this.onMove = false
      }
      this.offsetY = 0
    }

    // clearTimeout(this.checkTimer)
    // this.checkTimer = setTimeout(() => {
    if (!hasMore) return
    const element = this.elRef.current
    if (!this.parent) return
    const rect = element.getBoundingClientRect()
    const elementTop = rect.top
    const current = this.parent === window
      ? window.innerHeight
      : this.parent.getBoundingClientRect().bottom;
    if (current >= elementTop - 75 && (this.parent?.scrollTop + this.parent?.clientHeight - this.parent?.scrollHeight > -75)) {
      this.startLoading = true;
      loadMore()
    }
    // }, 20)

  }

  componentDidMount() {
    const { autoFillHeight, classPrefix: ns, tableLayout, loadDataOnce } = this.props;
    const element = this.elRef.current as HTMLDivElement;
    if (!element) return;
    let previousWidth = element.previousElementSibling?.clientWidth;

    if (!previousWidth) {
      previousWidth = element.closest(`.${ns}Tabs-content`)?.clientWidth || 0
    }

    if (!previousWidth) {
      previousWidth = element.parentElement?.clientWidth || 0;
    }

    element.style.width = previousWidth + 'px'
    this.originWidth = previousWidth - 20;
    // 获取滚动的dom
    this.parent = element.closest(autoFillHeight ? `.${ns}Table-content` : `.${ns}Drawer-body`) || element.closest(`.${ns}Cards-content`) || element.closest(`.${ns}List-items`) || element.closest(`.${ns}Page-body`)
    this.parent?.addEventListener('scroll', this.handleCheck)

    if (tableLayout == 'horizontal' && loadDataOnce) return
    this.parent?.addEventListener('touchmove', this.handleTouchmove)
    this.parent?.addEventListener('touchstart', this.handleTouchstart)
    this.parent?.addEventListener('touchend', this.handleTouchend, false)
  }

  componentWillUnmount() {
    const { tableLayout, loadDataOnce } = this.props;
    this.parent?.removeEventListener('scroll', this.handleCheck)
    if (tableLayout == 'horizontal' && loadDataOnce) return
    this.parent?.removeEventListener('touchmove', this.handleTouchmove)
    this.parent?.removeEventListener('touchstart', this.handleTouchstart)
    this.parent?.removeEventListener('touchend', this.handleTouchend)
  }

  render() {
    let {
      hasMore,
      translate,
      loadMore,
      hasData,
      tableRotate,
      loadmoreLoading
    } = this.props

    return (<>
      <div ref={this.elRef} className='infinteSroll' style={{ position: 'sticky', left: 0 }}>
        <InfiniteScrollContent loadmoreLoading={loadmoreLoading} hasMore={hasMore} translate={translate} loadMore={loadMore} hasData={hasData} tableRotate={tableRotate} />
      </div>
      <div ref={this.emptyRef}></div>
    </>
    )
  }
}

export default themeable(localeable(InfinteSroll))
