import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react';
import { View, ScrollView, StyleSheet, Pressable, Animated as RNAnimated, LayoutAnimation, Platform, UIManager } from 'react-native';
import CustomText from '@/components/common/CustomText.jsx';
import ApproveCardItem from '@/components/approve/ApproveCardItem';
import { fetchApprovalList, specialWork, information } from '@/api/approve';
import { wp } from '@/utils/ui/screenUtils';
import ApproveEmpty from '@/components/approve/ApproveEmpty';
import ApproveSkeleton from '@/components/approve/ApproveSkeleton';
import useCrossFadeSkeleton from '@/hooks/approve/useCrossFadeSkeleton';
import Animated from 'react-native-reanimated';
import { useFocusEffect } from '@react-navigation/native'
import { useApproveStore } from '@/stores/approve';
import { useAuthStore } from '@/stores/auth';
import useApprovalTabLogic from '@/hooks/approve/useApprovalTabLogic';
import ListFooter from '@/components/approve/ListFooter';
import { router } from 'expo-router';
import { useTranslation } from 'react-i18next';
import { useAppStore } from '@/stores';
import { FlashList } from '@shopify/flash-list';
import CustomRefreshControl from '@/components/ui/CustomRefreshControl';
const PAGE_SIZE = 10;

// 纯展示的网格卡片组件（避免 PendingTab 频繁重渲染影响到项）
const GridStatCard = React.memo(function GridStatCard({ width, label, count, primaryColor, onPress }) {
  const cardStyle = useMemo(() => ({
    backgroundColor: '#FFFFFF',
    borderRadius: wp(10),
    height: wp(83),
    alignItems: 'center',
    justifyContent: 'center',
    width,
    marginBottom: wp(12),
    borderWidth: wp(1),
    borderColor: '#E0E0E4',
  }), [width]);

  // 按压过渡动画
  const pressAnim = useRef(new RNAnimated.Value(0)).current; // 0 未按压, 1 按压中
  const handlePressIn = useCallback(() => {
    RNAnimated.timing(pressAnim, { toValue: 1, duration: 140, useNativeDriver: true }).start();
  }, [pressAnim]);
  const handlePressOut = useCallback(() => {
    RNAnimated.timing(pressAnim, { toValue: 0, duration: 220, useNativeDriver: true }).start();
  }, [pressAnim]);

  return (
    <Pressable
      onPress={onPress}
      onPressIn={handlePressIn}
      onPressOut={handlePressOut}
      // android_ripple 移除，确保仅保留背景色变化
      hitSlop={wp(6)}
      style={{ borderRadius: cardStyle.borderRadius }}
    >
      <RNAnimated.View style={[cardStyle, { overflow: 'hidden' }]}>
        {/* 渐进的按压过渡层：浅灰背景 */}
        <RNAnimated.View pointerEvents="none" style={[StyleSheet.absoluteFillObject, { backgroundColor: '#F7F7FA', opacity: pressAnim }]} />
        {/* 仅保留背景变化，移除描边与缩放 */}
        <CustomText style={[styles.gridCountText, { color: primaryColor }]}>{count ?? 0}</CustomText>
        <CustomText style={styles.gridLabelText}>{label}</CustomText>
      </RNAnimated.View>
    </Pressable>
  );
});

