import { XStack, YStack } from "tamagui";
import CustomText from "@/components/common/CustomText.jsx";
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
} from "react-native-reanimated";
import { TouchableOpacity, TouchableWithoutFeedback } from "react-native";
import { useCallback, useMemo, useEffect, useRef } from "react";
import { StyleSheet } from "react-native";
import { wp, sp } from "@/utils/ui/screenUtils";
import LoadingSpinner from "@/components/ui/LoadingSpinner";
import { router } from "expo-router";
import dayjs from "dayjs";
// 国际化
import { useTranslation } from "@/node_modules/react-i18next";
// 团队考勤统计store
import {
  useTeamAttendanceStore,
  useTeamCalendarStore,
  useAppStore,
} from "@/stores";
// 团队考勤统计、考勤详情数据映射配置
import { TEAM_ATTENDANCE_DATA_DEF } from "@/constants/attendanceStatus";
// 引入团队考勤模块工具函数
import { buildTeamStatisticsItems } from "@/utils/business/attendanceUtils";
import { ServerTeamCollection } from "@/api/attendance";
import {
  getAttendanceMonthRange2625,
  getDateRangeInclusive,
} from "@/utils/time/dateUtils";

const TeamStatisticsView = () => {
  //获取主色
  const primaryColor = useAppStore((s) => s.primary);

  //国际化
  const { t, i18n } = useTranslation("attendance");
  // 映射国际化文案，仅在语言变化时重算
  const statsConfig = useMemo(
    () =>
      TEAM_ATTENDANCE_DATA_DEF.map((d) => ({
        ...d,
        label: t(d.labelKey),
        labelUnit: t(d.labelUnitKey),
        valueUnit: t(d.valueUnitKey),
      })),
    // 依赖语言变化
    [i18n.language]
  );

  // 从团队考勤store读取数据
  const activeStatisticsMode = useTeamAttendanceStore(
    (s) => s.activeStatisticsMode
  );
  const teamStatisticsData_day = useTeamAttendanceStore(
    (s) => s.teamStatisticsData_day
  );
  const teamStatisticsData_week = useTeamAttendanceStore(
    (s) => s.teamStatisticsData_week
  );
  const teamStatisticsData_month = useTeamAttendanceStore(
    (s) => s.teamStatisticsData_month
  );

  // 读取团队日历上下文（当前日/周/月视图参数）
  const selectedDate = useTeamCalendarStore((s) => s.selectedDate);
  const weekSelectedMonday = useTeamCalendarStore((s) => s.weekSelectedMonday);
  const weekVisibleYM = useTeamCalendarStore((s) => s.weekVisibleYM);
  const monthVisibleYM = useTeamCalendarStore((s) => s.monthVisibleYM);

  // store 的加载态与写回方法
  const incLoading = useTeamAttendanceStore((s) => s.incLoading);
  const decLoading = useTeamAttendanceStore((s) => s.decLoading);
  const setTeamCollection_day = useTeamAttendanceStore(
    (s) => s.setTeamCollection_day
  );
  const setTeamStatisticsData_day = useTeamAttendanceStore(
    (s) => s.setTeamStatisticsData_day
  );
  const setTeamCollection_week = useTeamAttendanceStore(
    (s) => s.setTeamCollection_week
  );
  const setTeamStatisticsData_week = useTeamAttendanceStore(
    (s) => s.setTeamStatisticsData_week
  );
  const setTeamCollection_month = useTeamAttendanceStore(
    (s) => s.setTeamCollection_month
  );
  const setTeamStatisticsData_month = useTeamAttendanceStore(
    (s) => s.setTeamStatisticsData_month
  );
  const setLastUpdateTime = useTeamAttendanceStore((s) => s.setLastUpdateTime);

  // 组件级手动刷新取消控制器
  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 loadingCount = useTeamAttendanceStore((s) => s.loadingCount);
  const revalidatingCount = useTeamAttendanceStore((s) => s.revalidatingCount);
  const lastUpdateTime = useTeamAttendanceStore((s) => s.lastUpdateTime);
  const isLoading = (loadingCount || 0) > 0;
  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 statisticsData = useMemo(() => {
    if (activeStatisticsMode === "day") return teamStatisticsData_day || [];
    if (activeStatisticsMode === "week") return teamStatisticsData_week || [];
    if (activeStatisticsMode === "month") return teamStatisticsData_month || [];
    return [];
  }, [
    activeStatisticsMode,
    teamStatisticsData_day,
    teamStatisticsData_week,
    teamStatisticsData_month,
  ]);

  // 日模式仅显示 外勤/迟到/早退 三个统计项
  const effectiveConfig = useMemo(() => {
    if (activeStatisticsMode === "day") {
      const dayOrder = ["teamOutWorkNum", "teamLateNum", "teamBeforeNum"];
      const mapByKey = new Map(statsConfig.map((cfg) => [cfg.key, cfg]));
      return dayOrder.map((k) => mapByKey.get(k)).filter(Boolean);
    }
    return statsConfig;
  }, [activeStatisticsMode, statsConfig]);

  // 使用useMemo缓存统计项数据，避免重复计算
  const statisticsViews = useMemo(
    () => buildTeamStatisticsItems(statisticsData, effectiveConfig),
    [statisticsData, effectiveConfig]
  );

  //计算生成每行3个元素的数据排列
  const rows = useMemo(() => {
    const totalRows = Math.ceil(statisticsViews.length / 3);
    return Array.from({ length: totalRows }, (_, rowIndex) => {
      // 直接创建长度为3的数组，不足的部分用null填充，保证最后一行正常显示
      return Array.from({ length: 3 }, (_, colIndex) => {
        const itemIndex = rowIndex * 3 + colIndex;
        return itemIndex < statisticsViews.length
          ? statisticsViews[itemIndex]
          : null;
      });
    });
  }, [statisticsViews]);

  //跳转到统计详情页面
  const toStatisticsDetail = useCallback(
    (item) => {
      //加载中阻止跳转
      if (isLoading) return;
      router.push({
        pathname: "/attendance/teamAttendance/teamStatistics",
        params: {
          activeKey: item.key,
          valueUnit: item.valueUnit,
        },
      });
    },
    [isLoading]
  );

  // 手动刷新强制绕过缓存，按当前模式与参数请求一次最新数据并回填到对应状态
  const handleManualRefresh = useCallback(async () => {
    if (isLoading) return;

    const mode = activeStatisticsMode;
    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();

      if (mode === "day") {
        if (!selectedDate) return;
        const payload = {
          collectionType: 1,
          date: selectedDate,
          __bypassCache: true,
        };
        const res = await ServerTeamCollection(
          payload,
          signal ? { signal } : {}
        );
        if (
          res &&
          res.status === 0 &&
          res.data &&
          Object.keys(res.data).length
        ) {
          const result = res.data;
          setTeamCollection_day(result);
          setTeamStatisticsData_day(result);
          setLastUpdateTime(Date.now());
        }
      } else if (mode === "week") {
        if (!weekSelectedMonday || !weekVisibleYM) return;
        const weekStart = dayjs(weekSelectedMonday);
        const weekEnd = weekStart.add(6, "day");

        const { startDate, endDate } = getAttendanceMonthRange2625(
          weekVisibleYM.year,
          weekVisibleYM.month
        );
        const start = dayjs(startDate);
        const end = dayjs(endDate);
        const rangeStart = weekStart.isAfter(start, "day") ? weekStart : start;
        const rangeEnd = weekEnd.isBefore(end, "day") ? weekEnd : end;

        const dates = getDateRangeInclusive(
          rangeStart.format("YYYY-MM-DD"),
          rangeEnd.format("YYYY-MM-DD")
        );
        const today = dayjs().startOf("day");
        const clippedDates = dates.filter(
          (d) => !dayjs(d).isAfter(today, "day")
        );

        if (clippedDates.length === 0) {
          setTeamCollection_week({});
          setTeamStatisticsData_week([]);
          setLastUpdateTime(Date.now());
          return;
        }

        const payload = {
          collectionType: 2,
          dates: clippedDates,
          __bypassCache: true,
        };
        const res = await ServerTeamCollection(
          payload,
          signal ? { signal } : {}
        );
        if (
          res &&
          res.status === 0 &&
          res.data &&
          Object.keys(res.data).length
        ) {
          const result = res.data;
          setTeamCollection_week(result);
          setTeamStatisticsData_week(result);
          setLastUpdateTime(Date.now());
        }
      } else if (mode === "month") {
        if (!monthVisibleYM) return;
        const { startDate, endDate } = getAttendanceMonthRange2625(
          monthVisibleYM.year,
          monthVisibleYM.month
        );
        const dates = getDateRangeInclusive(startDate, endDate);
        const today = dayjs().startOf("day");
        const clippedDates = dates.filter(
          (d) => !dayjs(d).isAfter(today, "day")
        );

        if (clippedDates.length === 0) {
          setTeamCollection_month({});
          setTeamStatisticsData_month([]);
          setLastUpdateTime(Date.now());
          return;
        }

        const payload = {
          collectionType: 2,
          dates: clippedDates,
          __bypassCache: true,
        };
        const res = await ServerTeamCollection(
          payload,
          signal ? { signal } : {}
        );
        if (
          res &&
          res.status === 0 &&
          res.data &&
          Object.keys(res.data).length
        ) {
          const result = res.data;
          setTeamCollection_month(result);
          setTeamStatisticsData_month(result);
          setLastUpdateTime(Date.now());
        }
      }
    } catch (e) {
      // 静默失败
    } finally {
      // 清理当前的取消控制器引用
      manualRefreshAbortRef.current = null;
      decLoading();
    }
  }, [
    isLoading,
    activeStatisticsMode,
    selectedDate,
    weekSelectedMonday,
    weekVisibleYM,
    monthVisibleYM,
    incLoading,
    decLoading,
    setTeamCollection_day,
    setTeamStatisticsData_day,
    setTeamCollection_week,
    setTeamStatisticsData_week,
    setTeamCollection_month,
    setTeamStatisticsData_month,
    setLastUpdateTime,
  ]);

  return (
    <YStack style={styles.statisticsView}>
      {rows.map((rowItems, rowIndex) => (
        <XStack key={rowIndex} style={styles.statisticsRow}>
          {rowItems.map((item, colIndex) => (
            <YStack
              key={rowIndex * 3 + colIndex}
              style={styles.statisticsItemCol}
            >
              {item ? (
                item.value > 0 ? (
                  <TouchableOpacity
                    onPress={() => toStatisticsDetail(item)}
                    disabled={isLoading}
                  >
                    <YStack style={styles.statisticsItem}>
                      <CustomText
                        style={[
                          styles.statisticsValue,
                          { color: primaryColor },
                        ]}
                      >
                        {item.value}
                      </CustomText>
                      <CustomText
                        style={[styles.statisticsTitle, { color: "#191919" }]}
                      >
                        {item.labelUnit
                          ? `${item.label} (${item.labelUnit})`
                          : item.label}
                      </CustomText>
                    </YStack>
                  </TouchableOpacity>
                ) : (
                  <TouchableWithoutFeedback>
                    <YStack style={styles.statisticsItem}>
                      <CustomText
                        style={[styles.statisticsValue, { color: "#C1C1C1" }]}
                      >
                        {item.value}
                      </CustomText>
                      <CustomText
                        style={[styles.statisticsTitle, { color: "#C1C1C1" }]}
                      >
                        {item.labelUnit
                          ? `${item.label} (${item.labelUnit})`
                          : item.label}
                      </CustomText>
                    </YStack>
                  </TouchableWithoutFeedback>
                )
              ) : null}
            </YStack>
          ))}
        </XStack>
      ))}

      {isLoading && activeStatisticsMode !== "day" && (
        <YStack pointerEvents="none" style={styles.overlay}>
          <LoadingSpinner
            size={wp(20)}
            color={primaryColor}
            animating={isLoading}
          />
        </YStack>
      )}

      {!!lastUpdateTime && (
        <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>
      )}
    </YStack>
  );
};

export default TeamStatisticsView;

const styles = StyleSheet.create({
  statisticsView: {
    gap: wp(20),
    paddingVertical: wp(16),
    position: "relative",
  },
  statisticsRow: {
    alignItems: "center",
    justifyContent: "space-between",
    flexGrow: 1,
    flexBasis: 0,
  },
  statisticsItemCol: {
    flex: 1,
    minWidth: 0,
  },
  statisticsItem: {
    alignItems: "center",
    justifyContent: "center",
    gap: wp(2),
  },
  statisticsValue: {
    fontSize: sp(22),
    lineHeight: wp(30),
    fontFamily: "Bold",
  },
  statisticsTitle: {
    fontSize: sp(12),
    lineHeight: wp(17),
    fontFamily: "Medium",
  },
  overlay: {
    position: "absolute",
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    backgroundColor: "rgba(255,255,255,0.6)",
    alignItems: "center",
    justifyContent: "center",
    gap: wp(8),
  },
  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),
  },
});
