import React from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { ChevronRight, RefreshCcw, ArrowLeft } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Pressable } from '@tamagui/react-native-web-lite';
import { MobileShell, HeaderActionButton } from './components/MobileShell';
import { MobileCard, CTAButton, PillBadge } from './components/Primitives';
import { MobileInput, MobileTextArea } from './components/FormControls';
import {
  TenantEvent,
  EventQrInvite,
  EventQrInviteLayout,
  getEvent,
  getEventQrInvites,
  createQrInvite,
} from '../api';
import { isAuthError } from '../auth/tokens';
import { getApiErrorMessage } from '../lib/apiError';
import toast from 'react-hot-toast';
import { ADMIN_BASE_PATH, adminPath } from '../constants';
import { resolveLayoutForFormat } from './qr/utils';
import { useBackNavigation } from './hooks/useBackNavigation';
import { useAdminTheme } from './theme';
import { ContextHelpLink } from './components/ContextHelpLink';

export default function MobileQrPrintPage() {
  const { slug: slugParam } = useParams<{ slug?: string }>();
  const slug = slugParam ?? null;
  const navigate = useNavigate();
  const { t } = useTranslation('management');
  const { textStrong, text, muted, subtle, border, surfaceMuted, primary, danger, accentSoft } = useAdminTheme();

  const [event, setEvent] = React.useState<TenantEvent | null>(null);
  const [selectedInvite, setSelectedInvite] = React.useState<EventQrInvite | null>(null);
  const [selectedLayoutId, setSelectedLayoutId] = React.useState<string | null>(null);
  const [selectedFormat, setSelectedFormat] = React.useState<'a4-poster' | 'a5-foldable' | null>(null);
  const [error, setError] = React.useState<string | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [qrUrl, setQrUrl] = React.useState<string>('');
  const [qrImage, setQrImage] = React.useState<string>('');
  const back = useBackNavigation(slug ? adminPath(`/mobile/events/${slug}`) : adminPath('/mobile/events'));

  const load = React.useCallback(async () => {
    if (!slug) return;
    setLoading(true);
    try {
      const data = await getEvent(slug);
      const invites = await getEventQrInvites(slug);
      setEvent(data);
      const primaryInvite = invites.find((item) => item.is_active) ?? invites[0] ?? null;
      setSelectedInvite(primaryInvite);
      const initialLayout = primaryInvite?.layouts?.[0];
      const initialFormat =
        initialLayout && ((initialLayout.panel_mode ?? '').toLowerCase() === 'double-mirror' || (initialLayout.orientation ?? '').toLowerCase() === 'landscape')
          ? 'a5-foldable'
          : 'a4-poster';
      setSelectedFormat(initialFormat);
      const resolvedLayoutId = primaryInvite?.layouts
        ? resolveLayoutForFormat(initialFormat, primaryInvite.layouts) ?? initialLayout?.id ?? null
        : initialLayout?.id ?? null;
      setSelectedLayoutId(resolvedLayoutId);
      setQrUrl(primaryInvite?.url ?? data.public_url ?? '');
      setQrImage(primaryInvite?.qr_code_data_url ?? '');
      setError(null);
    } catch (err) {
      if (!isAuthError(err)) {
        setError(getApiErrorMessage(err, t('events.errors.loadFailed', 'QR-Daten konnten nicht geladen werden.')));
      }
    } finally {
      setLoading(false);
    }
  }, [slug, t]);

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

  return (
    <MobileShell
      activeTab="home"
      title={t('events.qr.title', 'QR Code & Print Layouts')}
      onBack={back}
      headerActions={
        <HeaderActionButton onPress={() => load()} ariaLabel={t('common.refresh', 'Refresh')}>
          <RefreshCcw size={18} color={textStrong} />
        </HeaderActionButton>
      }
    >
      {error ? (
        <MobileCard>
          <Text fontWeight="700" color={danger}>
            {error}
          </Text>
          <CTAButton
            label={t('common.retry', 'Retry')}
            tone="ghost"
            fullWidth={false}
            onPress={() => load()}
          />
        </MobileCard>
      ) : null}

      <XStack justifyContent="flex-end">
        <ContextHelpLink slug="guest-access-qr" />
      </XStack>

      <MobileCard space="$3" alignItems="center">
        <Text fontSize="$md" fontWeight="800" color={textStrong}>
          {t('events.qr.heroTitle', 'Entrance QR Code')}
        </Text>
        <YStack
          width={180}
          height={180}
          borderRadius={16}
          borderWidth={1}
          borderColor={border}
          backgroundColor={surfaceMuted}
          alignItems="center"
          justifyContent="center"
          overflow="hidden"
        >
          {qrImage ? (
            <img
              src={qrImage}
              alt={t('events.qr.qrAlt', 'QR code')}
              style={{ width: '100%', height: '100%', objectFit: 'contain' }}
            />
          ) : (
            <Text color={subtle} fontSize="$sm">
              {t('events.qr.missing', 'Kein QR-Link vorhanden')}
            </Text>
          )}
        </YStack>
        {qrUrl ? (
          <Text fontSize="$xs" color={text} textAlign="center" marginTop="$2" style={{ wordBreak: 'break-word' }}>
            {qrUrl}
          </Text>
        ) : null}
        <Text fontSize="$xs" color={muted} marginTop="$1">
          {selectedInvite?.expires_at
            ? t('events.qr.expiresAt', 'Valid until {{date}}', {
                date: formatExpiry(selectedInvite.expires_at),
              })
            : t('events.qr.noExpiry', 'No expiry configured')}
        </Text>
        <Text fontSize="$xs" color={muted}>
          {t('events.qr.description', 'Scan to access the event guest app.')}
        </Text>
        <XStack space="$2" width="100%" marginTop="$2">
          <CTAButton
          label={t('events.qr.download', 'Download')}
          fullWidth={false}
          onPress={() => {
            if (!qrImage) {
              toast.error(t('events.qr.missing', 'Kein QR-Link vorhanden'));
              return;
            }
            const link = document.createElement('a');
            link.href = qrImage;
            link.download = 'event-qr.png';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            toast.success(t('events.qr.downloadStarted', 'Download gestartet'));
          }}
        />
          <CTAButton
            label={t('events.qr.share', 'Share')}
            fullWidth={false}
            onPress={async () => {
              try {
                const shareUrl = String(qrUrl || (event as any)?.public_url || '');
                if (navigator.share && shareUrl) {
                  await navigator.share({
                    title: t('events.qr.title', 'QR Code & Print Layouts'),
                    text: t('events.qr.description', 'Scan to access the event guest app.'),
                    url: shareUrl,
                  });
                  toast.success(t('events.qr.shareSuccess', 'Link geteilt'));
                  return;
                }
                await navigator.clipboard.writeText(shareUrl);
                toast.success(t('events.qr.shareSuccess', 'Link kopiert'));
              } catch {
                toast.error(t('events.qr.shareFailed', 'Konnte Link nicht kopieren'));
              }
            }}
          />
        </XStack>
      </MobileCard>

      <MobileCard space="$2">
        <Text fontSize="$xs" color={muted}>
          {t('events.qr.step1', 'Schritt 1: Format wählen')}
        </Text>
        <Text fontSize="$md" fontWeight="800" color={textStrong}>
          {t('events.qr.layouts', 'Print Layouts')}
        </Text>
        <FormatSelection
          layouts={selectedInvite?.layouts ?? []}
          selectedFormat={selectedFormat}
          onSelect={(format, layoutId) => {
            setSelectedFormat(format);
            setSelectedLayoutId(layoutId);
          }}
        />
        <CTAButton
          label={t('events.qr.preview', 'Anpassen & Exportieren')}
          onPress={() => {
            if (!slug || !selectedInvite) {
              toast.error(t('events.qr.missing', 'Kein QR-Link vorhanden'));
              return;
            }
            const layouts = selectedInvite.layouts ?? [];
            const targetLayout =
              selectedLayoutId ??
              (selectedFormat ? resolveLayoutForFormat(selectedFormat, layouts) : layouts[0]?.id ?? '');
            if (!targetLayout) {
              toast.error(t('events.qr.missing', 'Kein Layout verfügbar'));
              return;
            }
            navigate(`${ADMIN_BASE_PATH}/mobile/events/${slug}/qr/customize/${selectedInvite.id}?layout=${encodeURIComponent(targetLayout)}`);
          }}
        />
      </MobileCard>

      <MobileCard space="$2">
        <Text fontSize="$sm" fontWeight="700" color={textStrong}>
          {t('events.qr.createLink', 'Neuen QR-Link erstellen')}
        </Text>
        <CTAButton
          label={t('events.qr.createLink', 'Neuen QR-Link erstellen')}
          onPress={async () => {
            if (!slug) return;
            try {
              const invite = await createQrInvite(slug, { label: t('events.qr.mobileLinkLabel', 'Mobile link') });
              setQrUrl(invite.url);
              setQrImage(invite.qr_code_data_url ?? '');
              setSelectedInvite(invite);
              setSelectedLayoutId(invite.layouts?.[0]?.id ?? selectedLayoutId);
              toast.success(t('events.qr.created', 'Neuer QR-Link erstellt'));
            } catch (err) {
              toast.error(getApiErrorMessage(err, t('events.qr.createFailed', 'Link konnte nicht erstellt werden.')));
            }
          }}
        />
      </MobileCard>
    </MobileShell>
  );
}

