import moment from 'moment'
import { useState, useEffect, memo, ReactNode } from 'react'
import {CaretUpOutlined, CaretDownOutlined, CaretRightOutlined} from '@ant-design/icons'

import '@styles/display.less'

export const formatNumber = (value?: unknown, format?: number) =>
  Number.isInteger(format) && Number.isFinite(value)
  ? Number(value).toFixed(format)
  : Number(value).toPrecision(4)

const iconStyle = { color:'#0008' }
const displayValueStyle = { display: 'flex', flexGrow: 1 }

export type ValueDisplayProps = {
  prefix?: ReactNode
  suffix?: ReactNode
  format?: number | string | ((arg: string) => ReactNode)
  isArrowVisible?: boolean
  enumeration?: Record<string, string>
  value: string
}

export type DisplayProps = ValueDisplayProps & {
  className?: string
  label?: ReactNode
}

export const ValueDisplay = memo<ValueDisplayProps>(({ prefix, value, suffix, isArrowVisible, format, enumeration }) => {
  const [val, setVal] = useState<ReactNode>('---')
  const [arrowState, setArrowState] = useState({
    preVal: NaN,
    preTimestamp: Date.now(),
    direction: 0,
  })

  useEffect(() => {
    setVal((preVal) => {
      if ((value ?? '-') === '-' || value === '--') return '---'
      if (typeof format === 'function') return format(enumeration?.[value] ?? value)
      if (enumeration?.[value]) return enumeration[value]

      if (Number.isFinite(+value)) {
        if (isArrowVisible && (arrowState.preTimestamp + 1000 < Date.now())) {
          let direction = 0
          if (+value > arrowState.preVal)
            direction = 1
          if (+value < arrowState.preVal)
            direction = -1

          setArrowState({
            preVal: +value,
            preTimestamp: Date.now(),
            direction: direction,
          })
        }

        return formatNumber(value, Number(format))
      }

      if (value.length > 4) {
        const valueDate = moment(value)
        if (valueDate.isValid())
          return valueDate.format(String(format))
      }

      return value
    })
  },[value, isArrowVisible, arrowState, format, enumeration])

  let arrow = null
  if(isArrowVisible)
    switch  (arrowState.direction){
      case 0:
        arrow = <CaretRightOutlined style={iconStyle}/>
        break
      case 1:
        arrow = <CaretUpOutlined style={iconStyle}/>
        break
      case -1:
        arrow = <CaretDownOutlined style={iconStyle}/>
        break
      default:
        break
    }

  return(
    <span className={'display_value'}>
      {prefix} {val} {suffix}{arrow}
    </span>
  )
})

export const Display = memo<DisplayProps>(({ className, label, ...other })=> (
  <div className={className}>
    <div className={'display_label'}>{label}</div>
    <div style={displayValueStyle}>
      <ValueDisplay {...other}/>
    </div>
  </div>
))
