import * as Sentry from '@sentry/react-native'
import * as Updates from 'expo-updates'
import { useUpdates } from 'expo-updates'
import { useCallback, useEffect, useState } from 'react'

import { Block, Text } from '@/@share/components'
import { useUpdateChecker } from '@/hooks/use-update-checker'

import { ProgressLine } from './progress'

export const HotUpdate = () => {
  const { hasUpdate = true } = useUpdateChecker()
  const [showUpdate, setShowUpdate] = useState(hasUpdate)
  const { isDownloading, isUpdatePending } = useUpdates()
  const [downloadProgress, setDownloadProgress] = useState(0)

  useEffect(() => {
    setShowUpdate(hasUpdate)
  }, [hasUpdate])

  useEffect(() => {
    Sentry.captureMessage('HotUpdate', {
      tags: {
        component: 'HotUpdate',
      },
      contexts: {
        update: {
          hasUpdate,
          isDownloading,
          isUpdatePending,
        },
      },
    })
    if (isDownloading) {
      const interval = setInterval(() => {
        setDownloadProgress((prev) => {
          if (prev >= 95) return prev
          const next = Number((prev + Math.random() * 10).toFixed(2))
          return Math.min(next, 100)
        })
      }, 300)
      return () => clearInterval(interval)
    }
  }, [isDownloading])

  useEffect(() => {
    if (isUpdatePending) {
      setDownloadProgress(100)
      setTimeout(() => {
        Updates.reloadAsync()
      }, 2000)
    }
  }, [isUpdatePending])

  const downloadAndApplyUpdate = useCallback(async () => {
    try {
      setDownloadProgress(0)
      await Updates.fetchUpdateAsync()
    } catch (error) {
      console.error('更新失败:', error)
      setShowUpdate(false)

      Sentry.captureMessage('HotUpdateError', {
        tags: {
          component: 'HotUpdate',
        },
        contexts: {
          update: {
            error: error instanceof Error ? error.message : '更新失败',
          },
        },
      })
    }
  }, [])

  useEffect(() => {
    if (showUpdate) {
      downloadAndApplyUpdate()
    }
  }, [showUpdate, downloadAndApplyUpdate])

  if (!showUpdate) return null
  return (
    <Block className="p-[10px]">
      <ProgressLine className="h-[5px] w-full" progress={downloadProgress} progressClassName="h-[5px]" />
      <Block className="mt-1 flex-row items-center justify-between px-1">
        <Text className="text-[12px]">
          {isDownloading ? '更新中' : downloadProgress >= 100 ? '更新成功' : '更新失败'}
        </Text>
        <Text className="text-[12px]">{downloadProgress}%</Text>
      </Block>
    </Block>
  )
}
