import React from 'react';
import { useNavigate } from 'react-router-dom';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Button } from '@tamagui/button';
import { Input } from '@tamagui/input';
import { Card } from '@tamagui/card';
import { Html5Qrcode } from 'html5-qrcode';
import { QrCode, ArrowRight } from 'lucide-react';
import { useTranslation } from '@/guest/i18n/useTranslation';
import { fetchEvent } from '../services/eventApi';
import { readGuestName } from '../context/GuestIdentityContext';
import EventLogo from '../components/EventLogo';
import { useGuestThemeVariant } from '../lib/guestTheme';

const qrConfig = { fps: 10, qrbox: { width: 240, height: 240 } } as const;

type LandingErrorKey = 'eventClosed' | 'network' | 'camera';

export default function LandingScreen() {
  const navigate = useNavigate();
  const { t } = useTranslation();
  const [eventCode, setEventCode] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [errorKey, setErrorKey] = React.useState<LandingErrorKey | null>(null);
  const [isScanning, setIsScanning] = React.useState(false);
  const scannerRef = React.useRef<Html5Qrcode | null>(null);
  const { isDark } = useGuestThemeVariant();
  const cardBackground = isDark ? 'rgba(15, 23, 42, 0.7)' : 'rgba(255, 255, 255, 0.9)';
  const cardBorder = isDark ? 'rgba(148, 163, 184, 0.2)' : 'rgba(15, 23, 42, 0.12)';
  const primaryText = isDark ? '#F8FAFF' : '#0F172A';
  const mutedText = isDark ? 'rgba(226, 232, 240, 0.78)' : 'rgba(15, 23, 42, 0.6)';
  const mutedButton = isDark ? 'rgba(248, 250, 255, 0.1)' : 'rgba(15, 23, 42, 0.06)';
  const mutedButtonBorder = isDark ? 'rgba(248, 250, 255, 0.2)' : 'rgba(15, 23, 42, 0.12)';
  const brandName = 'Fotospiel';

  const errorMessage = errorKey ? t(`landing.errors.${errorKey}`) : null;

  const extractEventKey = React.useCallback((raw: string): string => {
    const trimmed = raw.trim();
    if (!trimmed) {
      return '';
    }

    try {
      const url = new URL(trimmed);
      const inviteParam = url.searchParams.get('invite') ?? url.searchParams.get('token');
      if (inviteParam) {
        return inviteParam;
      }
      const segments = url.pathname.split('/').filter(Boolean);
      const eventIndex = segments.findIndex((segment) => segment === 'e');
      if (eventIndex >= 0 && segments.length > eventIndex + 1) {
        return decodeURIComponent(segments[eventIndex + 1]);
      }
      if (segments.length > 0) {
        return decodeURIComponent(segments[segments.length - 1]);
      }
    } catch {
      // Not a URL, treat as raw code.
    }

    return trimmed;
  }, []);

  const join = React.useCallback(
    async (input?: string) => {
      const provided = input ?? eventCode;
      const normalized = extractEventKey(provided);
      if (!normalized) return;

      setLoading(true);
      setErrorKey(null);

      try {
        const event = await fetchEvent(normalized);
        const targetKey = event.join_token ?? normalized;
        if (!targetKey) {
          setErrorKey('eventClosed');
          return;
        }

        const storedName = readGuestName(targetKey);
        if (!storedName) {
          navigate(`/setup/${encodeURIComponent(targetKey)}`);
        } else {
          navigate(`/e/${encodeURIComponent(targetKey)}`);
        }
      } catch (error) {
        console.error('Join request failed', error);
        setErrorKey('network');
      } finally {
        setLoading(false);
      }
    },
    [eventCode, extractEventKey, navigate]
  );

  const onScanSuccess = React.useCallback(
    async (decodedText: string) => {
      const value = decodedText.trim();
      if (!value) return;
      await join(value);
      if (scannerRef.current) {
        try {
          await scannerRef.current.stop();
        } catch (error) {
          console.warn('Scanner stop failed', error);
        }
      }
      setIsScanning(false);
    },
    [join]
  );

  const startScanner = React.useCallback(async () => {
    if (scannerRef.current) {
      try {
        await scannerRef.current.start({ facingMode: 'environment' }, qrConfig, onScanSuccess, () => undefined);
        setIsScanning(true);
      } catch (error) {
        console.error('Scanner start failed', error);
        setErrorKey('camera');
      }
      return;
    }

    try {
      const scanner = new Html5Qrcode('qr-reader');
      scannerRef.current = scanner;
      await scanner.start({ facingMode: 'environment' }, qrConfig, onScanSuccess, () => undefined);
      setIsScanning(true);
    } catch (error) {
      console.error('Scanner init failed', error);
      setErrorKey('camera');
    }
  }, [onScanSuccess]);

  const stopScanner = React.useCallback(async () => {
    if (!scannerRef.current) {
      setIsScanning(false);
      return;
    }

    try {
      await scannerRef.current.stop();
    } catch (error) {
      console.warn('Scanner stop failed', error);
    } finally {
      setIsScanning(false);
    }
  }, []);

  React.useEffect(() => () => {
    if (scannerRef.current) {
      scannerRef.current.stop().catch(() => undefined);
    }
  }, []);

  return (
    <YStack flex={1} minHeight="100vh" padding="$5" justifyContent="center" backgroundColor={isDark ? '#0B101E' : '#FFF8F5'}>
      <YStack gap="$5" maxWidth={480} width="100%" alignSelf="center">
        <XStack alignItems="center" gap="$3">
          <EventLogo name={brandName} size="s" />
          <Text fontSize="$5" fontFamily="$display" fontWeight="$8" color={primaryText}>
            {brandName}
          </Text>
        </XStack>
        <YStack gap="$2">
          <Text fontSize="$8" fontFamily="$display" fontWeight="$9" color={primaryText}>
            {t('landing.pageTitle')}
          </Text>
          <Text color={mutedText}>
            {t('landing.subheadline')}
          </Text>
        </YStack>

        {errorMessage ? (
          <Card padding="$3" backgroundColor="rgba(248, 113, 113, 0.12)" borderColor="rgba(248, 113, 113, 0.4)" borderWidth={1}>
            <Text color="#FEE2E2">{errorMessage}</Text>
          </Card>
        ) : null}

        <Card padding="$4" backgroundColor={cardBackground} borderColor={cardBorder} borderWidth={1}>
          <YStack gap="$4">
            <XStack alignItems="center" gap="$2">
              <QrCode size={18} color={primaryText} />
              <Text fontSize="$5" fontWeight="$8" color={primaryText}>
                {t('landing.join.title')}
              </Text>
            </XStack>
            <Text color={mutedText}>
              {t('landing.join.description')}
            </Text>

            <YStack gap="$3">
              <YStack
                id="qr-reader"
                height={240}
                borderRadius="$4"
                backgroundColor={isDark ? 'rgba(15, 23, 42, 0.55)' : 'rgba(15, 23, 42, 0.05)'}
                borderWidth={1}
                borderColor={isDark ? 'rgba(148, 163, 184, 0.15)' : 'rgba(15, 23, 42, 0.12)'}
                overflow="hidden"
              />
              <Button
                onPress={isScanning ? stopScanner : startScanner}
                backgroundColor={mutedButton}
                borderColor={mutedButtonBorder}
                borderWidth={1}
              >
                {isScanning ? t('landing.scan.stop', 'Scanner stoppen') : t('landing.scan.start', 'QR-Code scannen')}
              </Button>
            </YStack>

            <Text color={mutedText} textAlign="center">
              {t('landing.scan.manualDivider')}
            </Text>

            <YStack gap="$3">
              <Input
                value={eventCode}
                onChangeText={setEventCode}
                placeholder={t('landing.input.placeholder')}
                backgroundColor={isDark ? 'rgba(15, 23, 42, 0.6)' : 'rgba(15, 23, 42, 0.05)'}
                borderColor={cardBorder}
                color={primaryText}
              />
              <Button
                onPress={() => join()}
                disabled={loading || !eventCode.trim()}
                backgroundColor="$primary"
                color="#FFFFFF"
                iconAfter={loading ? undefined : () => <ArrowRight size={16} color="#FFFFFF" />}
              >
                {loading ? t('landing.join.buttonLoading') : t('landing.join.button')}
              </Button>
            </YStack>
          </YStack>
        </Card>
      </YStack>
    </YStack>
  );
}
