import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react';
import { TouchableOpacity, StyleSheet, FlatList } from 'react-native';
import { Image as ExpoImage } from 'expo-image';
import Animated, { useSharedValue, withTiming, useAnimatedStyle, Easing } from 'react-native-reanimated';
import { View, YStack, XStack, Card } from 'tamagui';
import CustomText from '@/components/common/CustomText.jsx';
import { CustomSafeArea } from '@/components/common/CustomSafeArea';
import { CustomHeader } from '@/components/common/CustomHeader';
import { ChevronRight } from '@tamagui/lucide-icons';
import { wp, sp } from '@/utils/ui/screenUtils';
import { useTranslation } from 'react-i18next';
import { scheduleList } from '@/api/approve';
import LoadingSpinner from '@/components/ui/LoadingSpinner';
import { router } from 'expo-router';
import { useFocusEffect } from '@react-navigation/native';
const PAGE_SIZE = 10;

const AnnouncementListScreen = () => {
  const [data, setData] = useState([]);
  const [page, setPage] = useState(1);
  const [refreshing, setRefreshing] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [initialLoading, setInitialLoading] = useState(true);
  const getStableId = useCallback((it) => it?.Uuid ?? it?.uuid ?? it?.ID ?? it?.id, []);
  const dedupeByStableId = useCallback(
    (arr) => {
      const seen = new Set();
      const out = [];
      for (const it of arr) {
        const id = getStableId(it);
        if (id == null || id === '') {
          out.push(it);
          continue;
        }
        const k = String(id);
        if (!seen.has(k)) {
          seen.add(k);
          out.push(it);
        }
      }
      return out;
    },
    [getStableId]
  );

  const contentOpacity = useSharedValue(0);
  const contentAnimatedStyle = useAnimatedStyle(() => ({ opacity: contentOpacity.value }));
  useEffect(() => {
    if (initialLoading) {
      contentOpacity.value = 0;
    } else {
      contentOpacity.value = withTiming(1, { duration: 800, easing: Easing.out(Easing.cubic) });
    }
  }, [initialLoading]);

  const fetchPage = useCallback(async (nextPage = 1, append = false) => {
    if (append) setLoadingMore(true);
    try {
      const res = await scheduleList({ pageNum: nextPage, pageSize: PAGE_SIZE });
      const list = res?.data?.Data ?? [];
      setData((prev) => {
        const merged = append ? dedupeByStableId([...prev, ...list]) : dedupeByStableId(list);
        if (append) {
          if (merged.length === prev.length) {
            setHasMore(false);
          } else {
            setHasMore(list.length === PAGE_SIZE);
          }
        } else {
          setHasMore(list.length === PAGE_SIZE);
        }
        return merged;
      });
      setPage(nextPage);
    } catch (e) {
      console.error('e', e);
    } finally {
      if (append) setLoadingMore(false);
      if (!append) setRefreshing(false);
      if (!append) setInitialLoading(false);
    }
  }, [dedupeByStableId]);

  useFocusEffect(
    useCallback(() => {
      fetchPage(1, false);
    }, [fetchPage])
  );

  const onRefresh = useCallback(() => {
    setRefreshing(true);
    fetchPage(1, false);
  }, [fetchPage]);


  const onEndReachedRef = useRef(0);
  const onEndReached = useCallback(() => {
    const now = Date.now();
    if (now - onEndReachedRef.current < 200) return;
    onEndReachedRef.current = now;
    if (!loadingMore && hasMore && !refreshing) fetchPage(page + 1, true);
  }, [loadingMore, hasMore, refreshing, page, fetchPage]);

  
  const renderItem = useCallback(({ item }) => <AnnouncementItem item={item} />, []);

  const itemSeparator = useMemo(() => () => <View style={{ height: wp(12) }} />, []);

  const { t } = useTranslation('common');

  const listFooter = useMemo(() => {
    if (loadingMore) {
      return (
        <View style={{ paddingVertical: wp(12), alignItems: 'center', justifyContent: 'center' }}>
          <LoadingSpinner size={wp(25)} color={'#409EFF'} />
        </View>
      );
    }
    if (!hasMore && data.length > 0) {
      return (
        <View style={{ paddingVertical: wp(16), alignItems: 'center', justifyContent: 'center' }}>
          <CustomText style={{ color: '#9AA0A6', fontSize: sp(12) }}>{t('announcement.loadedAll')}</CustomText>
        </View>
      );
    }
    return <View style={{ height: wp(4) }} />;
  }, [loadingMore, hasMore, data.length, t]);

  const emptyComponent = useMemo(
    () => (
      <View style={{ paddingTop: wp(80), alignItems: 'center', justifyContent: 'center' }}>
        <CustomText style={{ color: '#9AA0A6', fontSize: sp(12) }}>{t('announcement.empty')}</CustomText>
      </View>
    ),
    [t]
  );

  const listContentContainerStyle = useMemo(() => ({
    paddingHorizontal: wp(12),
    paddingTop: wp(8),
    paddingBottom: wp(12),
  }), []);

  // 首次加载骨架
  const renderSkeleton = () => {
    const items = [0, 1, 2, 3];
    return (
      <View style={{ flex: 1 }}>
        <View style={{ paddingHorizontal: wp(12), paddingTop: wp(8), paddingBottom: wp(12) }}>
          {items.map((i) => (
            <View key={i} style={styles.skeletonCard}>
              <View style={styles.skeletonTitle} />
              <View style={styles.divider} />
              <XStack alignItems="center" justifyContent="space-between">
                <View style={styles.skeletonDate} />
                <View style={styles.skeletonChevron} />
              </XStack>
            </View>
          ))}
        </View>
      </View>
    );
  };

  return (
    <View flex={1}>
      <ExpoImage
        source={require('@/assets/images/backgrounds/home-bg.webp')}
        style={StyleSheet.absoluteFill}
        contentFit="cover"
        transition={0}
        pointerEvents="none"
        cachePolicy="memory-disk"
      />
      <View flex={1}>
        <CustomHeader title={t('announcement.listTitle')} />
        <YStack flex={1}>
          {initialLoading ? renderSkeleton() : null}

          <Animated.View style={[{ flex: 1 }, contentAnimatedStyle]}>
            {!initialLoading && (
              <FlatList
                style={{ flex: 1 }}
                data={data}
                renderItem={renderItem}
                keyExtractor={(item, idx) => String(getStableId(item) ?? `idx-${idx}`)}
                refreshing={refreshing}
                onRefresh={onRefresh}
                onEndReached={onEndReached}
                onEndReachedThreshold={0.2}
                ItemSeparatorComponent={itemSeparator}
                ListFooterComponent={listFooter}
                ListEmptyComponent={emptyComponent}
                contentContainerStyle={listContentContainerStyle}
                removeClippedSubviews
                windowSize={5}
                initialNumToRender={6}
                maxToRenderPerBatch={8}
                updateCellsBatchingPeriod={80}
              />
            )}
          </Animated.View>
        </YStack>
      </View>
    </View>
  );
};

