import React from 'react';
import { ScrollView } from '@tamagui/scroll-view';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Button } from '@tamagui/button';
import { ArrowLeft, X } from 'lucide-react';
import SettingsContent from './SettingsContent';
import { useAppearance } from '@/hooks/use-appearance';
import { useTranslation } from '@/guest/i18n/useTranslation';
import { useLocale } from '@/guest/i18n/LocaleContext';
import { LegalMarkdown } from '@/guest/components/legal-markdown';
import type { LocaleCode } from '@/guest/i18n/messages';

const legalLinks = [
  { slug: 'impressum', labelKey: 'settings.legal.section.impressum', fallback: 'Impressum' },
  { slug: 'datenschutz', labelKey: 'settings.legal.section.privacy', fallback: 'Datenschutz' },
  { slug: 'agb', labelKey: 'settings.legal.section.terms', fallback: 'AGB' },
] as const;

type ViewState =
  | { mode: 'home' }
  | { mode: 'legal'; slug: (typeof legalLinks)[number]['slug']; labelKey: (typeof legalLinks)[number]['labelKey'] };

type LegalDocumentState =
  | { phase: 'idle'; title: string; markdown: string; html: string }
  | { phase: 'loading'; title: string; markdown: string; html: string }
  | { phase: 'ready'; title: string; markdown: string; html: string }
  | { phase: 'error'; title: string; markdown: string; html: string };

type SettingsSheetProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

export default function SettingsSheet({ open, onOpenChange }: SettingsSheetProps) {
  const { t } = useTranslation();
  const { locale } = useLocale();
  const { resolved } = useAppearance();
  const isDark = resolved === 'dark';
  const [view, setView] = React.useState<ViewState>({ mode: 'home' });
  const isLegal = view.mode === 'legal';
  const legalDocument = useLegalDocument(isLegal ? view.slug : null, locale);

  const handleBack = React.useCallback(() => setView({ mode: 'home' }), []);
  const handleOpenLegal = React.useCallback(
    (slug: (typeof legalLinks)[number]['slug'], labelKey: (typeof legalLinks)[number]['labelKey']) => {
      setView({ mode: 'legal', slug, labelKey });
    },
    []
  );

  React.useEffect(() => {
    if (!open) {
      setView({ mode: 'home' });
    }
  }, [open]);

  return (
    <>
      <YStack
        position="fixed"
        top={0}
        right={0}
        bottom={0}
        left={0}
        zIndex={1200}
        pointerEvents={open ? 'auto' : 'none'}
        style={{
          backgroundColor: isDark ? 'rgba(15, 23, 42, 0.45)' : 'rgba(15, 23, 42, 0.2)',
          opacity: open ? 1 : 0,
          transition: 'opacity 240ms ease',
        }}
        onPress={() => onOpenChange(false)}
        onClick={() => onOpenChange(false)}
        onMouseDown={() => onOpenChange(false)}
        onTouchStart={() => onOpenChange(false)}
      />
      <YStack
        position="fixed"
        top={0}
        right={0}
        bottom={0}
        zIndex={1300}
        width="85%"
        maxWidth={420}
        backgroundColor={isDark ? '#0B101E' : '#FFFFFF'}
        borderTopLeftRadius="$6"
        borderBottomLeftRadius="$6"
        borderTopRightRadius={0}
        borderBottomRightRadius={0}
        overflow="hidden"
        pointerEvents={open ? 'auto' : 'none'}
        style={{
          transform: open ? 'translateX(0)' : 'translateX(100%)',
          opacity: open ? 1 : 0,
          transition: 'transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1), opacity 220ms ease',
        }}
      >
        <XStack
          alignItems="center"
          justifyContent="space-between"
          paddingHorizontal="$4"
          paddingVertical="$3"
          style={{
            position: 'sticky',
            top: 0,
            zIndex: 2,
            backgroundColor: isDark ? 'rgba(11, 16, 30, 0.95)' : 'rgba(255, 255, 255, 0.95)',
            borderBottom: isDark ? '1px solid rgba(255, 255, 255, 0.08)' : '1px solid rgba(15, 23, 42, 0.1)',
            backdropFilter: 'saturate(160%) blur(18px)',
            WebkitBackdropFilter: 'saturate(160%) blur(18px)',
          }}
        >
          {isLegal ? (
            <XStack alignItems="center" gap="$2">
              <Button
                size="$3"
                circular
                backgroundColor={isDark ? 'rgba(248, 250, 255, 0.08)' : 'rgba(15, 23, 42, 0.06)'}
                borderColor={isDark ? 'rgba(248, 250, 255, 0.2)' : 'rgba(15, 23, 42, 0.12)'}
                borderWidth={1}
                onPress={handleBack}
                aria-label={t('common.actions.back', 'Back')}
              >
                <ArrowLeft size={18} color={isDark ? '#F8FAFF' : '#0F172A'} />
              </Button>
              <YStack>
                <Text fontSize="$5" fontFamily="$display" fontWeight="$8" color={isDark ? '#F8FAFF' : '#0F172A'}>
                  {legalDocument.phase === 'ready' && legalDocument.title
                    ? legalDocument.title
                    : t(view.labelKey, 'Legal')}
                </Text>
                <Text fontSize="$2" color={isDark ? 'rgba(226, 232, 240, 0.7)' : 'rgba(15, 23, 42, 0.6)'}>
                  {legalDocument.phase === 'loading'
                    ? t('common.actions.loading', 'Loading...')
                    : t('settings.legal.description', 'Legal notice')}
                </Text>
              </YStack>
            </XStack>
          ) : (
            <Text fontSize="$6" fontFamily="$display" fontWeight="$8" color={isDark ? '#F8FAFF' : '#0F172A'}>
              {t('settings.title', 'Settings')}
            </Text>
          )}
          <Button
            size="$3"
            circular
            backgroundColor={isDark ? 'rgba(248, 250, 255, 0.08)' : 'rgba(15, 23, 42, 0.06)'}
            borderColor={isDark ? 'rgba(248, 250, 255, 0.2)' : 'rgba(15, 23, 42, 0.12)'}
            borderWidth={1}
            onPress={() => onOpenChange(false)}
            aria-label={t('common.actions.close', 'Close')}
          >
            <X size={18} color={isDark ? '#F8FAFF' : '#0F172A'} />
          </Button>
        </XStack>
        <ScrollView flex={1} showsVerticalScrollIndicator={false} contentContainerStyle={{ padding: 16, paddingBottom: 48 }}>
          <YStack gap="$4">
            {isLegal ? (
              <LegalView
                document={legalDocument}
                fallbackTitle={t(view.labelKey, 'Legal')}
              />
            ) : (
              <SettingsContent
                onNavigate={() => onOpenChange(false)}
                showHeader={false}
                onOpenLegal={handleOpenLegal}
              />
            )}
          </YStack>
        </ScrollView>
      </YStack>
    </>
  );
}