function formatExpiry(value: string): string {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleString(undefined, { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit' });
}

function FormatSelection({
  layouts,
  selectedFormat,
  onSelect,
}: {
  layouts: EventQrInviteLayout[];
  selectedFormat: 'a4-poster' | 'a5-foldable' | null;
  onSelect: (format: 'a4-poster' | 'a5-foldable', layoutId: string | null) => void;
}) {
  const { t } = useTranslation('management');
  const { border, primary, accentSoft, surface, textStrong, muted, subtle } = useAdminTheme();

  const selectLayoutId = (format: 'a4-poster' | 'a5-foldable'): string | null => {
    return resolveLayoutForFormat(format, layouts);
  };

  const cards: { key: 'a4-poster' | 'a5-foldable'; title: string; subtitle: string; badges: string[] }[] = [
    {
      key: 'a4-poster',
      title: t('events.qr.format.poster', 'A4 Poster'),
      subtitle: t('events.qr.format.posterSubtitle', 'Hochformat für Aushänge'),
      badges: ['A4', 'Portrait'],
    },
    {
      key: 'a5-foldable',
      title: t('events.qr.format.table', 'A5 Tischkarte (faltbar)'),
      subtitle: t('events.qr.format.tableSubtitle', 'Quer, doppelt & gespiegelt'),
      badges: ['A4', 'Landscape', 'Double-Mirror'],
    },
  ];

  return (
    <YStack space="$2" marginTop="$2">
      {cards.map((card) => {
        const isSelected = selectedFormat === card.key;
        return (
          <Pressable
            key={card.key}
            onPress={() => onSelect(card.key, selectLayoutId(card.key))}
            style={{ width: '100%' }}
          >
            <MobileCard
              padding="$3"
              borderColor={isSelected ? primary : border}
              borderWidth={isSelected ? 2 : 1}
              backgroundColor={isSelected ? accentSoft : surface}
            >
              <XStack alignItems="center" justifyContent="space-between" space="$3">
                <YStack space="$1" flex={1}>
                  <Text fontSize="$sm" fontWeight="700" color={textStrong}>
                    {card.title}
                  </Text>
                  <Text fontSize="$xs" color={muted}>
                    {card.subtitle}
                  </Text>
                  <XStack space="$2" alignItems="center" flexWrap="wrap">
                    {card.badges.map((badge) => (
                      <PillBadge tone="muted" key={badge}>
                        {badge}
                      </PillBadge>
                    ))}
                  </XStack>
                </YStack>
                <ChevronRight size={16} color={subtle} />
              </XStack>
            </MobileCard>
          </Pressable>
        );
      })}
    </YStack>
  );
}

function BackgroundStep({
  onBack,
  presets,
  selectedPreset,
  onSelectPreset,
  selectedLayout,
  layouts,
  onSave,
  saving,
}: {
  onBack: () => void;
  presets: { id: string; src: string; label: string }[];
  selectedPreset: string | null;
  onSelectPreset: (id: string) => void;
  selectedLayout: EventQrInviteLayout | null;
  layouts: EventQrInviteLayout[];
  onSave: () => void;
  saving: boolean;
}) {
  const { t } = useTranslation('management');
  const { textStrong, muted, border, primary, surfaceMuted } = useAdminTheme();
  const resolvedLayout =
    selectedLayout ??
    layouts.find((layout) => {
      const panel = (layout.panel_mode ?? '').toLowerCase();
      const orientation = (layout.orientation ?? '').toLowerCase();
      return panel === 'double-mirror' || orientation === 'landscape';
    }) ??
    layouts[0] ??
    null;

  const isFoldable = (resolvedLayout?.panel_mode ?? '').toLowerCase() === 'double-mirror';
  const isPortrait = (resolvedLayout?.orientation ?? 'portrait').toLowerCase() === 'portrait';
  const disablePresets = isFoldable;
  const formatLabel = isFoldable ? 'A4 Landscape (Double/Mirror)' : 'A4 Portrait';

  return (
    <YStack space="$3" marginTop="$2">
      <XStack alignItems="center" space="$2">
        <Pressable onPress={onBack}>
          <XStack alignItems="center" space="$1">
            <ArrowLeft size={16} color={textStrong} />
            <Text fontSize="$sm" color={textStrong}>
              {t('common.back', 'Zurück')}
            </Text>
          </XStack>
        </Pressable>
        <PillBadge tone="muted">
          {selectedLayout ? `${(selectedLayout.paper || 'A4').toUpperCase()} • ${(selectedLayout.orientation || 'portrait').toUpperCase()}` : 'Layout'}
        </PillBadge>
      </XStack>

      <YStack space="$2">
        <Text fontSize="$sm" fontWeight="700" color={textStrong}>
          {t(
            'events.qr.backgroundPicker',
            disablePresets ? 'Hintergrund für A5 (Gradient/Farbe)' : `Hintergrund auswählen (${formatLabel})`
          )}
        </Text>
        {!disablePresets ? (
          <>
            <XStack flexWrap="wrap" gap="$2">
              {presets.map((preset) => {
                const isSelected = selectedPreset === preset.id;
                return (
                  <Pressable key={preset.id} onPress={() => onSelectPreset(preset.id)} style={{ width: '48%' }}>
                    <YStack
                      aspectRatio={210 / 297}
                      maxHeight={220}
                      borderRadius={14}
                      overflow="hidden"
                      borderWidth={isSelected ? 2 : 1}
                      borderColor={isSelected ? primary : border}
                      backgroundColor={surfaceMuted}
                    >
                      <YStack
                        flex={1}
                        backgroundImage={`url(${preset.src})`}
                        backgroundSize="cover"
                        backgroundPosition="center"
                      />
                    <XStack padding="$2" justifyContent="space-between" alignItems="center" backgroundColor="rgba(255,255,255,0.92)">
                        <Text fontSize="$xs" color={textStrong}>
                          {preset.label}
                        </Text>
                        {isSelected ? <PillBadge tone="muted">{t('common.selected', 'Ausgewählt')}</PillBadge> : null}
                      </XStack>
                    </YStack>
                  </Pressable>
                );
              })}
            </XStack>
            <Text fontSize="$xs" color={muted}>
              {t('events.qr.backgroundNote', 'Diese Presets sind für A4 Hochformat. Spiegelung erfolgt automatisch bei Tischkarten.')}
            </Text>
          </>
        ) : (
          <Text fontSize="$xs" color={muted}>
            {t('events.qr.foldableBackgroundNote', 'Für A5 Tischkarten bitte Gradient oder Vollfarbe wählen.')}
          </Text>
        )}
      </YStack>

      <CTAButton
        label={saving ? t('common.saving', 'Speichern …') : t('common.save', 'Speichern')}
        disabled={saving || !selectedLayout}
        onPress={onSave}
      />
    </YStack>
  );
}

function TextStep({
  onBack,
  textFields,
  onChange,
  onSave,
  saving,
}: {
  onBack: () => void;
  textFields: { headline: string; subtitle: string; description: string; instructions: string[] };
  onChange: (fields: { headline: string; subtitle: string; description: string; instructions: string[] }) => void;
  onSave: () => void;
  saving: boolean;
}) {
  const { t } = useTranslation('management');
  const { textStrong } = useAdminTheme();

  const updateField = (key: 'headline' | 'subtitle' | 'description', value: string) => {
    onChange({ ...textFields, [key]: value });
  };

  const updateInstruction = (idx: number, value: string) => {
    const next = [...textFields.instructions];
    next[idx] = value;
    onChange({ ...textFields, instructions: next });
  };

  const addInstruction = () => {
    onChange({ ...textFields, instructions: [...textFields.instructions, ''] });
  };

  const removeInstruction = (idx: number) => {
    const next = textFields.instructions.filter((_, i) => i !== idx);
    onChange({ ...textFields, instructions: next.length ? next : [''] });
  };

  return (
    <YStack space="$3" marginTop="$2">
      <XStack alignItems="center" space="$2">
        <Pressable onPress={onBack}>
          <XStack alignItems="center" space="$1">
            <ArrowLeft size={16} color={textStrong} />
            <Text fontSize="$sm" color={textStrong}>
              {t('common.back', 'Zurück')}
            </Text>
          </XStack>
        </Pressable>
        <PillBadge tone="muted">{t('events.qr.textStep', 'Texte & Hinweise')}</PillBadge>
      </XStack>

      <YStack space="$2">
        <Text fontSize="$sm" fontWeight="700" color={textStrong}>
          {t('events.qr.textFields', 'Texte')}
        </Text>
        <MobileInput
          placeholder={t('events.qr.headline', 'Headline')}
          value={textFields.headline}
          onChange={(event) => updateField('headline', event.target.value)}
        />
        <MobileInput
          placeholder={t('events.qr.subtitle', 'Subtitle')}
          value={textFields.subtitle}
          onChange={(event) => updateField('subtitle', event.target.value)}
        />
        <MobileTextArea
          placeholder={t('events.qr.description', 'Beschreibung')}
          value={textFields.description}
          onChange={(event) => updateField('description', event.target.value)}
        />
      </YStack>

      <YStack space="$2">
        <Text fontSize="$sm" fontWeight="700" color={textStrong}>
          {t('events.qr.instructions', 'Anleitung')}
        </Text>
        {textFields.instructions.map((item, idx) => (
          <XStack key={idx} alignItems="center" space="$2">
            <MobileInput
              style={{ flex: 1 }}
              placeholder={t('events.qr.instructionsPlaceholder', 'Schritt hinzufügen')}
              value={item}
              onChange={(event) => updateInstruction(idx, event.target.value)}
            />
            <CTAButton
              label="–"
              onPress={() => removeInstruction(idx)}
              disabled={textFields.instructions.length === 1}
            />
          </XStack>
        ))}
        <CTAButton label={t('common.add', 'Hinzufügen')} onPress={addInstruction} />
      </YStack>

      <CTAButton
        label={saving ? t('common.saving', 'Speichern …') : t('common.save', 'Speichern')}
        disabled={saving}
        onPress={onSave}
      />
    </YStack>
  );
}

function PreviewStep({
  onBack,
  layout,
  backgroundPreset,
  presets,
  textFields,
  qrUrl,
  qrImage,
  onExport,
}: {
  onBack: () => void;
  layout: EventQrInviteLayout | null;
  backgroundPreset: string | null;
  presets: { id: string; src: string; label: string }[];
  textFields: { headline: string; subtitle: string; description: string; instructions: string[] };
  qrUrl: string;
  qrImage: string;
  onExport: (format: 'pdf' | 'png') => void;
}) {
  const { t } = useTranslation('management');
  const { textStrong, text, muted, border, surfaceMuted } = useAdminTheme();
  const presetSrc = backgroundPreset ? presets.find((p) => p.id === backgroundPreset)?.src ?? null : null;
  const resolvedBg = presetSrc ?? layout?.preview?.background ?? surfaceMuted;
  const previewText = layout?.preview?.text ?? textStrong;
  const previewBody = layout?.preview?.text ?? text;

  return (
    <YStack space="$3" marginTop="$2">
      <XStack alignItems="center" space="$2">
        <Pressable onPress={onBack}>
          <XStack alignItems="center" space="$1">
            <ArrowLeft size={16} color={textStrong} />
            <Text fontSize="$sm" color={textStrong}>
              {t('common.back', 'Zurück')}
            </Text>
          </XStack>
        </Pressable>
        {layout ? (
          <PillBadge tone="muted">
            {(layout.paper || 'A4').toUpperCase()} • {(layout.orientation || 'portrait').toUpperCase()}
          </PillBadge>
        ) : null}
      </XStack>

      <YStack space="$2">
        <Text fontSize="$sm" fontWeight="700" color={textStrong}>
          {t('events.qr.preview', 'Vorschau')}
        </Text>
        <YStack
          borderRadius={16}
          borderWidth={1}
          borderColor={border}
          overflow="hidden"
          backgroundColor={presetSrc ? 'transparent' : surfaceMuted}
          style={
            presetSrc
              ? {
                  backgroundImage: `url(${presetSrc})`,
                  backgroundSize: 'cover',
                  backgroundPosition: 'center',
                }
              : { background: resolvedBg ?? surfaceMuted }
          }
          padding="$3"
          gap="$3"
        >
          <Text fontSize="$lg" fontWeight="800" color={previewText}>
            {textFields.headline || layout?.name || t('events.qr.previewHeadline', 'Event QR')}
          </Text>
          {textFields.subtitle ? (
            <Text fontSize="$sm" color={previewBody}>
              {textFields.subtitle}
            </Text>
          ) : null}
            {textFields.description ? (
              <Text fontSize="$sm" color={previewBody}>
                {textFields.description}
              </Text>
            ) : null}
          <YStack space="$1">
            {textFields.instructions.filter((i) => i.trim().length > 0).map((item, idx) => (
              <Text key={idx} fontSize="$xs" color={previewBody}>
                • {item}
              </Text>
            ))}
          </YStack>
          <YStack alignItems="center" justifyContent="center">
            {qrImage ? (
              <>
                <img
                  src={qrImage}
                  alt={t('events.qr.qrAlt', 'QR code')}
                  style={{ width: 140, height: 140, objectFit: 'contain' }}
                />
                <Text fontSize="$xs" color={text} textAlign="center" marginTop="$2" style={{ wordBreak: 'break-word' }}>
                  {qrUrl}
                </Text>
              </>
            ) : (
              <Text fontSize="$xs" color={muted}>
                {t('events.qr.missing', 'Kein QR-Link vorhanden')}
              </Text>
            )}
          </YStack>
        </YStack>
      </YStack>

      <XStack space="$2">
        <CTAButton label={t('events.qr.exportPdf', 'Export PDF')} onPress={() => onExport('pdf')} />
        <CTAButton label={t('events.qr.exportPng', 'Export PNG')} onPress={() => onExport('png')} />
      </XStack>
    </YStack>
  );
}
