import ChallengeProgressCard from '@/components/challenges/ChallengeProgressCard';
import { Colors } from '@/constants/Colors';
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
import {
  fetchChallenges,
  selectChallengeCards,
  selectChallengesListError,
  selectChallengesListStatus,
  type ChallengeCardViewModel,
} from '@/store/challengesSlice';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import { useRouter } from 'expo-router';
import React, { useEffect, useMemo } from 'react';
import {
  ActivityIndicator,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

const AVATAR_SIZE = 36;
const CARD_IMAGE_WIDTH = 132;
const CARD_IMAGE_HEIGHT = 96;
const STATUS_LABELS: Record<'upcoming' | 'ongoing' | 'expired', string> = {
  upcoming: '即将开始',
  ongoing: '进行中',
  expired: '已结束',
};

export default function ChallengesScreen() {
  const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
  const colorTokens = Colors[theme];
  const router = useRouter();
  const dispatch = useAppDispatch();
  const challenges = useAppSelector(selectChallengeCards);
  const listStatus = useAppSelector(selectChallengesListStatus);
  const listError = useAppSelector(selectChallengesListError);
  const ongoingChallenge = useMemo(
    () =>
      challenges.find(
        (challenge) => challenge.status === 'ongoing' && challenge.isJoined && challenge.progress
      ),
    [challenges]
  );
  const progressTrackColor = theme === 'dark' ? 'rgba(255, 255, 255, 0.08)' : '#eceffa';
  const progressInactiveColor = theme === 'dark' ? 'rgba(255, 255, 255, 0.24)' : '#dfe4f6';

  useEffect(() => {
    if (listStatus === 'idle') {
      dispatch(fetchChallenges());
    }
  }, [dispatch, listStatus]);

  const gradientColors: [string, string] =
    theme === 'dark'
      ? ['#1f2230', '#10131e']
      : [colorTokens.backgroundGradientStart, colorTokens.backgroundGradientEnd];

  const renderChallenges = () => {
    if (listStatus === 'loading' && challenges.length === 0) {
      return (
        <View style={styles.stateContainer}>
          <ActivityIndicator color={colorTokens.primary} />
          <Text style={[styles.stateText, { color: colorTokens.textSecondary }]}>加载挑战中…</Text>
        </View>
      );
    }

    if (listStatus === 'failed' && challenges.length === 0) {
      return (
        <View style={styles.stateContainer}>
          <Text style={[styles.stateText, { color: colorTokens.textSecondary }]}>
            {listError ?? '加载挑战失败，请稍后重试'}
          </Text>
          <TouchableOpacity
            style={[styles.retryButton, { borderColor: colorTokens.primary }]}
            activeOpacity={0.9}
            onPress={() => dispatch(fetchChallenges())}
          >
            <Text style={[styles.retryText, { color: colorTokens.primary }]}>重新加载</Text>
          </TouchableOpacity>
        </View>
      );
    }

    if (challenges.length === 0) {
      return (
        <View style={styles.stateContainer}>
          <Text style={[styles.stateText, { color: colorTokens.textSecondary }]}>暂无挑战，稍后再来探索。</Text>
        </View>
      );
    }

    return challenges.map((challenge) => (
      <ChallengeCard
        key={challenge.id}
        challenge={challenge}
        surfaceColor={colorTokens.surface}
        textColor={colorTokens.text}
        mutedColor={colorTokens.textSecondary}
        onPress={() =>
          router.push({ pathname: '/challenges/[id]', params: { id: challenge.id } })
        }
      />
    ));
  };

  return (
    <View style={[styles.screen, { backgroundColor: colorTokens.pageBackgroundEmphasis }]}>
      <StatusBar barStyle={theme === 'dark' ? 'light-content' : 'dark-content'} />
      <LinearGradient colors={gradientColors} style={StyleSheet.absoluteFillObject} />
      <SafeAreaView style={styles.safeArea} edges={['top']}>
        <ScrollView
          contentContainerStyle={styles.scrollContent}
          showsVerticalScrollIndicator={false}
          bounces
        >
          <View style={styles.headerRow}>
            <View>
              <Text style={[styles.title, { color: colorTokens.text }]}>挑战</Text>
              <Text style={[styles.subtitle, { color: colorTokens.textSecondary }]}>参与精选活动，保持每日动力</Text>
            </View>
            {/* <TouchableOpacity activeOpacity={0.9} style={styles.giftShadow}>
              <LinearGradient
                colors={[colorTokens.primary, colorTokens.accentPurple]}
                start={{ x: 0, y: 0 }}
                end={{ x: 1, y: 1 }}
                style={styles.giftButton}
              >
                <IconSymbol name="gift.fill" size={18} color={colorTokens.onPrimary} />
              </LinearGradient>
            </TouchableOpacity> */}
          </View>

          {ongoingChallenge ? (
            <TouchableOpacity
              activeOpacity={0.92}
              onPress={() =>
                router.push({ pathname: '/challenges/[id]', params: { id: ongoingChallenge.id } })
              }
            >
              <ChallengeProgressCard
                title={ongoingChallenge.title}
                endAt={ongoingChallenge.endAt}
                progress={ongoingChallenge.progress}
                style={styles.progressCardWrapper}
                backgroundColors={[colorTokens.card, colorTokens.card]}
                titleColor={colorTokens.text}
                subtitleColor={colorTokens.textSecondary}
                metaColor={colorTokens.primary}
                metaSuffixColor={colorTokens.textSecondary}
                accentColor={colorTokens.primary}
                trackColor={progressTrackColor}
                inactiveColor={progressInactiveColor}
              />
            </TouchableOpacity>
          ) : null}

          <View style={styles.cardsContainer}>{renderChallenges()}</View>
        </ScrollView>
      </SafeAreaView>
    </View>
  );
}

type ChallengeCardProps = {
  challenge: ChallengeCardViewModel;
  surfaceColor: string;
  textColor: string;
  mutedColor: string;
  onPress: () => void;
};

function ChallengeCard({ challenge, surfaceColor, textColor, mutedColor, onPress }: ChallengeCardProps) {
  const statusLabel = STATUS_LABELS[challenge.status] ?? challenge.status;

  return (
    <TouchableOpacity
      activeOpacity={0.92}
      onPress={onPress}
      style={[
        styles.card,
        {
          backgroundColor: surfaceColor,
          shadowColor: 'rgba(15, 23, 42, 0.18)',
        },
      ]}
    >
      <Image
        source={{ uri: challenge.image }}
        style={styles.cardImage}
        cachePolicy={'memory-disk'}
      />

      <View style={styles.cardContent}>
        <Text style={[styles.cardTitle, { color: textColor }]} numberOfLines={1}>
          {challenge.title}
        </Text>
        <Text style={[styles.cardDate, { color: mutedColor }]}>{challenge.dateRange}</Text>
        <Text style={[styles.cardParticipants, { color: mutedColor }]}>
          {challenge.participantsLabel}
          {' · '}
          {statusLabel}
          {challenge.isJoined ? ' · 已加入' : ''}
        </Text>
        {challenge.avatars.length ? (
          <AvatarStack avatars={challenge.avatars} borderColor={surfaceColor} />
        ) : null}
      </View>
    </TouchableOpacity>
  );
}

type AvatarStackProps = {
  avatars: string[];
  borderColor: string;
};

function AvatarStack({ avatars, borderColor }: AvatarStackProps) {
  return (
    <View style={styles.avatarRow}>
      {avatars
        .filter(Boolean)
        .map((avatar, index) => (
          <Image
            key={`${avatar}-${index}`}
            source={{ uri: avatar }}
            style={[
              styles.avatar,
              { borderColor },
              index === 0 ? null : styles.avatarOffset,
            ]}
          />
        ))}
    </View>
  );
}

const styles = StyleSheet.create({
  screen: {
    flex: 1,
  },
  safeArea: {
    flex: 1,
  },
  scrollContent: {
    paddingHorizontal: 20,
    paddingBottom: 32,
  },
  headerRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginTop: 8,
    marginBottom: 26,
  },
  title: {
    fontSize: 32,
    fontWeight: '700',
    letterSpacing: 1,
  },
  subtitle: {
    marginTop: 6,
    fontSize: 14,
    fontWeight: '500',
    opacity: 0.8,
  },
  giftShadow: {
    shadowColor: 'rgba(94, 62, 199, 0.45)',
    shadowOffset: { width: 0, height: 8 },
    shadowOpacity: 0.35,
    shadowRadius: 12,
    elevation: 8,
    borderRadius: 26,
  },
  giftButton: {
    width: 32,
    height: 32,
    borderRadius: 26,
    alignItems: 'center',
    justifyContent: 'center',
  },
  cardsContainer: {
    gap: 18,
  },
  progressCardWrapper: {
    marginBottom: 24,
  },
  stateContainer: {
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 40,
    paddingHorizontal: 20,
  },
  stateText: {
    marginTop: 12,
    fontSize: 14,
    textAlign: 'center',
    lineHeight: 20,
  },
  retryButton: {
    marginTop: 16,
    paddingHorizontal: 18,
    paddingVertical: 8,
    borderRadius: 18,
    borderWidth: StyleSheet.hairlineWidth,
  },
  retryText: {
    fontSize: 13,
    fontWeight: '600',
  },
  card: {
    flexDirection: 'row',
    borderRadius: 28,
    padding: 18,
    alignItems: 'center',
    shadowOffset: { width: 0, height: 16 },
    shadowOpacity: 0.18,
    shadowRadius: 24,
    elevation: 6,
  },
  cardImage: {
    width: CARD_IMAGE_WIDTH,
    height: CARD_IMAGE_HEIGHT,
    borderRadius: 22,
  },
  cardContent: {
    flex: 1,
    marginLeft: 16,
  },
  cardTitle: {
    fontSize: 18,
    fontWeight: '700',
    marginBottom: 4,
  },
  cardDate: {
    fontSize: 13,
    fontWeight: '500',
    marginBottom: 4,
  },
  cardParticipants: {
    fontSize: 13,
    fontWeight: '500',
  },
  cardProgress: {
    marginTop: 8,
    fontSize: 13,
    fontWeight: '600',
  },
  avatarRow: {
    flexDirection: 'row',
    marginTop: 16,
    alignItems: 'center',
  },
  avatar: {
    width: AVATAR_SIZE,
    height: AVATAR_SIZE,
    borderRadius: AVATAR_SIZE / 2,
    borderWidth: 2,
  },
  avatarOffset: {
    marginLeft: -12,
  },
});