export default AnnouncementListScreen;

const styles = StyleSheet.create({
  card: {
    backgroundColor: '#fff',
    borderRadius: wp(8),
    paddingHorizontal: wp(12),
    paddingVertical: wp(12),
  },
  title: {
    color: '#191919',
    fontSize: sp(16),
    fontFamily: 'Bold',
    flexShrink: 1,
  },
  date: {
    color: '#A1A1A1',
    fontSize: sp(12),
  },
  dot: {
    width: wp(8),
    height: wp(8),
    borderRadius: wp(4),
    backgroundColor: '#FF3B30',
  },
  divider: {
    height: StyleSheet.hairlineWidth,
    backgroundColor: '#F0F0F0',
  },
  // 骨架样式
  skeletonCard: {
    backgroundColor: '#fff',
    borderRadius: wp(8),
    paddingHorizontal: wp(12),
    paddingVertical: wp(12),
    marginBottom: wp(12),
    borderWidth: wp(1),
    borderColor: '#F0F0F0',
  },
  skeletonTitle: {
    width: '72%',
    height: wp(16),
    backgroundColor: '#F2F3F5',
    borderRadius: wp(4),
    marginBottom: wp(12),
  },
  skeletonDate: {
    width: wp(110),
    height: wp(12),
    backgroundColor: '#F2F3F5',
    borderRadius: wp(4),
  },
  skeletonChevron: {
    width: wp(18),
    height: wp(18),
    backgroundColor: '#F2F3F5',
    borderRadius: wp(9),
  },
});

const AnnouncementItem = React.memo(({ item }) => {
  const isReadFlag = item?.IsRead;
  const title = item?.Title;
  const date = item?.CreatedTime;
  const uuid = item?.Uuid;

  const handlePress = useCallback(() => {
    if (uuid) {
      router.push({ pathname: '/announcement/details', params: { uuid: String(uuid) } });
    }
  }, [uuid]);

  return (
    <Card style={styles.card}>
      <TouchableOpacity activeOpacity={0.7} onPress={handlePress}>
        <YStack gap={wp(10)}>
          <XStack alignItems="center" justifyContent="space-between">
            <XStack alignItems="center" gap={wp(6)} flex={1}>
              {isReadFlag === 0 && <View style={styles.dot} />}
              <CustomText numberOfLines={1} style={styles.title}>
                {title || '-'}
              </CustomText>
            </XStack>
          </XStack>

          <View style={styles.divider} />
          <XStack alignItems="center" justifyContent="space-between">
            <CustomText style={styles.date}>{date || '-'}</CustomText>
            <ChevronRight color="#C4C4C4" size={wp(18)} />
          </XStack>
        </YStack>
      </TouchableOpacity>
    </Card>
  );
});
