import React from 'react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Button } from '@tamagui/button';
import { Award, BarChart2, Camera, Flame, Sparkles, Trophy, Users } from 'lucide-react';
import AppShell from '../components/AppShell';
import PullToRefresh from '@/shared/guest/components/PullToRefresh';
import { useEventData } from '../context/EventDataContext';
import { useOptionalGuestIdentity } from '../context/GuestIdentityContext';
import {
  fetchAchievements,
  type AchievementBadge,
  type AchievementsPayload,
  type FeedEntry,
  type LeaderboardEntry,
  type TimelinePoint,
  type TopPhotoHighlight,
  type TrendingEmotionHighlight,
} from '../services/achievementsApi';
import { useTranslation } from '@/shared/guest/i18n/useTranslation';
import { useLocale } from '@/shared/guest/i18n/LocaleContext';
import { useGuestThemeVariant } from '../lib/guestTheme';
import { getBentoSurfaceTokens } from '../lib/bento';
import { localizeTaskLabel } from '@/shared/guest/lib/localizeTaskLabel';
import { buildEventPath } from '../lib/routes';
import { useNavigate } from 'react-router-dom';

const GENERIC_ERROR = 'GENERIC_ERROR';

type TabKey = 'personal' | 'event' | 'feed';

type BentoCardProps = {
  children: React.ReactNode;
  isDark: boolean;
  padding?: number;
  gradient?: string;
};

function formatRelativeTimestamp(input: string, formatter: Intl.RelativeTimeFormat): string {
  const date = new Date(input);
  if (Number.isNaN(date.getTime())) return '';
  const diff = date.getTime() - Date.now();
  const minute = 60_000;
  const hour = 60 * minute;
  const day = 24 * hour;
  const abs = Math.abs(diff);
  if (abs < minute) return formatter.format(0, 'second');
  if (abs < hour) return formatter.format(Math.round(diff / minute), 'minute');
  if (abs < day) return formatter.format(Math.round(diff / hour), 'hour');
  return formatter.format(Math.round(diff / day), 'day');
}

function BentoCard({ children, isDark, padding = 16, gradient }: BentoCardProps) {
  const surface = getBentoSurfaceTokens(isDark);
  return (
    <YStack
      padding={padding}
      borderRadius="$bento"
      backgroundColor={surface.backgroundColor}
      borderWidth={1}
      borderBottomWidth={3}
      borderColor={surface.borderColor}
      borderBottomColor={surface.borderBottomColor}
      style={{ boxShadow: surface.shadow, backgroundImage: gradient }}
    >
      {children}
    </YStack>
  );
}

type LeaderboardProps = {
  title: string;
  description: string;
  icon: React.ElementType;
  entries: LeaderboardEntry[];
  emptyCopy: string;
  formatNumber: (value: number) => string;
  guestFallback: string;
  isDark: boolean;
};

