import React from 'react';
import { useNavigate } from 'react-router-dom';
import { XStack, YStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Button } from '@tamagui/button';
import { Camera, Sparkles, Image as ImageIcon, Trophy, Star } from 'lucide-react';
import AppShell from '../components/AppShell';
import PhotoFrameTile from '../components/PhotoFrameTile';
import { useEventData } from '../context/EventDataContext';
import { buildEventPath } from '../lib/routes';
import { useStaggeredReveal } from '../lib/useStaggeredReveal';
import { usePollStats } from '../hooks/usePollStats';
import { fetchGallery } from '../services/photosApi';
import { useUploadQueue } from '../services/uploadApi';
import { useTranslation } from '@/guest/i18n/useTranslation';
import { useAppearance } from '@/hooks/use-appearance';

type ActionRingProps = {
  label: string;
  icon: React.ReactNode;
  onPress: () => void;
};

type GalleryPreview = {
  id: number;
  imageUrl: string;
};

function ActionRing({
  label,
  icon,
  onPress,
  isDark,
}: ActionRingProps & { isDark: boolean }) {
  return (
    <Button unstyled onPress={onPress}>
      <YStack alignItems="center" gap="$2">
        <YStack
          width={74}
          height={74}
          borderRadius={37}
          backgroundColor="$surface"
          borderWidth={2}
          borderColor="$primary"
          alignItems="center"
          justifyContent="center"
          style={{
            backgroundImage: isDark
              ? 'radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0.05))'
              : 'radial-gradient(circle at 30% 30%, color-mix(in oklab, var(--guest-primary, #FF5A5F) 20%, white), rgba(255, 255, 255, 0.7))',
            boxShadow: isDark
              ? '0 10px 24px rgba(255, 79, 216, 0.2)'
              : '0 10px 24px rgba(15, 23, 42, 0.12)',
          }}
        >
          {icon}
        </YStack>
        <Text fontSize="$2" fontWeight="$6" color="$color" opacity={0.9}>
          {label}
        </Text>
      </YStack>
    </Button>
  );
}

function QuickStats({
  reveal,
  stats,
  queueCount,
  isDark,
}: {
  reveal: number;
  stats: { onlineGuests: number; tasksSolved: number };
  queueCount: number;
  isDark: boolean;
}) {
  const { t } = useTranslation();
  const cardBorder = isDark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(15, 23, 42, 0.12)';
  const cardShadow = isDark ? '0 16px 30px rgba(2, 6, 23, 0.35)' : '0 14px 24px rgba(15, 23, 42, 0.12)';
  return (
    <XStack
      gap="$3"
      animation="slow"
      animateOnly={['transform', 'opacity']}
      opacity={reveal >= 3 ? 1 : 0}
      y={reveal >= 3 ? 0 : 12}
    >
      <YStack
        flex={1}
        padding="$3"
        borderRadius="$card"
        backgroundColor="$surface"
        borderWidth={1}
        borderColor={cardBorder}
        gap="$1"
        style={{
          boxShadow: cardShadow,
        }}
      >
        <Text fontSize="$4" fontWeight="$8">
          {stats.onlineGuests}
        </Text>
        <Text fontSize="$2" color="$color" opacity={0.7}>
          {t('home.stats.online', 'Guests online')}
        </Text>
      </YStack>
      <YStack
        flex={1}
        padding="$3"
        borderRadius="$card"
        backgroundColor="$surface"
        borderWidth={1}
        borderColor={cardBorder}
        gap="$1"
        style={{
          boxShadow: cardShadow,
        }}
      >
        <Text fontSize="$4" fontWeight="$8">
          {queueCount}
        </Text>
        <Text fontSize="$2" color="$color" opacity={0.7}>
          {t('homeV2.stats.uploadsQueued', 'Uploads queued')}
        </Text>
      </YStack>
    </XStack>
  );
}

function normalizeImageUrl(src?: string | null) {
  if (!src) {
    return '';
  }

  if (/^https?:/i.test(src)) {
    return src;
  }

  let cleanPath = src.replace(/^\/+/g, '').replace(/\/+/g, '/');
  if (!cleanPath.startsWith('storage/')) {
    cleanPath = `storage/${cleanPath}`;
  }

  return `/${cleanPath}`.replace(/\/+/g, '/');
}

