import ChallengeProgressCard from '@/components/challenges/ChallengeProgressCard';
import { ChallengeRankingItem } from '@/components/challenges/ChallengeRankingItem';
import { HeaderBar } from '@/components/ui/HeaderBar';
import { Colors } from '@/constants/Colors';
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
import { useSafeAreaTop } from '@/hooks/useSafeAreaWithPadding';
import {
  fetchChallengeDetail,
  fetchChallengeRankings,
  selectChallengeById,
  selectChallengeDetailError,
  selectChallengeDetailStatus,
  selectChallengeRankingError,
  selectChallengeRankingList,
  selectChallengeRankingLoadMoreStatus,
  selectChallengeRankingStatus,
} from '@/store/challengesSlice';
import { useLocalSearchParams, useRouter } from 'expo-router';
import React, { useEffect, useMemo } from 'react';
import type { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
import {
  ActivityIndicator,
  RefreshControl,
  ScrollView,
  StyleSheet,
  Text,
  View
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

export default function ChallengeLeaderboardScreen() {
  const safeAreaTop = useSafeAreaTop()
  const { id } = useLocalSearchParams<{ id?: string }>();
  const router = useRouter();
  const dispatch = useAppDispatch();
  const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
  const colorTokens = Colors[theme];
  const insets = useSafeAreaInsets();

  const challengeSelector = useMemo(() => (id ? selectChallengeById(id) : undefined), [id]);
  const challenge = useAppSelector((state) => (challengeSelector ? challengeSelector(state) : undefined));

  const detailStatusSelector = useMemo(() => (id ? selectChallengeDetailStatus(id) : undefined), [id]);
  const detailStatus = useAppSelector((state) => (detailStatusSelector ? detailStatusSelector(state) : 'idle'));
  const detailErrorSelector = useMemo(() => (id ? selectChallengeDetailError(id) : undefined), [id]);
  const detailError = useAppSelector((state) => (detailErrorSelector ? detailErrorSelector(state) : undefined));

  const rankingListSelector = useMemo(() => (id ? selectChallengeRankingList(id) : undefined), [id]);
  const rankingList = useAppSelector((state) => (rankingListSelector ? rankingListSelector(state) : undefined));
  const rankingStatusSelector = useMemo(() => (id ? selectChallengeRankingStatus(id) : undefined), [id]);
  const rankingStatus = useAppSelector((state) => (rankingStatusSelector ? rankingStatusSelector(state) : 'idle'));
  const rankingLoadMoreStatusSelector = useMemo(
    () => (id ? selectChallengeRankingLoadMoreStatus(id) : undefined),
    [id]
  );
  const rankingLoadMoreStatus = useAppSelector((state) =>
    rankingLoadMoreStatusSelector ? rankingLoadMoreStatusSelector(state) : 'idle'
  );
  const rankingErrorSelector = useMemo(() => (id ? selectChallengeRankingError(id) : undefined), [id]);
  const rankingError = useAppSelector((state) => (rankingErrorSelector ? rankingErrorSelector(state) : undefined));

  useEffect(() => {
    if (id) {
      void dispatch(fetchChallengeDetail(id));
    }
  }, [dispatch, id]);

  useEffect(() => {
    if (id && !rankingList) {
      void dispatch(fetchChallengeRankings({ id }));
    }
  }, [dispatch, id, rankingList]);

  if (!id) {
    return (
      <View style={[styles.safeArea, { backgroundColor: colorTokens.background }]}>
        <HeaderBar title="排行榜" onBack={() => router.back()} withSafeTop />
        <View style={{
          paddingTop: safeAreaTop
        }} />
        <View style={styles.missingContainer}>
          <Text style={[styles.missingText, { color: colorTokens.textSecondary }]}>未找到该挑战。</Text>
        </View>
      </View>
    );
  }

  if (detailStatus === 'loading' && !challenge) {
    return (
      <View style={[styles.safeArea, { backgroundColor: '#f3f4fb' }]}>
        <HeaderBar title="排行榜" onBack={() => router.back()} withSafeTop />
        <View style={styles.loadingContainer}>
          <ActivityIndicator color={colorTokens.primary} />
          <Text style={[styles.loadingText, { color: colorTokens.textSecondary }]}>加载榜单中…</Text>
        </View>
      </View>
    );
  }

  const hasMore = rankingList?.hasMore ?? false;
  const isRefreshing = rankingStatus === 'loading';
  const isLoadingMore = rankingLoadMoreStatus === 'loading';
  const defaultPageSize = rankingList?.pageSize ?? 20;
  const showInitialRankingLoading = isRefreshing && (!rankingList || rankingList.items.length === 0);

  const handleRefresh = () => {
    if (!id) {
      return;
    }
    void dispatch(fetchChallengeRankings({ id, page: 1, pageSize: defaultPageSize }));
  };

  const handleLoadMore = () => {
    if (!id || !rankingList || !hasMore || isLoadingMore || rankingStatus === 'loading') {
      return;
    }
    void dispatch(
      fetchChallengeRankings({ id, page: rankingList.page + 1, pageSize: rankingList.pageSize })
    );
  };

  const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
    const { layoutMeasurement, contentOffset, contentSize } = event.nativeEvent;
    const paddingToBottom = 160;
    if (layoutMeasurement.height + contentOffset.y >= contentSize.height - paddingToBottom) {
      handleLoadMore();
    }
  };

  if (!challenge) {
    return (
      <View style={[styles.safeArea, { backgroundColor: '#f3f4fb' }]}>
        <HeaderBar title="排行榜" onBack={() => router.back()} withSafeTop />
        <View style={styles.missingContainer}>
          <Text style={[styles.missingText, { color: colorTokens.textSecondary }]}>
            {detailError ?? '暂时无法加载榜单，请稍后再试。'}
          </Text>
        </View>
      </View>
    );
  }

  const rankingData = rankingList?.items ?? challenge.rankings ?? [];
  const subtitle = challenge.rankingDescription ?? challenge.summary;

  return (
    <View style={[styles.safeArea, { backgroundColor: '#f3f4fb' }]}>
      <HeaderBar title="排行榜" onBack={() => router.back()} withSafeTop />
      <ScrollView
        style={styles.scrollView}
        contentContainerStyle={{ paddingBottom: insets.bottom + 40, paddingTop: safeAreaTop }}
        showsVerticalScrollIndicator={false}
        refreshControl={
          <RefreshControl
            refreshing={isRefreshing}
            onRefresh={handleRefresh}
            tintColor={colorTokens.primary}
          />
        }
        onScroll={handleScroll}
        scrollEventThrottle={16}
      >
        <View style={styles.pageHeader}>
          <Text style={styles.challengeTitle}>{challenge.title}</Text>
          {subtitle ? <Text style={styles.challengeSubtitle}>{subtitle}</Text> : null}
          {challenge.progress ? (
            <ChallengeProgressCard
              title={challenge.title}
              endAt={challenge.endAt}
              progress={challenge.progress}
              style={styles.progressCardWrapper}
            />
          ) : null}
        </View>

        <View style={styles.rankingCard}>
          {showInitialRankingLoading ? (
            <View style={styles.rankingLoading}>
              <ActivityIndicator color={colorTokens.primary} />
              <Text style={[styles.loadingText, { color: colorTokens.textSecondary }]}>加载榜单中…</Text>
            </View>
          ) : rankingData.length ? (
            rankingData.map((item, index) => (
              <ChallengeRankingItem
                key={item.id ?? index}
                item={item}
                index={index}
                showDivider={index > 0}
                unit={challenge?.unit}
              />
            ))
          ) : rankingError ? (
            <View style={styles.emptyRanking}>
              <Text style={styles.rankingErrorText}>{rankingError}</Text>
            </View>
          ) : (
            <View style={styles.emptyRanking}>
              <Text style={styles.emptyRankingText}>榜单即将开启，快来抢占席位。</Text>
            </View>
          )}
          {isLoadingMore ? (
            <View style={styles.loadMoreIndicator}>
              <ActivityIndicator color={colorTokens.primary} size="small" />
              <Text style={[styles.loadingText, { color: colorTokens.textSecondary, marginTop: 8 }]}>加载更多…</Text>
            </View>
          ) : null}
          {rankingLoadMoreStatus === 'failed' ? (
            <View style={styles.loadMoreIndicator}>
              <Text style={styles.loadMoreErrorText}>加载更多失败，请下拉刷新重试</Text>
            </View>
          ) : null}
        </View>
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
  },
  scrollView: {
    flex: 1,
    backgroundColor: 'transparent',
  },
  pageHeader: {
    paddingHorizontal: 24,
    paddingTop: 24,
  },
  challengeTitle: {
    fontSize: 22,
    fontWeight: '800',
    color: '#1c1f3a',
  },
  challengeSubtitle: {
    marginTop: 8,
    fontSize: 14,
    color: '#6f7ba7',
    lineHeight: 20,
  },
  progressCardWrapper: {
    marginTop: 20,
  },
  rankingCard: {
    marginTop: 24,
    marginHorizontal: 24,
    borderRadius: 24,
    backgroundColor: '#ffffff',
    paddingVertical: 10,
    shadowColor: 'rgba(30, 41, 59, 0.12)',
    shadowOpacity: 0.16,
    shadowRadius: 18,
    shadowOffset: { width: 0, height: 10 },
    elevation: 6,
  },
  emptyRanking: {
    paddingVertical: 40,
    alignItems: 'center',
    justifyContent: 'center',
  },
  emptyRankingText: {
    fontSize: 14,
    color: '#6f7ba7',
  },
  rankingLoading: {
    paddingVertical: 32,
    alignItems: 'center',
    justifyContent: 'center',
  },
  rankingErrorText: {
    fontSize: 14,
    color: '#eb5757',
  },
  loadMoreIndicator: {
    paddingVertical: 16,
    alignItems: 'center',
    justifyContent: 'center',
  },
  loadMoreErrorText: {
    fontSize: 13,
    color: '#eb5757',
  },
  loadingContainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  loadingText: {
    marginTop: 16,
    fontSize: 14,
  },
  missingContainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingHorizontal: 32,
  },
  missingText: {
    fontSize: 14,
    textAlign: 'center',
  },
});