function Leaderboard({ title, description, icon: Icon, entries, emptyCopy, formatNumber, guestFallback, isDark }: LeaderboardProps) {
  return (
    <YStack gap="$2">
      <XStack alignItems="center" gap="$2">
        <YStack
          width={34}
          height={34}
          borderRadius={12}
          backgroundColor="rgba(244, 63, 94, 0.12)"
          alignItems="center"
          justifyContent="center"
        >
          <Icon size={16} color="#F43F5E" />
        </YStack>
        <YStack gap="$0.5">
          <Text fontSize="$3" fontWeight="$7">
            {title}
          </Text>
          <Text fontSize="$1" color="$color" opacity={0.7}>
            {description}
          </Text>
        </YStack>
      </XStack>
      {entries.length === 0 ? (
        <Text fontSize="$2" color="$color" opacity={0.7}>
          {emptyCopy}
        </Text>
      ) : (
        <YStack gap="$2">
          {entries.map((entry, index) => (
            <XStack
              key={`${entry.guest}-${index}`}
              alignItems="center"
              justifyContent="space-between"
              padding="$2"
              borderRadius="$card"
              backgroundColor={isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(15, 23, 42, 0.05)'}
              borderWidth={1}
              borderColor={isDark ? 'rgba(255, 255, 255, 0.16)' : 'rgba(15, 23, 42, 0.08)'}
            >
              <XStack alignItems="center" gap="$2">
                <Text fontSize="$1" fontWeight="$7" color="$color" opacity={0.7}>
                  #{index + 1}
                </Text>
                <Text fontSize="$2" fontWeight="$6">
                  {entry.guest || guestFallback}
                </Text>
              </XStack>
              <XStack gap="$3">
                <Text fontSize="$1" color="$color" opacity={0.7}>
                  {formatNumber(entry.photos)}
                </Text>
                <Text fontSize="$1" color="$color" opacity={0.7}>
                  {formatNumber(entry.likes)}
                </Text>
              </XStack>
            </XStack>
          ))}
        </YStack>
      )}
    </YStack>
  );
}

type BadgesGridProps = {
  badges: AchievementBadge[];
  emptyCopy: string;
  completeCopy: string;
  isDark: boolean;
};

function BadgesGrid({ badges, emptyCopy, completeCopy, isDark }: BadgesGridProps) {
  if (badges.length === 0) {
    return (
      <Text fontSize="$2" color="$color" opacity={0.7}>
        {emptyCopy}
      </Text>
    );
  }

  return (
    <XStack flexWrap="wrap" gap="$2">
      {badges.map((badge) => {
        const target = badge.target ?? 0;
        const progress = badge.progress ?? 0;
        const ratio = target > 0 ? Math.min(1, progress / target) : 0;
        const percentage = Math.round((badge.earned ? 1 : ratio) * 100);
        return (
          <YStack
            key={badge.id}
            width="48%"
            minWidth={140}
            padding="$2"
            borderRadius="$card"
            borderWidth={1}
            borderColor={badge.earned ? 'rgba(16, 185, 129, 0.4)' : isDark ? 'rgba(255, 255, 255, 0.16)' : 'rgba(15, 23, 42, 0.1)'}
            backgroundColor={badge.earned ? 'rgba(16, 185, 129, 0.08)' : isDark ? 'rgba(255, 255, 255, 0.05)' : 'rgba(255, 255, 255, 0.85)'}
            gap="$1"
          >
            <Text fontSize="$2" fontWeight="$7">
              {badge.title}
            </Text>
            <Text fontSize="$1" color="$color" opacity={0.7}>
              {badge.description}
            </Text>
            <XStack alignItems="center" justifyContent="space-between">
              <Text fontSize="$1" color="$color" opacity={0.6}>
                {percentage}%
              </Text>
              <Text fontSize="$1" color="$color" opacity={0.6}>
                {badge.earned ? completeCopy : `${progress}/${target}`}
              </Text>
            </XStack>
            <YStack height={6} borderRadius={999} backgroundColor={isDark ? 'rgba(255, 255, 255, 0.16)' : 'rgba(15, 23, 42, 0.08)'}>
              <YStack
                height={6}
                borderRadius={999}
                backgroundColor="rgba(244, 63, 94, 0.8)"
                style={{ width: `${percentage}%` }}
              />
            </YStack>
          </YStack>
        );
      })}
    </XStack>
  );
}

type TimelineProps = {
  points: TimelinePoint[];
  formatNumber: (value: number) => string;
  emptyCopy: string;
  isDark: boolean;
};

function Timeline({ points, formatNumber, emptyCopy, isDark }: TimelineProps) {
  if (points.length === 0) {
    return (
      <Text fontSize="$2" color="$color" opacity={0.7}>
        {emptyCopy}
      </Text>
    );
  }

  return (
    <YStack gap="$2">
      {points.map((point) => (
        <XStack
          key={point.date}
          alignItems="center"
          justifyContent="space-between"
          padding="$2"
          borderRadius="$card"
          backgroundColor={isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(15, 23, 42, 0.05)'}
          borderWidth={1}
          borderColor={isDark ? 'rgba(255, 255, 255, 0.16)' : 'rgba(15, 23, 42, 0.08)'}
        >
          <Text fontSize="$2" fontWeight="$6">
            {point.date}
          </Text>
          <Text fontSize="$1" color="$color" opacity={0.7}>
            {formatNumber(point.photos)} photos · {formatNumber(point.guests)} guests
          </Text>
        </XStack>
      ))}
    </YStack>
  );
}

type HighlightsProps = {
  topPhoto: TopPhotoHighlight | null;
  trendingEmotion: TrendingEmotionHighlight | null;
  formatRelativeTime: (value: string) => string;
  locale: string;
  formatNumber: (value: number) => string;
  emptyCopy: string;
  topPhotoTitle: string;
  topPhotoNoPreview: string;
  topPhotoFallbackGuest: string;
  trendingTitle: string;
  trendingCountLabel: string;
  isDark: boolean;
};

function Highlights({
  topPhoto,
  trendingEmotion,
  formatRelativeTime,
  locale,
  formatNumber,
  emptyCopy,
  topPhotoTitle,
  topPhotoNoPreview,
  topPhotoFallbackGuest,
  trendingTitle,
  trendingCountLabel,
  isDark,
}: HighlightsProps) {
  if (!topPhoto && !trendingEmotion) {
    return (
      <Text fontSize="$2" color="$color" opacity={0.7}>
        {emptyCopy}
      </Text>
    );
  }

  return (
    <YStack gap="$3">
      {topPhoto ? (
        <YStack gap="$2">
          <XStack alignItems="center" justifyContent="space-between">
            <Text fontSize="$3" fontWeight="$7">
              {topPhotoTitle}
            </Text>
            <Trophy size={18} color="#FBBF24" />
          </XStack>
          <YStack gap="$2">
            {topPhoto.thumbnail ? (
              <img
                src={topPhoto.thumbnail}
                alt="Top photo"
                style={{ width: '100%', height: 180, objectFit: 'cover', borderRadius: 16 }}
              />
            ) : (
              <YStack
                height={180}
                borderRadius={16}
                backgroundColor={isDark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(15, 23, 42, 0.08)'}
                alignItems="center"
                justifyContent="center"
              >
                <Text fontSize="$2" color="$color" opacity={0.7}>
                  {topPhotoNoPreview}
                </Text>
              </YStack>
            )}
            <Text fontSize="$2" fontWeight="$6">
              {topPhoto.guest || topPhotoFallbackGuest}
            </Text>
            <Text fontSize="$1" color="$color" opacity={0.7}>
              {formatNumber(topPhoto.likes)} likes · {formatRelativeTime(topPhoto.createdAt)}
            </Text>
            {topPhoto.task ? (
              <Text fontSize="$1" color="$color" opacity={0.7}>
                {localizeTaskLabel(topPhoto.task ?? null, locale) ?? topPhoto.task}
              </Text>
            ) : null}
          </YStack>
        </YStack>
      ) : null}

      {trendingEmotion ? (
        <YStack gap="$2">
          <XStack alignItems="center" justifyContent="space-between">
            <Text fontSize="$3" fontWeight="$7">
              {trendingTitle}
            </Text>
            <Flame size={18} color="#F43F5E" />
          </XStack>
          <Text fontSize="$4" fontWeight="$8">
            {trendingEmotion.name}
          </Text>
          <Text fontSize="$1" color="$color" opacity={0.7}>
            {trendingCountLabel.replace('{count}', formatNumber(trendingEmotion.count))}
          </Text>
        </YStack>
      ) : null}
    </YStack>
  );
}

type FeedProps = {
  feed: FeedEntry[];
  formatRelativeTime: (value: string) => string;
  locale: string;
  formatNumber: (value: number) => string;
  emptyCopy: string;
  guestFallback: string;
  likesLabel: string;
  isDark: boolean;
};

function Feed({ feed, formatRelativeTime, locale, formatNumber, emptyCopy, guestFallback, likesLabel, isDark }: FeedProps) {
  if (feed.length === 0) {
    return (
      <Text fontSize="$2" color="$color" opacity={0.7}>
        {emptyCopy}
      </Text>
    );
  }

  return (
    <YStack gap="$3">
      {feed.map((item) => {
        const taskLabel = localizeTaskLabel(item.task ?? null, locale);
        return (
          <XStack
            key={item.photoId}
            gap="$2"
            padding="$2"
            borderRadius="$card"
            backgroundColor={isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(15, 23, 42, 0.05)'}
            borderWidth={1}
            borderColor={isDark ? 'rgba(255, 255, 255, 0.16)' : 'rgba(15, 23, 42, 0.08)'}
          >
            {item.thumbnail ? (
              <img
                src={item.thumbnail}
                alt="Feed thumbnail"
                style={{ width: 64, height: 64, objectFit: 'cover', borderRadius: 12 }}
              />
            ) : (
              <YStack
                width={64}
                height={64}
                borderRadius={12}
                backgroundColor={isDark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(15, 23, 42, 0.08)'}
                alignItems="center"
                justifyContent="center"
              >
                <Camera size={18} color={isDark ? '#F8FAFF' : '#0F172A'} />
              </YStack>
            )}
            <YStack flex={1} gap="$1">
              <Text fontSize="$2" fontWeight="$7">
                {item.guest || guestFallback}
              </Text>
              {taskLabel ? (
                <Text fontSize="$1" color="$color" opacity={0.7}>
                  {taskLabel}
                </Text>
              ) : null}
              <XStack gap="$3">
                <Text fontSize="$1" color="$color" opacity={0.6}>
                  {formatRelativeTime(item.createdAt)}
                </Text>
                <Text fontSize="$1" color="$color" opacity={0.6}>
                  {likesLabel.replace('{count}', formatNumber(item.likes))}
                </Text>
              </XStack>
            </YStack>
          </XStack>
        );
      })}
    </YStack>
  );
}

export default function AchievementsScreen() {
  const { token, tasksEnabled } = useEventData();
  const identity = useOptionalGuestIdentity();
  const { t } = useTranslation();
  const { locale } = useLocale();
  const { isDark } = useGuestThemeVariant();
  const navigate = useNavigate();
  const mutedButton = isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(15, 23, 42, 0.06)';
  const mutedButtonBorder = isDark ? 'rgba(255, 255, 255, 0.2)' : 'rgba(15, 23, 42, 0.12)';
  const [payload, setPayload] = React.useState<AchievementsPayload | null>(null);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);
  const [activeTab, setActiveTab] = React.useState<TabKey>('personal');

  const numberFormatter = React.useMemo(() => new Intl.NumberFormat(locale), [locale]);
  const formatNumber = (value: number) => numberFormatter.format(value);
  const relativeFormatter = React.useMemo(() => new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }), [locale]);
  const formatRelative = (value: string) => formatRelativeTimestamp(value, relativeFormatter);

  const loadAchievements = React.useCallback(async (forceRefresh = false) => {
    if (!token) return;
    setLoading(true);
    setError(null);

    try {
      const data = await fetchAchievements(token, {
        guestName: identity?.name ?? undefined,
        locale,
        forceRefresh,
      });
      setPayload(data);
      setActiveTab(data.personal ? 'personal' : 'event');
    } catch (err) {
      console.error('Failed to load achievements', err);
      setError(err instanceof Error ? err.message : GENERIC_ERROR);
    } finally {
      setLoading(false);
    }
  }, [identity?.name, locale, token]);

  React.useEffect(() => {
    loadAchievements();
  }, [loadAchievements]);

  if (!token) {
    return null;
  }

  const hasPersonal = Boolean(payload?.personal);
  const summary = payload?.summary;
  const personal = payload?.personal ?? null;
  const leaderboards = payload?.leaderboards ?? null;
  const highlights = payload?.highlights ?? null;
  const feed = payload?.feed ?? [];

  const headerGradient = isDark
    ? 'radial-gradient(120% 120% at 20% 20%, rgba(79, 209, 255, 0.16), transparent 60%), radial-gradient(120% 120% at 80% 0%, rgba(244, 63, 94, 0.18), transparent 60%)'
    : 'radial-gradient(140% 140% at 20% 10%, color-mix(in oklab, var(--guest-primary, #0EA5E9) 22%, white), transparent 55%), radial-gradient(120% 120% at 80% 0%, color-mix(in oklab, var(--guest-secondary, #F43F5E) 22%, white), transparent 60%)';

  const content = (
    <YStack gap="$4" paddingBottom={100}>
      <BentoCard isDark={isDark} padding={20} gradient={headerGradient}>
        <XStack alignItems="center" gap="$2">
          <YStack
            width={40}
            height={40}
            borderRadius={14}
            backgroundColor="rgba(244, 63, 94, 0.16)"
            alignItems="center"
            justifyContent="center"
          >
            <Award size={18} color="#F43F5E" />
          </YStack>
          <YStack gap="$0.5" flexShrink={1} maxWidth="100%">
            <Text fontSize="$5" fontWeight="$8">
              {t('achievements.page.title', 'Achievements')}
            </Text>
            <Text fontSize="$2" color="$color" opacity={0.7} flexWrap="wrap">
              {t('achievements.page.subtitle', 'Track your milestones and highlight streaks.')}
            </Text>
          </YStack>
        </XStack>
      </BentoCard>

      {summary ? (
        <XStack gap="$2" flexWrap="nowrap" overflow="hidden">
          {[
            { label: t('achievements.summary.photosShared', 'Photos shared'), value: summary.totalPhotos },
            ...(tasksEnabled
              ? [{ label: t('achievements.summary.tasksCompleted', 'Tasks completed'), value: summary.tasksSolved }]
              : []),
            { label: t('achievements.summary.likesCollected', 'Likes collected'), value: summary.likesTotal },
            { label: t('achievements.summary.uniqueGuests', 'Guests involved'), value: summary.uniqueGuests },
          ].map((item) => (
            <YStack key={item.label} flex={1} minWidth={0}>
              <BentoCard isDark={isDark} padding={10}>
                <Text fontSize="$3" fontWeight="$8">
                  {formatNumber(item.value)}
                </Text>
                <Text fontSize="$1" color="$color" opacity={0.7} numberOfLines={2}>
                  {item.label}
                </Text>
              </BentoCard>
            </YStack>
          ))}
        </XStack>
      ) : null}

      <XStack gap="$2" flexWrap="wrap">
        {([
          { key: 'personal', label: t('achievements.page.buttons.personal', 'Personal'), icon: Sparkles, disabled: !hasPersonal },
          { key: 'event', label: t('achievements.page.buttons.event', 'Event'), icon: Users, disabled: false },
          { key: 'feed', label: t('achievements.page.buttons.feed', 'Feed'), icon: BarChart2, disabled: false },
        ] as const).map((tab) => (
          <Button
            key={tab.key}
            size="$3"
            borderRadius="$pill"
            backgroundColor={activeTab === tab.key ? '$primary' : mutedButton}
            borderWidth={1}
            borderColor={activeTab === tab.key ? '$primary' : mutedButtonBorder}
            onPress={() => setActiveTab(tab.key)}
            disabled={tab.disabled}
            opacity={tab.disabled ? 0.5 : 1}
          >
            <XStack alignItems="center" gap="$2">
              <tab.icon size={14} color={activeTab === tab.key ? '#FFFFFF' : isDark ? '#F8FAFF' : '#0F172A'} />
              <Text fontSize="$2" fontWeight="$7" color={activeTab === tab.key ? '#FFFFFF' : undefined}>
                {tab.label}
              </Text>
            </XStack>
          </Button>
        ))}
      </XStack>

      {loading ? (
        <YStack gap="$3">
          {Array.from({ length: 3 }).map((_, index) => (
            <BentoCard key={`loading-${index}`} isDark={isDark}>
              <YStack height={56} />
            </BentoCard>
          ))}
        </YStack>
      ) : error ? (
        <BentoCard isDark={isDark}>
          <Text fontSize="$2" color={isDark ? '#FCA5A5' : '#DC2626'}>
            {error === GENERIC_ERROR
              ? t('achievements.page.loadError', 'Achievements could not be loaded.')
              : error}
          </Text>
        </BentoCard>
      ) : payload ? (
        <YStack gap="$4">
          {activeTab === 'personal' ? (
            <YStack gap="$4">
              <BentoCard isDark={isDark}>
                <YStack gap="$2">
                  <Text fontSize="$3" fontWeight="$7">
                    {t('achievements.badges.title', 'Badges')}
                  </Text>
                  <Text fontSize="$2" color="$color" opacity={0.7}>
                    {t('achievements.badges.description', 'Unlock achievements and keep your streak going.')}
                  </Text>
                  <BadgesGrid
                    badges={personal?.badges ?? []}
                    emptyCopy={t('achievements.badges.empty', 'No badges yet.')}
                    completeCopy={t('achievements.badges.complete', 'Complete')}
                    isDark={isDark}
                  />
                </YStack>
              </BentoCard>
            </YStack>
          ) : null}

          {activeTab === 'event' ? (
            <YStack gap="$4">
              <BentoCard isDark={isDark}>
                <Highlights
                  topPhoto={highlights?.topPhoto ?? null}
                  trendingEmotion={highlights?.trendingEmotion ?? null}
                  formatRelativeTime={formatRelative}
                  locale={locale}
                  formatNumber={formatNumber}
                  emptyCopy={t('achievements.highlights.empty', 'Highlights will appear as soon as more photos are shared.')}
                  topPhotoTitle={t('achievements.highlights.topTitle', 'Top photo')}
                  topPhotoNoPreview={t('achievements.highlights.noPreview', 'No preview')}
                  topPhotoFallbackGuest={t('achievements.leaderboard.guestFallback', 'Guest')}
                  trendingTitle={t('achievements.highlights.trendingTitle', 'Trending emotion')}
                  trendingCountLabel={t('achievements.highlights.trendingCount', { count: '{count}' }, '{count} photos')}
                  isDark={isDark}
                />
              </BentoCard>

              <XStack gap="$3" flexWrap="wrap">
                <YStack flex={1} minWidth={240} gap="$3">
                  <BentoCard isDark={isDark}>
                    <Text fontSize="$3" fontWeight="$7">
                      {t('achievements.timeline.title', 'Timeline')}
                    </Text>
                    <Text fontSize="$2" color="$color" opacity={0.7}>
                      {t('achievements.timeline.description', 'Daily momentum snapshot.')}
                    </Text>
                    <Timeline
                      points={highlights?.timeline ?? []}
                      formatNumber={formatNumber}
                      emptyCopy={t('achievements.timeline.empty', 'No timeline data yet.')}
                      isDark={isDark}
                    />
                  </BentoCard>
                </YStack>
                <YStack flex={1} minWidth={240} gap="$3">
                  <BentoCard isDark={isDark}>
                    <Leaderboard
                      title={t('achievements.leaderboard.uploadsTitle', 'Top uploads')}
                      description={t('achievements.leaderboard.description', 'Most photos shared.')}
                      icon={Users}
                      entries={leaderboards?.uploads ?? []}
                      emptyCopy={t('achievements.leaderboard.uploadsEmpty', 'No uploads yet.')}
                      formatNumber={formatNumber}
                      guestFallback={t('achievements.leaderboard.guestFallback', 'Guest')}
                      isDark={isDark}
                    />
                  </BentoCard>
                  <BentoCard isDark={isDark}>
                    <Leaderboard
                      title={t('achievements.leaderboard.likesTitle', 'Top likes')}
                      description={t('achievements.leaderboard.description', 'Most loved moments.')}
                      icon={Trophy}
                      entries={leaderboards?.likes ?? []}
                      emptyCopy={t('achievements.leaderboard.likesEmpty', 'No likes yet.')}
                      formatNumber={formatNumber}
                      guestFallback={t('achievements.leaderboard.guestFallback', 'Guest')}
                      isDark={isDark}
                    />
                  </BentoCard>
                </YStack>
              </XStack>
            </YStack>
          ) : null}

          {activeTab === 'feed' ? (
            <BentoCard isDark={isDark}>
              <Feed
                feed={feed}
                formatRelativeTime={formatRelative}
                locale={locale}
                formatNumber={formatNumber}
                emptyCopy={t('achievements.feed.empty', 'The feed is quiet for now.')}
                guestFallback={t('achievements.leaderboard.guestFallback', 'Guest')}
                likesLabel={t('achievements.feed.likesLabel', { count: '{count}' }, '{count} likes')}
                isDark={isDark}
              />
            </BentoCard>
          ) : null}

        </YStack>
      ) : null}
    </YStack>
  );

  return (
    <AppShell>
      <PullToRefresh
        onRefresh={() => loadAchievements(true)}
        pullLabel={t('common.pullToRefresh')}
        releaseLabel={t('common.releaseToRefresh')}
        refreshingLabel={t('common.refreshing')}
      >
        {content}
      </PullToRefresh>
    </AppShell>
  );
}
