import PropTypes from 'prop-types'
import { useContext, useEffect, useState, useRef, useCallback } from 'react'
import { Input, Result, Typography, Flex, Progress } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import { ApiServerContext } from '../../context/ApiServerContext'
import CopyButton from '../../common/CopyButton'
import OTPIcon from '../../../Icons/OTPIcon'

const { Text } = Typography

const HostOTP = ({ id }) => {
  const { fetchHostOTP } = useContext(ApiServerContext)
  const [hostObject, setHostObject] = useState(null)
  const [loading, setLoading] = useState(true)
  const [timeRemaining, setTimeRemaining] = useState(0)
  const [totalTime, setTotalTime] = useState(0)
  const [initialized, setInitialized] = useState(false)
  const intervalRef = useRef(null)

  const fetchNewOTP = useCallback(() => {
    setLoading(true)
    setHostObject(null) // Reset to show loading
    fetchHostOTP(id, (hostOTPObject) => {
      setHostObject(hostOTPObject)
      setLoading(false)

      if (hostOTPObject?.otpExpiresAt) {
        const now = Date.now()
        const expiresAt = new Date(hostOTPObject.otpExpiresAt).getTime()
        const remaining = Math.max(0, expiresAt - now)

        setTimeRemaining(remaining)
        setTotalTime(remaining)
      }
    })
  }, [id, fetchHostOTP])

  useEffect(() => {
    if (hostObject === null && initialized == false) {
      setInitialized(true)
      fetchNewOTP()
    }
  }, [id, fetchNewOTP, initialized, hostObject])

  useEffect(() => {
    if (hostObject && timeRemaining > 0) {
      intervalRef.current = setInterval(() => {
        setTimeRemaining((prev) => {
          const newTime = prev - 1000
          if (newTime <= 0) {
            // OTP expired, fetch a new one
            fetchNewOTP()
            return 0
          }
          return newTime
        })
      }, 1000)

      return () => {
        if (intervalRef.current) {
          clearInterval(intervalRef.current)
        }
      }
    }
  }, [hostObject, timeRemaining, fetchNewOTP])

  // Clean up interval on unmount
  useEffect(() => {
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current)
      }
    }
  }, [])

  const progressPercent =
    totalTime > 0 ? Math.max(0, (timeRemaining / totalTime) * 100) : 0

  return (
    <Flex vertical align='center'>
      <Result
        title={'Connect a Host.'}
        subTitle={<Text>Enter the following one time passcode.</Text>}
        icon={<OTPIcon />}
      >
        <Flex justify='center'>
          <Flex gap={'small'} align='center' justify='center'>
            <div>
              <Input.OTP
                disabled={loading}
                size='large'
                value={hostObject?.otp}
                onChange={(e) => e.preventDefault()} // prevent typing
                onKeyDown={(e) => e.preventDefault()} // prevent key input
                onPaste={(e) => e.preventDefault()} // prevent pasting
              />
            </div>
            <CopyButton
              size='default'
              text={hostObject?.otp}
              disabled={loading}
            />
            <div style={{ margin: '0 6px 0 8px', paddingBottom: '5px' }}>
              {loading ? (
                <Text>
                  <LoadingOutlined />
                </Text>
              ) : (
                <Progress
                  type='circle'
                  showInfo={false}
                  strokeColor='#32D74B'
                  size={14}
                  strokeWidth={14}
                  percent={progressPercent}
                />
              )}
            </div>
          </Flex>
        </Flex>
      </Result>
    </Flex>
  )
}

HostOTP.propTypes = {
  id: PropTypes.string.isRequired
}

export default HostOTP