export default function HomeScreen() {
  const { tasksEnabled, token } = useEventData();
  const navigate = useNavigate();
  const revealStage = useStaggeredReveal({ steps: 4, intervalMs: 140, delayMs: 120 });
  const { stats } = usePollStats(token ?? null);
  const { items } = useUploadQueue();
  const [preview, setPreview] = React.useState<GalleryPreview[]>([]);
  const [previewLoading, setPreviewLoading] = React.useState(false);
  const { t } = useTranslation();
  const { resolved } = useAppearance();
  const isDark = resolved === 'dark';
  const cardBorder = isDark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(15, 23, 42, 0.12)';
  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 cardShadow = isDark ? '0 18px 40px rgba(2, 6, 23, 0.4)' : '0 16px 32px rgba(15, 23, 42, 0.12)';

  const goTo = (path: string) => () => navigate(buildEventPath(token, path));

  const rings = [
    tasksEnabled
      ? {
          label: t('home.actions.items.tasks.label', 'Draw a task card'),
          icon: <Sparkles size={20} color={isDark ? '#F8FAFF' : '#0F172A'} />,
          path: '/tasks',
        }
      : {
          label: t('home.actions.items.upload.label', 'Upload photo'),
          icon: <Camera size={20} color={isDark ? '#F8FAFF' : '#0F172A'} />,
          path: '/upload',
        },
    {
      label: t('homeV2.rings.newUploads', 'New uploads'),
      icon: <ImageIcon size={20} color={isDark ? '#F8FAFF' : '#0F172A'} />,
      path: '/gallery',
    },
    {
      label: t('homeV2.rings.topMoments', 'Top moments'),
      icon: <Star size={20} color={isDark ? '#F8FAFF' : '#0F172A'} />,
      path: '/gallery',
    },
    {
      label: t('navigation.achievements', 'Achievements'),
      icon: <Trophy size={20} color={isDark ? '#F8FAFF' : '#0F172A'} />,
      path: '/achievements',
    },
  ];

  React.useEffect(() => {
    if (!token) {
      setPreview([]);
      return;
    }

    let active = true;
    setPreviewLoading(true);

    fetchGallery(token, { limit: 3 })
      .then((response) => {
        if (!active) return;
        const photos = Array.isArray(response.data) ? response.data : [];
        const mapped = photos
          .map((photo) => {
            const record = photo as Record<string, unknown>;
            const id = Number(record.id ?? 0);
            const imageUrl = normalizeImageUrl(
              (record.thumbnail_url as string | null | undefined)
                ?? (record.thumbnail_path as string | null | undefined)
                ?? (record.file_path as string | null | undefined)
                ?? (record.full_url as string | null | undefined)
                ?? (record.url as string | null | undefined)
                ?? (record.image_url as string | null | undefined)
            );
            return { id, imageUrl };
          })
          .filter((item) => item.id && item.imageUrl);
        setPreview(mapped);
      })
      .catch((error) => {
        console.error('Failed to load gallery preview', error);
        if (active) {
          setPreview([]);
        }
      })
      .finally(() => {
        if (active) {
          setPreviewLoading(false);
        }
      });

    return () => {
      active = false;
    };
  }, [token]);

  const queueCount = items.filter((item) => item.status !== 'done').length;

  return (
    <AppShell>
      <YStack gap="$4">
        <YStack
          gap="$3"
          animation="slow"
          animateOnly={['transform', 'opacity']}
          opacity={revealStage >= 1 ? 1 : 0}
          y={revealStage >= 1 ? 0 : 12}
        >
          <XStack gap="$2" justifyContent="space-between">
            {rings.map((ring) => (
              <YStack key={ring.label} flex={1} alignItems="center">
                <ActionRing label={ring.label} icon={ring.icon} onPress={goTo(ring.path)} isDark={isDark} />
              </YStack>
            ))}
          </XStack>
        </YStack>

        {tasksEnabled ? (
          <YStack
            padding="$4"
            borderRadius="$card"
            backgroundColor="$surface"
            borderWidth={1}
            borderColor={cardBorder}
            gap="$3"
            y={revealStage >= 2 ? 0 : 16}
            style={{
              backgroundImage: isDark
                ? 'linear-gradient(135deg, rgba(255, 79, 216, 0.25), rgba(79, 209, 255, 0.12))'
                : 'linear-gradient(135deg, color-mix(in oklab, var(--guest-primary, #FF5A5F) 18%, white), color-mix(in oklab, var(--guest-secondary, #F43F5E) 10%, white))',
              boxShadow: cardShadow,
            }}
          >
            <XStack alignItems="center" gap="$2">
              <Sparkles size={18} color="#FF4FD8" />
              <Text fontSize="$3" fontWeight="$7">
                {t('homeV2.promptQuest.label', 'Prompt quest')}
              </Text>
            </XStack>
            <Text fontSize="$7" fontFamily="$display" fontWeight="$8">
              {t('homeV2.promptQuest.title', 'Capture the happiest laugh')}
            </Text>
            <Text fontSize="$3" color="$color" opacity={0.75}>
              {t('homeV2.promptQuest.subtitle', 'Earn points and keep the gallery lively.')}
            </Text>
            <XStack gap="$2" flexWrap="wrap">
              <Button size="$4" backgroundColor="$primary" borderRadius="$pill" onPress={goTo('/upload')}>
                {t('homeV2.promptQuest.ctaStart', 'Start prompt')}
              </Button>
              <Button
                size="$4"
                backgroundColor={mutedButton}
                borderRadius="$pill"
                borderWidth={1}
                borderColor={mutedButtonBorder}
                onPress={goTo('/tasks')}
              >
                {t('homeV2.promptQuest.ctaBrowse', 'Browse tasks')}
              </Button>
            </XStack>
          </YStack>
        ) : (
          <YStack
            padding="$4"
            borderRadius="$card"
            backgroundColor="$surface"
            borderWidth={1}
            borderColor={cardBorder}
            gap="$3"
            y={revealStage >= 2 ? 0 : 16}
            style={{
              backgroundImage: isDark
                ? 'linear-gradient(135deg, rgba(79, 209, 255, 0.18), rgba(255, 79, 216, 0.12))'
                : 'linear-gradient(135deg, color-mix(in oklab, var(--guest-secondary, #F43F5E) 10%, white), color-mix(in oklab, var(--guest-primary, #FF5A5F) 10%, white))',
              boxShadow: cardShadow,
            }}
          >
            <XStack alignItems="center" gap="$2">
              <Camera size={18} color={isDark ? '#F8FAFF' : '#0F172A'} />
              <Text fontSize="$3" fontWeight="$7">
                {t('homeV2.captureReady.label', 'Capture ready')}
              </Text>
            </XStack>
            <Text fontSize="$7" fontFamily="$display" fontWeight="$8">
              {t('homeV2.captureReady.title', 'Add a photo to the shared gallery')}
            </Text>
            <Text fontSize="$3" color="$color" opacity={0.75}>
              {t('homeV2.captureReady.subtitle', 'Quick add from your camera or device.')}
            </Text>
            <Button size="$4" backgroundColor="$primary" borderRadius="$pill" onPress={goTo('/upload')}>
              {t('homeV2.captureReady.cta', 'Upload / Take photo')}
            </Button>
          </YStack>
        )}

        <QuickStats
          reveal={revealStage}
          stats={{ onlineGuests: stats.onlineGuests, tasksSolved: stats.tasksSolved }}
          queueCount={queueCount}
          isDark={isDark}
        />

        <YStack
          padding="$4"
          borderRadius="$card"
          backgroundColor="$surface"
          borderWidth={1}
          borderColor={cardBorder}
          gap="$3"
          animation="slow"
          animateOnly={['transform', 'opacity']}
          opacity={revealStage >= 4 ? 1 : 0}
          y={revealStage >= 4 ? 0 : 16}
          style={{
            boxShadow: cardShadow,
          }}
        >
          <XStack alignItems="center" justifyContent="space-between">
            <Text fontSize="$4" fontWeight="$7">
              {t('homeV2.galleryPreview.title', 'Gallery preview')}
            </Text>
            <Button
              size="$3"
              backgroundColor={mutedButton}
              borderRadius="$pill"
              borderWidth={1}
              borderColor={mutedButtonBorder}
              onPress={goTo('/gallery')}
            >
              {t('homeV2.galleryPreview.cta', 'View all')}
            </Button>
          </XStack>
          <XStack
            gap="$2"
            style={{
              overflowX: 'auto',
              WebkitOverflowScrolling: 'touch',
              paddingBottom: 6,
            }}
          >
            {(previewLoading || preview.length === 0 ? [1, 2, 3, 4] : preview).map((tile, index) => {
              if (typeof tile === 'number') {
                return (
                  <YStack key={tile} flexShrink={0} width={140}>
                    <PhotoFrameTile height={110} shimmer shimmerDelayMs={tile * 140} />
                  </YStack>
                );
              }
              return (
                <YStack key={tile.id} flexShrink={0} width={140}>
                  <PhotoFrameTile height={110}>
                    <YStack
                      flex={1}
                      width="100%"
                      height="100%"
                      style={{
                        backgroundImage: `url(${tile.imageUrl})`,
                        backgroundSize: 'cover',
                        backgroundPosition: 'center',
                      }}
                    />
                  </PhotoFrameTile>
                </YStack>
              );
            })}
          </XStack>
        </YStack>
      </YStack>
    </AppShell>
  );
}