const PendingTab = ({ primaryColor, tabBarInset = 0, isActive = false, mode = 'list', containerWidth = 0, refreshKey = 0, searchValue = '', resetKey = 0 }) => {
  useEffect(() => {
    if (Platform.OS === 'android') {
      if (UIManager.setLayoutAnimationEnabledExperimental) {
        UIManager.setLayoutAnimationEnabledExperimental(true);
      }
    }
  }, []);

  const listRef = useRef(null);
  const primaryColorStore = useAppStore(s => s.primary);

  const { t } = useTranslation();

  const pendingCache = useApproveStore((s) => s.tabCache.pending);
  const isFirstPending = useApproveStore((s) => s.firstLoad.pending);
  const markTabLoaded = useApproveStore((s) => s.markTabLoaded);
  const initiallyLoading = mode === 'grid' ? false : (isFirstPending && ((pendingCache?.list?.length || 0) === 0));
  const { skeletonVisible, contentAnimatedStyle, skeletonAnimatedStyle, setLoading, revealNow } = useCrossFadeSkeleton({ initiallyLoading });
  const setLoadingRef = useRef(setLoading);
  setLoadingRef.current = setLoading;

  // zustand: doingTotal 更新和用户信息
  const clearLastH5Action = useApproveStore((s) => s.clearLastH5Action);
  const setDoingTotal = useApproveStore((s) => s.setDoingTotal);
  const user = useAuthStore((s) => s.user);
  const setTabCache = useApproveStore((s) => s.setTabCache);
  
  // 内部网格数据
  const [pendingGridItems, setPendingGridItems] = useState([
    { key: 'claims', label: t('approve:grid.claims'), value: 'claims', count: 0, list: [] },
    { key: 'payments', label: t('approve:grid.payments'), value: 'payments', count: 0, list: [] },
    { key: 'deployment', label: t('approve:grid.deployment'), value: 'deployment', count: 0, list: [] },
    { key: 'contract', label: t('approve:grid.contract'), value: 'contract', count: 0, list: [] },
    { key: 'seal', label: t('approve:grid.seal'), value: 'seal', count: 0, list: [] },
    { key: 'oa', label: t('approve:grid.oa'), value: 'oa', count: 0, list: [] },
    { key: 'others', label: t('approve:grid.others'), value: 'others', count: 0, list: [] },
  ]);
  const onGridItemPress = (item) => {
    router.push({
      pathname: '/webview',
      params: {
        url: `${process.env.EXPO_PUBLIC_H5_APPROVAL_URL}/#/pages/applyfor/components/approvalList/index`,
        label: item.label,
        value: item.value,
        busName: 'Sort',
      },
    });
  };

  // grid 模式立即展示内容
  useEffect(() => {
    if (mode === 'grid') {
      revealNow();
    }
  }, [mode, revealNow]);


  const fetchList = useCallback(async (nextPage, pageSize) => {
    return fetchApprovalList('pending', {
      Page: nextPage,
      PageSize: pageSize,
      Status: 1,
      Type: '',
      domain: 'all',
      endTime: '',
      menuType: 3,
      startTime: '',
      submitterName: '',
      title: '',
    }, searchValue);
  }, [searchValue]);

  const onNonAppendFinally = useCallback(() => {
    if (mode !== 'grid') setLoadingRef.current(false);
    markTabLoaded('pending');
  }, [mode, markTabLoaded]);
  const { data, page, refreshing, loadingMore, hasMore, fetchPage, onRefresh, onEndReached, onMomentumScrollBegin, error, retry } = useApprovalTabLogic({
    pageSize: PAGE_SIZE,
    fetchList,
    onNonAppendFinally,
    tabKey: 'pending',
  });

  useEffect(() => {
    if (isActive && mode !== 'grid') {
      fetchPage(1, false)
    }
  }, [isActive, mode, fetchPage])

  // 搜索变化时刷新第一页（仅列表模式）
  useEffect(() => {
    if (isActive && mode !== 'grid') {
      fetchPage(1, false);
    }
  }, [searchValue, isActive, mode, fetchPage]);

  // 新增：仅在从 WebView 返回（父传入 refreshKey 变化）且为网格模式时刷新
  useEffect(() => {
    let cancelled = false;
    const run = async () => {
      try {
        if (!isActive || mode !== 'grid') return;
        const params = {
          Page: 1,
          PageSize: 10,
          Status: 1,
          Type: '',
          domain: 'all',
          endTime: '',
          menuType: 3,
          startTime: '',
          submitterName: '',
          title: '',
          IsSpecial: true,
        };
        const { status, data } = await specialWork(params);
        if (cancelled) return;
        if (status === 0 && data && data.data) {
          const d = data.data;
          setPendingGridItems([
            { key: 'claims', label: t('approve:grid.claims'), value: 'claims', count: d.claims || 0, list: d.claimsApply || [] },
            { key: 'payments', label: t('approve:grid.payments'), value: 'payments', count: d.payments || 0, list: d.paymentsApply || [] },
            { key: 'deployment', label: t('approve:grid.deployment'), value: 'deployment', count: d.deployment || 0, list: d.deploymentApply || [] },
            { key: 'contract', label: t('approve:grid.contract'), value: 'contract', count: d.contract || 0, list: d.contractApply || [] },
            { key: 'seal', label: t('approve:grid.seal'), value: 'seal', count: d.seal || 0, list: d.sealApply || [] },
            { key: 'oa', label: t('approve:grid.oa'), value: 'oa', count: d.oa || 0, list: d.oaApply || [] },
            { key: 'others', label: t('approve:grid.others'), value: 'others', count: d.other || 0, list: d.otherApply || [] },
          ]);
        }
      } catch (e) {}
    };
    run();
    return () => { cancelled = true; };
  }, [refreshKey]);

  // 网格统计拉取（初次挂载或模式/激活变化时）
  useEffect(() => {
    let cancelled = false;
    const fetchGrid = async () => {
      try {
        if (!isActive || mode !== 'grid') return;
        const params = {
          Page: 1,
          PageSize: 10,
          Status: 1,
          Type: '',
          domain: 'all',
          endTime: '',
          menuType: 3,
          startTime: '',
          submitterName: '',
          title: '',
          IsSpecial: true,
        };
        const { status, data } = await specialWork(params);
        if (cancelled) return;
        if (status === 0 && data && data.data) {
          const d = data.data;
          setPendingGridItems([
            { key: 'claims', label: t('approve:grid.claims'), value: 'claims', count: d.claims || 0, list: d.claimsApply || [] },
            { key: 'payments', label: t('approve:grid.payments'), value: 'payments', count: d.payments || 0, list: d.paymentsApply || [] },
            { key: 'deployment', label: t('approve:grid.deployment'), value: 'deployment', count: d.deployment || 0, list: d.deploymentApply || [] },
            { key: 'contract', label: t('approve:grid.contract'), value: 'contract', count: d.contract || 0, list: d.contractApply || [] },
            { key: 'seal', label: t('approve:grid.seal'), value: 'seal', count: d.seal || 0, list: d.sealApply || [] },
            { key: 'oa', label: t('approve:grid.oa'), value: 'oa', count: d.oa || 0, list: d.oaApply || [] },
            { key: 'others', label: t('approve:grid.others'), value: 'others', count: d.other || 0, list: d.otherApply || [] },
          ]);
        }
      } catch (e) {}
    };
    fetchGrid();
    return () => { cancelled = true; };
  }, [isActive, mode, t]);

  useEffect(() => {
    if (isActive && listRef.current) {
      try {
        listRef.current.scrollToOffset({ offset: 0, animated: false });
      } catch (e) {}
    }
  }, [isActive]);

  useEffect(() => {
    if (isActive && listRef.current) {
      try {
        listRef.current.scrollToOffset({ offset: 0, animated: true });
      } catch (e) {}
    }
  }, [resetKey, isActive]);


  const refreshWithBadgeUpdate = useCallback(() => {}, []);
  const [overrideData, setOverrideData] = useState(null);
  const listData = overrideData || data;

  useEffect(() => {
    // 有新数据（如手动刷新或翻页）时取消覆盖，回归真实数据源
    setOverrideData(null);
  }, [data]);

  const removeItemById = useCallback((id) => {
    if (!id) return;
    // 使用 LayoutAnimation 消除底部删除时的布局跳动闪烁
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    
    // 移除后，为防止底部上跳，如果当前已在底部，则不应改变内容高度导致视口跳变？
    // 实际上 FlashList 只要数据源变了就会重新计算布局。
    // 尝试方案：如果处于列表末尾删除，且数据量足够撑满屏幕，则不做特殊处理；
    // 闪烁本质是 Footer 位置瞬间变化 + 列表内容高度骤减导致 ScrollView 内部 contentOffset 修正
    // LayoutAnimation 应该能缓解，但如果 FlashList 自身刷新机制导致重绘，可能需要先改数据源再做动画？
    // 或者，在底部删除时，先不物理移除，而是将其高度设为 0 并在动画结束后再移除？
    // 鉴于复杂度，这里先尝试禁用 removeClippedSubviews 在特定时刻，或者调整 FlashList 属性
    
    const base = overrideData || data || [];
    const next = base.filter((x) => String(x.ID) !== String(id));
    setOverrideData(next);
    try { setTabCache('pending', { list: next, page, hasMore }); } catch (_) {}
  }, [overrideData, data, setTabCache, page, hasMore]);
  const handleApproveAction = useCallback(async (id) => {
    removeItemById(id);
    try {
      const res = await information({ menuType: 3, UserID: user.ID });
      const val = res?.data?.SubmitMeInfo?.DoingTotal ?? 0;
      setDoingTotal(Number(val) || 0);
    } catch (e) {}
  }, [removeItemById, setDoingTotal, user]);
  const handleRejectAction = useCallback(async (reason, id) => {
    removeItemById(id);
    try {
      const res = await information({ menuType: 3, UserID: user.ID });
      const val = res?.data?.SubmitMeInfo?.DoingTotal ?? 0;
      setDoingTotal(Number(val) || 0);
    } catch (e) {}
  }, [removeItemById, setDoingTotal, user]);

  useFocusEffect(
    useCallback(() => {
      try {
        const entry = useApproveStore.getState().lastH5Action;
        if (entry && entry.id) {
          removeItemById(entry.id);
          clearLastH5Action();
        }
      } catch (_) {}
    }, [removeItemById, clearLastH5Action])
  );


  const noop = useCallback(() => {}, []);

  const keyExtractor = useCallback((item, idx) => String(item?.ID ?? idx), []);

  const renderItem = useCallback(({ item }) => (
    <ApproveCardItem 
      item={item} 
      onApprove={() => handleApproveAction(item.ID)} 
      onReject={(reason) => handleRejectAction(reason, item.ID)} 
      primaryColor={primaryColor}
      onDeleted={refreshWithBadgeUpdate}
      isMyPending={true}
      isMeCheck={false}
    />
  ), [primaryColor, refreshWithBadgeUpdate, handleApproveAction, handleRejectAction]);

  const itemSeparator = useMemo(() => () => (
    <View style={styles.separator12} />
  ), []);

  const listFooter = useMemo(() => (
    <ListFooter loadingMore={loadingMore} hasMore={hasMore} dataLength={listData.length} primaryColor={primaryColor} error={!!error} onRetry={retry} />
  ), [loadingMore, hasMore, listData.length, primaryColor, error, retry]);

  const emptyComponent = useMemo(() => (<ApproveEmpty />), []);
  const skeleton = useMemo(() => (<ApproveSkeleton variant={mode === 'grid' ? 'grid' : 'list'} containerWidth={containerWidth} />), [mode, containerWidth]);
  const contentContainerStyle = useMemo(() => ({ paddingBottom: tabBarInset, paddingTop: wp(8), paddingHorizontal: wp(16) }), [tabBarInset]);
  // Grid 专用 memo 变量，避免内联样式抖动
  const scrollContentContainerStyle = useMemo(() => ({ paddingBottom: tabBarInset , paddingTop: wp(8), paddingHorizontal: wp(16) }), [tabBarInset]);
  const gridRowStyle = useMemo(() => ({ flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between' }), []);
  const gridItemWidth = useMemo(() => (containerWidth - wp(16) * 2 - wp(12)) / 2, [containerWidth]);

  return (
    <View style={styles.container}>
      {skeletonVisible && (
        <Animated.View style={[styles.overlay, skeletonAnimatedStyle]}>
          {skeleton}
        </Animated.View>
      )}

      <Animated.View style={[styles.flex1, contentAnimatedStyle]}>
        {mode === 'grid' ? (
          <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={scrollContentContainerStyle}>
            <View style={gridRowStyle}>
              {pendingGridItems.map((g) => (
                <GridStatCard
                  key={g.key}
                  width={gridItemWidth}
                  label={g.label}
                  count={g.count}
                  primaryColor={primaryColor}
                  onPress={() => onGridItemPress(g)}
                />
              ))}
            </View>
          </ScrollView>
        ) : (
          <FlashList
            ref={listRef}
            style={styles.flex1}
            data={listData}
            renderItem={renderItem}
            keyExtractor={keyExtractor}
            refreshing={refreshing}
            onRefresh={onRefresh}
            onEndReached={onEndReached}
            onEndReachedThreshold={0.2}
            onMomentumScrollBegin={onMomentumScrollBegin}
            ItemSeparatorComponent={itemSeparator}
            ListFooterComponent={listFooter}
            ListEmptyComponent={emptyComponent}
            contentContainerStyle={contentContainerStyle}
            removeClippedSubviews={false}
            windowSize={5}
            initialNumToRender={6}
            maxToRenderPerBatch={6}
            updateCellsBatchingPeriod={16}
            estimatedItemSize={wp(132)}
            refreshControl={
              <CustomRefreshControl
                refreshing={refreshing}
                onRefresh={onRefresh}
                tintColor={primaryColorStore}
              />
            }
          />
        )}
      </Animated.View>
    </View>
  );
};

export default React.memo(PendingTab);

const styles = StyleSheet.create({
  container: { flex: 1, position: 'relative' },
  overlay: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 2 },
  flex1: { flex: 1 },
  separator12: { height: wp(12) },
  gridCountText: { fontSize: wp(28), fontFamily: 'AlibabaPuHuiTi-Bold' },
  gridLabelText: { marginTop: wp(6), fontSize: wp(14), color: '#4D4D4D' },
});