function LegalView({ document, fallbackTitle }: { document: LegalDocumentState; fallbackTitle: string }) {
  const { t } = useTranslation();
  const { resolved } = useAppearance();
  const isDark = resolved === 'dark';
  const mutedText = isDark ? 'rgba(226, 232, 240, 0.7)' : 'rgba(15, 23, 42, 0.6)';

  if (document.phase === 'error') {
    return (
      <YStack gap="$3">
        <Text fontSize="$4" fontWeight="$7" color={isDark ? '#F8FAFF' : '#0F172A'}>
          {t('settings.legal.error', 'Etwas ist schiefgelaufen.')}
        </Text>
        <Text fontSize="$2" color={mutedText}>
          {t('settings.legal.loading', 'Lade...')}
        </Text>
      </YStack>
    );
  }

  if (document.phase === 'loading' || document.phase === 'idle') {
    return (
      <Text fontSize="$2" color={mutedText}>
        {t('settings.legal.loading', 'Lade...')}
      </Text>
    );
  }

  return (
    <YStack gap="$3">
      <Text fontSize="$5" fontWeight="$8" color={isDark ? '#F8FAFF' : '#0F172A'}>
        {document.title || fallbackTitle}
      </Text>
      <YStack
        padding="$3"
        borderRadius="$4"
        backgroundColor={isDark ? 'rgba(15, 23, 42, 0.65)' : 'rgba(255, 255, 255, 0.85)'}
        borderColor={isDark ? 'rgba(148, 163, 184, 0.18)' : 'rgba(15, 23, 42, 0.12)'}
        borderWidth={1}
      >
        <LegalMarkdown markdown={document.markdown} html={document.html} />
      </YStack>
    </YStack>
  );
}

function useLegalDocument(slug: string | null, locale: LocaleCode): LegalDocumentState {
  const [state, setState] = React.useState<LegalDocumentState>({
    phase: 'idle',
    title: '',
    markdown: '',
    html: '',
  });

  React.useEffect(() => {
    if (!slug) {
      setState({ phase: 'idle', title: '', markdown: '', html: '' });
      return;
    }

    const controller = new AbortController();
    setState((prev) => ({ ...prev, phase: 'loading' }));

    fetch(`/api/v1/legal/${encodeURIComponent(slug)}?lang=${encodeURIComponent(locale)}`, {
      headers: { Accept: 'application/json' },
      signal: controller.signal,
    })
      .then(async (res) => {
        if (!res.ok) {
          throw new Error('Failed to load legal page');
        }
        return res.json();
      })
      .then((data) => {
        setState({
          phase: 'ready',
          title: data?.title ?? '',
          markdown: data?.body_markdown ?? '',
          html: data?.body_html ?? '',
        });
      })
      .catch((error) => {
        if (error?.name === 'AbortError') return;
        console.error('Failed to load legal page', error);
        setState((prev) => ({ ...prev, phase: 'error' }));
      });

    return () => controller.abort();
  }, [slug, locale]);

  return state;
}
