import React, { useEffect, useState } from 'react'

import { Box, BoxProps } from '../box'
import { styled, useStyleConfig, vui } from '../core'
import { T } from '../t'
import { cs } from '../utils'
import { absCenterStyles, labelBottom, maxValue } from './consts'
import { ProgressCircularProps } from './progressCircular.types'

export const ProgressCircularBase = styled.divBox`
  display: flex;
  position: relative;
  width: 100%;
`
const MainCircle = styled.circle`
  fill: transparent;
`

const ProgressCircle = styled(MainCircle)`
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  transition: stroke-dashoffset 0.5s ease-out;
`

/** Indicates a process progress. */
export const ProgressCircular = vui<'div', ProgressCircularProps>((props, ref) => {
  const { children, className, label, value = 0, showPercentage, ...rest } = props

  const styles = useStyleConfig('ProgressCircular', props)

  const [progress, setProgress] = useState(value)

  useEffect(() => {
    setProgress(value ? Math.ceil(value) : 0)
  }, [value])

  useEffect(() => {
    const w = !value ? 0 : Math.ceil(value)
    setProgress(w > maxValue ? maxValue : w)
  }, [value])

  const radius = maxValue / 2 - styles.strokeWidth * 2
  const angle = radius * 2 * Math.PI
  const offset = angle - (progress / maxValue) * angle

  return (
    <ProgressCircularBase className={cs('vui-progress-circular', className)} ref={ref} w={styles.width} {...rest}>
      <svg
        aria-valuemax={maxValue}
        aria-valuemin={0}
        aria-valuenow={progress}
        height={styles.width}
        role="meter"
        version="1.1"
        viewBox="0 0 100 100"
        width={styles.width}
        xmlns="http://www.w3.org/2000/svg"
      >
        <MainCircle cx="50" cy="50" r={radius} stroke={styles.stroke.main} strokeWidth={styles.strokeWidth} />
        <ProgressCircle
          cx="50"
          cy="50"
          r={radius}
          stroke={styles.stroke.progress}
          strokeDasharray={`${angle} ${angle}`}
          strokeDashoffset={offset}
          strokeWidth={styles.strokeWidth}
        />
      </svg>
      <Box {...(absCenterStyles as BoxProps)} top={styles.top}>
        {children ? (
          children
        ) : showPercentage ? (
          <T color={styles.color} fontSize={styles.fontSize}>
            {progress}%
          </T>
        ) : null}
      </Box>
      {!!label && (
        <Box {...(absCenterStyles as BoxProps)} bottom={labelBottom}>
          <T color={styles.color} fontSize={styles.fontSize}>
            {label}
          </T>
        </Box>
      )}
    </ProgressCircularBase>
  )
})

ProgressCircular.displayName = 'ProgressCircular'
export default ProgressCircular
