import React, { useRef, useEffect, useCallback } from 'react';
import { XStack, useTheme } from 'tamagui';
import { TouchableOpacity, StyleSheet } from 'react-native';
import dayjs from 'dayjs';
// 考勤统计、日历与认证 store
import { useStatisticsStore, useCalendarStore, useAuthStore } from '@/stores';
// 考勤接口函数
import { ServeCollectionDates, ServeCollectionDetail } from '@/api/attendance';
// 日期工具函数（周范围、区间构造）
import { getDateRangeInclusive, getAttendanceWeeksInAttendanceMonth } from '@/utils/time/dateUtils';

// UI组件
import CustomText from '@/components/common/CustomText';
import LoadingSpinner from '@/components/ui/LoadingSpinner';
import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';

// 国际化
import { useTranslation } from '@/node_modules/react-i18next';

// 引入屏幕适配
import { wp, sp } from '@/utils/ui/screenUtils';

const LastUpdateView = () => {
  //获取主题色
  const theme = useTheme()
  const primaryColor = theme.primary.val

  //国际化
  const { t, i18n } = useTranslation('attendance');

  // 读取接口加载状态与更新时间
  const lastUpdateTime = useStatisticsStore(s => s.lastUpdateTime)
  const loadingCount = useStatisticsStore(s => s.loadingCount)
  const isLoading = (loadingCount || 0) > 0
  // 读取静默刷新进行中计数，仅用于按钮禁用
  const revalidatingCount = useStatisticsStore(s => s.revalidatingCount)
  const isRevalidating = (revalidatingCount || 0) > 0

  // 局部菊花滑入动画（仅在静默刷新时显示）
  const spinnerSize = wp(12)
  const spinnerWidth = useSharedValue(0)
  useEffect(() => {
    spinnerWidth.value = withTiming(isRevalidating ? spinnerSize : 0, { duration: 180 })
  }, [isRevalidating, spinnerSize, spinnerWidth])
  const spinnerAnimStyle = useAnimatedStyle(() => ({
    width: spinnerWidth.value,
    overflow: 'hidden',
    alignItems: 'center',
  }))
  const gap = isRevalidating ? wp(6) : 0

  // 刷新控制与状态写入方法
  const activeStatisticsMode = useStatisticsStore(s => s.activeStatisticsMode)
  const incLoading = useStatisticsStore(s => s.incLoading)
  const decLoading = useStatisticsStore(s => s.decLoading)
  const setLastUpdateTime = useStatisticsStore(s => s.setLastUpdateTime)
  const setStatisticsDetail = useStatisticsStore(s => s.setStatisticsDetail)

  // 当前可见年月与选中周信息
  const dayVisibleYM = useCalendarStore(s => s.dayVisibleYM)
  const weekVisibleYM = useCalendarStore(s => s.weekVisibleYM)
  const weekSelectedMonday = useCalendarStore(s => s.weekSelectedMonday)
  const monthVisibleYM = useCalendarStore(s => s.monthVisibleYM)

  // 当前用户 UID
  const userInfo = useAuthStore(state => state.getUser())
  const targetStaffUID = userInfo?.ID

  // 手动刷新取消控制器（组件级）
  const manualRefreshAbortRef = useRef(null)

  // 模式切换时取消在途的刷新请求，避免跨模式写入
  useEffect(() => {
    if (manualRefreshAbortRef.current) {
      try { manualRefreshAbortRef.current.abort() } catch { }
      manualRefreshAbortRef.current = null
    }
  }, [activeStatisticsMode])

  // 组件卸载时清理在途请求，避免内存泄漏
  useEffect(() => {
    return () => {
      if (manualRefreshAbortRef.current) {
        try { manualRefreshAbortRef.current.abort() } catch { }
        manualRefreshAbortRef.current = null
      }
    }
  }, [])

  // 手动刷新：依据当前模式（日/周/月）构造请求，裁剪未来日期，并落盘
  const handleManualRefresh = useCallback(async () => {
    if (isLoading) return
    try {
      if (manualRefreshAbortRef.current) {
        try { manualRefreshAbortRef.current.abort() } catch { }
        manualRefreshAbortRef.current = null
      }
      const controller = typeof AbortController !== 'undefined' ? new AbortController() : null
      if (controller) manualRefreshAbortRef.current = controller
      const signal = controller?.signal

      incLoading()

      const mode = activeStatisticsMode
      if (mode === 'day') {
        // 日模式：构造月网格（含两侧补齐），裁剪未来日期，并携带 monthKey
        const year = dayVisibleYM?.year
        const month = dayVisibleYM?.month
        if (!year || !month) return
        const first = new Date(year, month - 1, 1)
        const last = new Date(year, month, 0)
        const wdMonFirst = (first.getDay() + 6) % 7
        const wdMonLast = (last.getDay() + 6) % 7
        const start = new Date(first)
        start.setDate(first.getDate() - wdMonFirst)
        const end = new Date(last)
        end.setDate(last.getDate() + (6 - wdMonLast))
        const dates = []
        for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
          const y = d.getFullYear()
          const m = String(d.getMonth() + 1).padStart(2, '0')
          const dd = String(d.getDate()).padStart(2, '0')
          dates.push(`${y}-${m}-${dd}`)
        }
        const mm = String(month).padStart(2, '0')
        const monthKey = `${year}-${mm}`
        const today = dayjs().startOf('day')
        const clippedDates = dates.filter((d) => !dayjs(d).isAfter(today, 'day'))
        if (dates.length > 0 && clippedDates.length === 0) {
          setStatisticsDetail({})
          setLastUpdateTime(Date.now())
          return
        }
        const payload = { collectionType: 23, staffUID: targetStaffUID, dates: clippedDates.length ? clippedDates : dates, monthKey }
        const res = await ServeCollectionDates(payload, signal ? { signal } : {})
        if (res && res.status === 0 && res.data && Object.keys(res.data).length) {
          setStatisticsDetail(res.data)
          setLastUpdateTime(Date.now())
        }
      } else if (mode === 'week') {
        // 周模式：定位选中周范围，裁剪未来日期，并携带 weekKey
        if (!weekVisibleYM?.year || !weekVisibleYM?.month || !weekSelectedMonday) return
        const weeks = getAttendanceWeeksInAttendanceMonth(weekVisibleYM.year, weekVisibleYM.month)
        const selected = weeks.find(w => w.startDate <= weekSelectedMonday && weekSelectedMonday <= w.endDate)
        if (!selected) return
        const dates = getDateRangeInclusive(selected.startDate, selected.endDate)
        const today = dayjs().startOf('day')
        const clippedDates = dates.filter((d) => !dayjs(d).isAfter(today, 'day'))
        if (dates.length > 0 && clippedDates.length === 0) {
          setStatisticsDetail({})
          setLastUpdateTime(Date.now())
          return
        }
        const weekKey = selected.startDate
        const payload = { collectionType: 23, staffUID: targetStaffUID, dates: clippedDates.length ? clippedDates : dates, weekKey }
        const res = await ServeCollectionDates(payload, signal ? { signal } : {})
        if (res && res.status === 0 && res.data && Object.keys(res.data).length) {
          setStatisticsDetail(res.data)
          setLastUpdateTime(Date.now())
        }
      } else if (mode === 'month') {
        // 月模式：未来自然月（且非“标签月”）短路；其余按月详情拉取
        if (!monthVisibleYM?.year || !monthVisibleYM?.month) return
        const mm = String(monthVisibleYM.month).padStart(2, '0')
        const monthStr = `${monthVisibleYM.year}-${mm}`
        const now = dayjs()
        const todayMonth = now.startOf('month')
        const targetMonth = dayjs(`${monthStr}-01`).startOf('month')
        const labelMonthStart = (now.date() >= 26 ? now.add(1, 'month') : now).startOf('month')
        const isFutureNaturalMonth = targetMonth.isAfter(todayMonth, 'month')
        const isLabelMonth = targetMonth.isSame(labelMonthStart, 'month')
        if (isFutureNaturalMonth && !isLabelMonth) {
          setStatisticsDetail({})
          setLastUpdateTime(Date.now())
          return
        }
        const payload = { collectionType: 23, staffUID: targetStaffUID, month: monthStr }
        const res = await ServeCollectionDetail(payload, signal ? { signal } : {})
        if (res && res.status === 0 && res.data && Object.keys(res.data).length) {
          setStatisticsDetail(res.data)
          setLastUpdateTime(Date.now())
        }
      }
    } catch (e) {
      // 静默失败
    } finally {
      manualRefreshAbortRef.current = null
      decLoading()
    }
  }, [isLoading, activeStatisticsMode, dayVisibleYM?.year, dayVisibleYM?.month, weekVisibleYM?.year, weekVisibleYM?.month, weekSelectedMonday, monthVisibleYM?.year, monthVisibleYM?.month, targetStaffUID])

  // 无更新时间时不渲染，保持最小行为变化
  if (!lastUpdateTime) return null

  return (
    <XStack style={styles.updateTextContainer}>
      <CustomText style={styles.updateText}>{t('teamAttendance.lastUpdatePrefix')} {dayjs(lastUpdateTime).format('YYYY-MM-DD HH:mm:ss')}</CustomText>
      <TouchableOpacity onPress={() => handleManualRefresh()} disabled={isLoading || isRevalidating}>
        <XStack
          alignItems="center"
          justifyContent="center"
          gap={gap}
          style={[
            styles.updateButton,
            { borderColor: primaryColor }
          ]}
        >
          <Animated.View style={spinnerAnimStyle}>
            <LoadingSpinner size={spinnerSize} color={primaryColor} animating={isRevalidating} />
          </Animated.View>
          <CustomText style={{ color: primaryColor, fontSize: sp(10), lineHeight: wp(14) }}>
            {t('btnText.refresh')}
          </CustomText>
        </XStack>
      </TouchableOpacity>
    </XStack>
  )
}

export default LastUpdateView

const styles = StyleSheet.create({
  updateTextContainer: {
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: wp(6),
  },
  updateText: {
    fontSize: sp(10),
    lineHeight: wp(14),
    color: '#bababa',
  },
  updateButton: {
    fontSize: sp(10),
    borderWidth: wp(1),
    borderRadius: wp(4),
    paddingHorizontal: wp(4),
    paddingVertical: wp(1),
    marginHorizontal: wp(8),
    color: '#1F80F0',
    borderColor: '#1F80F0',
  }
})
