import { useEffect, useState, useMemo, startTransition } from 'react';
import { Box, Button, FormControl, FormLabel, Input, VStack, Heading, useToast, SimpleGrid, Divider, Text, useColorModeValue, InputGroup, InputRightElement, List, ListItem, Spinner, HStack, Image, Checkbox, Tooltip, Alert, AlertIcon, Select, FormHelperText, Badge, Link } from '@chakra-ui/react';
import { InfoOutlineIcon } from '@chakra-ui/icons';
import './styles/MagazineHome.css';
import './styles/ProHome.css';
import { useNavigate } from 'react-router-dom';
import { getSetupStatus, initializeSetup, SetupInitializePayload, validateSMTP } from '../services/setup';
import { updateSeoSettings } from '../services/seo';
import { API_URL } from '../services/api';
import { assetUrl } from '../utils/url';
import { useFacrApi } from '../hooks/useFacrApi';
import { SearchResult } from '../services/facr/types';
import { extractPalette, pickTextColor, generateJwtSecret, contrastRatio, isContrastAccessible, generateThemeCandidates, ThemeCandidate, adjustForContrast } from '../utils/colors';
import { clearToken, setHasAdmin } from '../utils/auth';
import ContactMap from '../components/home/ContactMap';
import { FONT_PAIRINGS, applyFontPairing, getFontStyleColor } from '../config/fonts';
import MapLinkImporter from '../components/admin/MapLinkImporter';
import MapStyleSelector from '../components/admin/MapStyleSelector';
import { MapCoordinates } from '../utils/mapUrlParser';
import { fetchLogoFromLogoAPI } from '../utils/sportLogosAPI';

const SetupPage: React.FC = () => {
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [requiresSetup, setRequiresSetup] = useState(false);

  // form state
  const [adminEmail, setAdminEmail] = useState('');
  const [adminPassword, setAdminPassword] = useState('');
  const [showAdminPassword, setShowAdminPassword] = useState(false);
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [jwtSecret, setJwtSecret] = useState('');
  const [clubId, setClubId] = useState('');
  const [clubType, setClubType] = useState('football');
  const [clubName, setClubName] = useState('');
  const [clubLogoUrl, setClubLogoUrl] = useState('');
  const [uploadingLogo, setUploadingLogo] = useState(false);
  const [clubUrl, setClubUrl] = useState('');
  const [clubQuery, setClubQuery] = useState('');
  const { searchClubs, searchResults, searchLoading } = useFacrApi();

  const resolveLogoUrl = (u?: string | null) => {
    if (!u) return undefined;
    // If it's a logoapi URL, use it directly (no proxy needed)
    if (u.includes('logoapi.sportcreative.eu')) return u;
    // If it's a backend-relative path or dist asset, use assetUrl helper
    if (u.startsWith('/uploads') || u.startsWith('/dist') || u.startsWith('/api/')) return assetUrl(u);
    // If it's an absolute remote URL, route through backend proxy to avoid CORS/hotlinking issues
    if (/^https?:\/\//i.test(u)) {
      const base = (API_URL || '').replace(/\/$/, '');
      return `${base}/proxy/image?url=${encodeURIComponent(u)}`;
    }
    return u;
  };

  // Theme colors
  // Default theme colors before any logo/preset is selected
  const [primaryColor, setPrimaryColor] = useState('#2d74da');
  const [secondaryColor, setSecondaryColor] = useState('#f6f8fb');
  const [accentColor, setAccentColor] = useState('#ffb703');
  const [backgroundColor, setBackgroundColor] = useState('#ffffff');
  const [textColor, setTextColor] = useState('#111827');
  // Site style
  const [frontpageStyle, setFrontpageStyle] = useState<'unified' | 'magazine'>('unified');
  // Theme presets generated from logo
  const [themePresets, setThemePresets] = useState<ThemeCandidate[]>([]);
  const [selectedPreset, setSelectedPreset] = useState<number | null>(null);

  // Typography/Font
  const [selectedFont, setSelectedFont] = useState<string>('inter-inter');

  // GPS Location
  const [mapUrl, setMapUrl] = useState('');
  const [gpsLat, setGpsLat] = useState<number | ''>('');
  const [gpsLng, setGpsLng] = useState<number | ''>('');
  const [mapStyle, setMapStyle] = useState<string>('positron');

  // Contact Details
  const [contactStreet, setContactStreet] = useState('');
  const [contactCity, setContactCity] = useState('');
  const [contactPostalCode, setContactPostalCode] = useState('');
  const [contactCountry, setContactCountry] = useState('Česká republika');
  const [contactPhone, setContactPhone] = useState('');
  const [contactEmail, setContactEmail] = useState('');

  // SMTP
  const [smtpHost, setSmtpHost] = useState('');
  const [smtpPort, setSmtpPort] = useState<number | ''>('');
  const [smtpUser, setSmtpUser] = useState('');
  const [smtpPass, setSmtpPass] = useState('');
  const [showSmtpPass, setShowSmtpPass] = useState(false);
  // Sender display name only; actual email is derived from smtpUser
  const [smtpFromName, setSmtpFromName] = useState('');
  const [smtpTLS, setSmtpTLS] = useState(true);
  const [testingSMTP, setTestingSMTP] = useState(false);

  // Social & gallery
  const [facebookUrl, setFacebookUrl] = useState('');
  const [instagramUrl, setInstagramUrl] = useState('');
  const [youtubeUrl, setYoutubeUrl] = useState('');
  const [galleryUrl, setGalleryUrl] = useState('');
  const [galleryLabel, setGalleryLabel] = useState('Fotogalerie');

  const toast = useToast();
  const navigate = useNavigate();
  const bg = useColorModeValue('white', 'gray.800');
  const borderCol = useColorModeValue('gray.200', 'gray.600');

  // Password helpers
  const sanitizePassword = (val: string) => {
    // remove all whitespace characters (spaces, tabs, newlines, non-breaking spaces)
    return (val || '').replace(/\s+/g, '');
  };
  const isPasswordValid = (val: string) => {
    // 8-128 chars, no whitespace
    return /^\S{8,128}$/.test(val);
  };
  const generateStrongPassword = () => {
    const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*()-_=+[]{};:,.?';
    let out = '';
    const len = 16;
    for (let i = 0; i < len; i++) {
      out += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return out;
  };


  useEffect(() => {
    let mounted = true;
    // Ensure no stale auth/admin flags can interfere with setup
    try {
      clearToken();
      setHasAdmin(false);
    } catch {}
    (async () => {
      try {
        const s = await getSetupStatus();
        if (!mounted) return;
        setRequiresSetup(!!s.requires_setup);
      } catch (e) {
        setRequiresSetup(false);
      } finally {
        if (mounted) setLoading(false);
      }
    })();
    return () => { mounted = false; };
  }, []);

  // Auto-generate JWT secret when setup is required
  useEffect(() => {
    if (requiresSetup && !jwtSecret) {
      setJwtSecret(generateJwtSecret());
    }
  }, [requiresSetup, jwtSecret]);

  // Debounced search for clubs
  useEffect(() => {
    const q = clubQuery.trim();
    if (!q) return;
    const t = setTimeout(() => {
      searchClubs(q).catch(() => {});
    }, 300);
    return () => clearTimeout(t);
  }, [clubQuery, searchClubs]);

  // Load and apply selected font for preview
  useEffect(() => {
    const pairing = FONT_PAIRINGS.find((f) => f.id === selectedFont);
    if (pairing) {
      applyFontPairing(pairing);
    }
  }, [selectedFont]);

  // Auto-fill SMTP username from contact email
  useEffect(() => {
    if (contactEmail && !smtpUser) {
      setSmtpUser(contactEmail);
    }
  }, [contactEmail, smtpUser]);

  const handleSelectClub = async (item: SearchResult) => {
    const clubIdValue = item.club_id || '';
    setClubId(clubIdValue);
    setClubType(item.club_type || 'football');
    setClubName(item.name || '');
    setClubUrl(item.url || '');
    setClubQuery(item.name || '');
    
    // Try to fetch logo from logoapi first, fallback to FACR logo
    let logoUrl = '';
    if (clubIdValue) {
      const logoApiUrl = await fetchLogoFromLogoAPI(clubIdValue, item.name);
      if (logoApiUrl) {
        logoUrl = logoApiUrl;
      }
    }
    // Fallback to FACR logo if logoapi doesn't have it
    if (!logoUrl && item.logo_url) {
      logoUrl = item.logo_url;
    }
    setClubLogoUrl(logoUrl);
    
    // Auto-fill sender display name from club name if empty
    if (!smtpFromName && item.name) {
      setSmtpFromName(item.name);
    }
    // Update the document title immediately for instant feedback
    try {
      if (typeof document !== 'undefined' && item.name) {
        document.title = item.name;
      }
    } catch {}
    // Try to extract colors
    if (logoUrl) {
      extractPalette(logoUrl, 5)
        .then((colors) => {
          if (!colors || colors.length === 0) return;
          const presets = generateThemeCandidates(colors);
          setThemePresets(presets);
          // Apply first preset by default
          const p0 = presets[0];
          if (p0) {
            setPrimaryColor(p0.primary);
            setSecondaryColor(p0.secondary);
            setAccentColor(p0.accent);
            setBackgroundColor(p0.background);
            setTextColor(p0.text);
            setSelectedPreset(0);
          }
        })
        .catch(() => {});
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setSubmitting(true);
    try {
      // Validate and sanitize password
      const cleanPassword = sanitizePassword(adminPassword);
      if (!isPasswordValid(cleanPassword)) {
        toast({ title: 'Neplatné heslo', description: 'Heslo musí mít 8–128 znaků a nesmí obsahovat mezery.', status: 'error' });
        setSubmitting(false);
        return;
      }
      // Compose SMTP From as "Name <username>" if both provided
      const composedFrom = smtpFromName && smtpUser
        ? `${smtpFromName} <${smtpUser}>`
        : (smtpUser || undefined);

      const payload: SetupInitializePayload = {
        admin_email: adminEmail,
        admin_password: cleanPassword,
        first_name: firstName || undefined,
        last_name: lastName || undefined,
        jwt_secret: jwtSecret || undefined,
        club_id: clubId || undefined,
        club_type: clubType || undefined,
        club_name: clubName || undefined,
        club_logo_url: clubLogoUrl || undefined,
        club_url: clubUrl || undefined,
        frontpage_style: frontpageStyle || undefined,
        primary_color: primaryColor || undefined,
        secondary_color: secondaryColor || undefined,
        accent_color: accentColor || undefined,
        background_color: backgroundColor || undefined,
        text_color: textColor || undefined,
        // typography (optional)
        font_heading: FONT_PAIRINGS.find(f => f.id === selectedFont)?.heading || undefined,
        font_body: FONT_PAIRINGS.find(f => f.id === selectedFont)?.body || undefined,
        // social & gallery (optional)
        facebook_url: facebookUrl || undefined,
        instagram_url: instagramUrl || undefined,
        youtube_url: youtubeUrl || undefined,
        gallery_url: galleryUrl || undefined,
        gallery_label: galleryLabel || undefined,
        // GPS location (optional)
        location_latitude: typeof gpsLat === 'number' ? gpsLat : undefined,
        location_longitude: typeof gpsLng === 'number' ? gpsLng : undefined,
        map_style: mapStyle || undefined,
        // Contact details (optional)
        contact_address: contactStreet || undefined,
        contact_city: contactCity || undefined,
        contact_zip: contactPostalCode || undefined,
        contact_country: contactCountry || undefined,
        contact_phone: contactPhone || undefined,
        contact_email: contactEmail || undefined,
        smtp: (smtpHost || smtpPort || smtpUser || smtpPass || smtpFromName) ? {
          host: smtpHost || undefined,
          port: typeof smtpPort === 'number' ? smtpPort : undefined,
          username: smtpUser || undefined,
          password: smtpPass || undefined,
          from: composedFrom,
          use_tls: smtpTLS,
        } : null,
      };
      await initializeSetup(payload);
      // Set sensible default SEO based on setup data
      try {
        const origin = (typeof window !== 'undefined' ? window.location.origin : '').replace(/\/$/, '');
        await updateSeoSettings({
          site_title: clubName || 'Fotbal Club',
          site_description: clubName ? `${clubName} – oficiální klubový web: aktuality, zápasy, tabulky, hráči.` : 'Oficiální klubový web: aktuality, zápasy, tabulky, hráči.',
          default_og_image_url: clubLogoUrl || undefined,
          canonical_base_url: origin || undefined,
          enable_indexing: true,
        });
      } catch {}
      toast({ title: 'Nastavení dokončeno', status: 'success', duration: 3000, isClosable: true });
      navigate('/login', { replace: true });
      // Force full reload to ensure app picks up fresh server state and env
      setTimeout(() => {
        try { window.location.reload(); } catch {}
      }, 800);
    } catch (error: any) {
      toast({ title: 'Nastavení selhalo', description: error?.response?.data?.error || 'Zkontrolujte prosím své údaje', status: 'error' });
    } finally {
      setSubmitting(false);
    }
  };

  const onLogoFile = async (f?: File | null) => {
    if (!f) return;
    setUploadingLogo(true);
    try {
      // Use a dedicated form so we can pass preserve_quality to backend
      const fd = new FormData();
      fd.append('file', f);
      fd.append('preserve_quality', 'true');
      // Upload should go to the API root (usually /api/v1/upload). Use configured API_URL
      const uploadUrl = `${(API_URL || '').replace(/\/$/, '')}/upload`;
      const res = await fetch(uploadUrl, { method: 'POST', body: fd });
      if (!res.ok) throw new Error('Upload failed');
      const data = await res.json();
      let url = data?.url || '';
      try {
        const parsed = new URL(url, window.location.origin);
        url = parsed.pathname + parsed.search + parsed.hash;
      } catch {}
      setClubLogoUrl(url);
      
      // Also upload to logoapi if we have a club ID
      if (clubId) {
        try {
          const logoFd = new FormData();
          logoFd.append('logo', f);
          const logoApiRes = await fetch(`https://logoapi.sportcreative.eu/logos/${clubId}`, {
            method: 'POST',
            body: logoFd,
          });
          if (logoApiRes.ok) {
            toast({ title: 'Logo nahráno', description: 'Logo bylo nahráno na logoapi i lokálně', status: 'success', duration: 3000 });
          }
        } catch (logoApiErr) {
          console.warn('Failed to upload to logoapi:', logoApiErr);
          // Don't fail the whole upload if logoapi fails
        }
      }
      
      // Try to extract colors from uploaded logo
      try { const colors = await extractPalette(url, 5); const presets = generateThemeCandidates(colors); setThemePresets(presets); if (presets[0]) { setPrimaryColor(presets[0].primary); setSecondaryColor(presets[0].secondary); setAccentColor(presets[0].accent); setBackgroundColor(presets[0].background); setTextColor(presets[0].text); setSelectedPreset(0); } } catch {}
    } catch (e) {
      toast({ title: 'Nahrání loga selhalo', status: 'error' });
    } finally {
      setUploadingLogo(false);
    }
  };

  // Derived: contrast checks (memoized for perf)
  const bgTextContrast = useMemo(() => {
    if (!backgroundColor || !textColor) return null;
    return contrastRatio(backgroundColor, textColor);
  }, [backgroundColor, textColor]);

  const primaryTextContrast = useMemo(() => {
    if (!primaryColor || !textColor) return null;
    return contrastRatio(primaryColor, textColor);
  }, [primaryColor, textColor]);

  const isBgTextAccessible = useMemo(() => {
    if (bgTextContrast == null) return true;
    return isContrastAccessible(backgroundColor, textColor, 'AA');
  }, [bgTextContrast, backgroundColor, textColor]);

  const autofixTextForBg = () => {
    if (!backgroundColor) return;
    const fixed = pickTextColor(backgroundColor);
    setTextColor(fixed);
  };

  // Re-generate presets manually when user clicks button (from current logo URL)
  const regenerateFromLogo = async () => {
    const url = clubLogoUrl?.trim();
    if (!url) return;
    try {
      const colors = await extractPalette(url, 5);
      const presets = generateThemeCandidates(colors);
      setThemePresets(presets);
      if (presets[0]) {
        setPrimaryColor(presets[0].primary);
        setSecondaryColor(presets[0].secondary);
        setAccentColor(presets[0].accent);
        setBackgroundColor(presets[0].background);
        setTextColor(presets[0].text);
        setSelectedPreset(0);
      }
    } catch {}
  };

  const applyPreset = (idx: number) => {
  const p = themePresets[idx];
  if (!p) return;
  setPrimaryColor(p.primary);
  setSecondaryColor(p.secondary);
  setAccentColor(p.accent);
  setBackgroundColor(p.background);
  setTextColor(p.text);
  setSelectedPreset(idx);
  };

  // Redirect if setup not required
  useEffect(() => {
    if (!loading && !requiresSetup) {
      navigate('/login', { replace: true });
    }
  }, [loading, requiresSetup, navigate]);

  if (loading) return <Box p={8}>Načítání…</Box>;
  if (!requiresSetup) {
    return null;
  }

  // Get selected font pairing for live preview
  const selectedFontPairing = FONT_PAIRINGS.find((f) => f.id === selectedFont);
  const fontHeading = selectedFontPairing?.cssHeading || 'inherit';
  const fontBody = selectedFontPairing?.cssBody || 'inherit';

  return (
    <Box minH="100vh" bg="gray.50" display="flex" alignItems="center" justifyContent="center" px={8} py={8} fontFamily={fontBody}>
      <Box as="form" onSubmit={handleSubmit} w="100%" maxW="3xl" p={8} bg={bg} borderRadius="xl" boxShadow="lg" borderWidth="1px" borderColor={borderCol} fontFamily={fontBody}>
        <VStack spacing={3} mb={6} align="stretch">
          <Heading size="xl" fontFamily={fontHeading}>🚀 Vítejte v nastavení vašeho webu!</Heading>
          <Text fontSize="md" color="gray.600">
            Nastavte základní informace o vašem klubu. Můžete vše vyplnit nyní, nebo některé údaje doplnit později v administraci.
          </Text>
          <Alert status="info" borderRadius="md">
            <AlertIcon />
            <Box>
              <Text fontSize="sm" fontWeight="medium">💡 Tip: Vyhledejte váš klub v databázi FAČR</Text>
              <Text fontSize="sm">Logo, barvy a základní údaje se doplní automaticky.</Text>
            </Box>
          </Alert>
        </VStack>

        <SimpleGrid columns={[1, 1, 2]} spacing={6}>
          <Box>
            <Heading as="h3" size="md" mb={4} fontFamily={fontHeading}>🔐 Administrátorský účet</Heading>
            <VStack align="stretch" spacing={4}>
              <FormControl isRequired>
                <FormLabel>E‑mail administrátora</FormLabel>
                <Input type="email" value={adminEmail} onChange={(e) => setAdminEmail(e.target.value)} placeholder="admin@example.com" />
              </FormControl>
              <FormControl isRequired>
                <FormLabel>Heslo administrátora</FormLabel>
                <InputGroup>
                  <Input
                    type={showAdminPassword ? 'text' : 'password'}
                    value={adminPassword}
                    onChange={(e) => setAdminPassword(sanitizePassword(e.target.value))}
                    placeholder="Minimálně 8 znaků, bez mezer"
                    minLength={8}
                  />
                  <InputRightElement width="4.5rem">
                    <Button h="1.75rem" size="sm" onClick={() => setShowAdminPassword((s) => !s)}>{showAdminPassword ? 'Skrýt' : 'Zobrazit'}</Button>
                  </InputRightElement>
                </InputGroup>
                <FormHelperText>Bez mezer. 8–128 znaků. Použijte písmena, číslice a speciální znaky.</FormHelperText>
                <HStack mt={2} spacing={2}>
                  <Button size="sm" variant="outline" onClick={() => setAdminPassword(generateStrongPassword())}>Vygenerovat silné heslo</Button>
                  <Button size="sm" variant="ghost" onClick={() => setAdminPassword('')}>Vymazat</Button>
                </HStack>
              </FormControl>
              <FormControl>
                <FormLabel>Jméno</FormLabel>
                <Input value={firstName} onChange={(e) => setFirstName(e.target.value)} />
              </FormControl>
              <FormControl>
                <FormLabel>Příjmení</FormLabel>
                <Input value={lastName} onChange={(e) => setLastName(e.target.value)} />
              </FormControl>
            </VStack>
          </Box>

          <Box>
            <Heading as="h3" size="md" mb={4} fontFamily={fontHeading}>⚽ Informace o klubu</Heading>
            <VStack align="stretch" spacing={4}>
              <FormControl>
                <FormLabel>Hledat klub (FAČR)</FormLabel>
                <InputGroup>
                  <Input value={clubQuery} onChange={(e) => setClubQuery(e.target.value)} placeholder="Hledejte podle názvu klubu" />
                  <InputRightElement>
                    {searchLoading ? <Spinner size="sm" /> : null}
                  </InputRightElement>
                </InputGroup>
                {clubQuery && searchResults?.length > 0 && (
                  <Box mt={2} borderWidth="1px" borderRadius="md" maxH="240px" overflowY="auto">
                    <List spacing={0}>
                      {searchResults.filter((r) => r.name && r.name.trim() !== '').slice(0, 8).map((r) => (
                        <ListItem 
                          key={`${r.club_type}-${r.club_id}`} 
                          px={3} py={2} _hover={{ bg: 'gray.50', cursor: 'pointer' }}
                          onClick={() => handleSelectClub(r)}
                        >
                          <HStack spacing={3}>
                            {r.logo_url ? <Image src={resolveLogoUrl(r.logo_url)} alt={r.name} boxSize="24px" objectFit="contain" /> : null}
                            <Box>
                              <Text fontWeight="medium">{r.name}</Text>
                              <Text fontSize="sm" color="gray.500">{r.club_type}</Text>
                            </Box>
                          </HStack>
                        </ListItem>
                      ))}
                    </List>
                  </Box>
                )}
              </FormControl>
              <FormControl>
                <FormLabel>Typ klubu</FormLabel>
                <Input value={clubType} onChange={(e) => setClubType(e.target.value)} placeholder="football nebo futsal" />
              </FormControl>
              <FormControl>
                <FormLabel>ID klubu</FormLabel>
                <Input value={clubId} onChange={(e) => setClubId(e.target.value)} placeholder="FAČR ID klubu" />
              </FormControl>
              <FormControl>
                <FormLabel>Název klubu</FormLabel>
                <Input value={clubName} onChange={(e) => setClubName(e.target.value)} />
              </FormControl>
              <FormControl>
                <FormLabel>URL loga klubu</FormLabel>
                <Input value={clubLogoUrl} onChange={(e) => setClubLogoUrl(e.target.value)} />
                <HStack mt={2} spacing={3}>
                  <Button as="label" size="sm" leftIcon={<InfoOutlineIcon />}>
                    Nahrát logo
                    <Input
                      type="file"
                      display="none"
                      accept="image/*,image/svg+xml,application/pdf"
                      onChange={(e) => {
                        const f = e.target.files?.[0] || null;
                        // Process selected file
                        onLogoFile(f);
                        // Important: reset input value so selecting the same file again fires onChange
                        // This fixes the bug where uploading the same logo twice did nothing
                        try { (e.target as HTMLInputElement).value = ''; } catch {}
                      }}
                    />
                  </Button>
                  {uploadingLogo ? <Text fontSize="sm">Nahrávám…</Text> : null}
                </HStack>
              </FormControl>
              <FormControl>
                <FormLabel>URL klubu</FormLabel>
                <Input value={clubUrl} onChange={(e) => setClubUrl(e.target.value)} />
              </FormControl>
              <Box>
                <Text mb={2}>Náhled loga</Text>
                <Image src={resolveLogoUrl(clubLogoUrl) || (assetUrl('/dist/img/logo-club-empty.svg') as string)} alt="Logo preview" maxH="80px" objectFit="contain" />
              </Box>
            </VStack>
          </Box>
        </SimpleGrid>

  {/* removed overall style preview per request */}

        <Divider my={6} />

        <Heading as="h3" size="md" mb={2} fontFamily={fontHeading}>🎨 Barvy a vzhled webu</Heading>
        <Text fontSize="sm" mb={3} color="gray.600">Automaticky z loga (lze upravit). Vyberte jednu z předloh nebo barvy ručně dolaďte.</Text>

        {/* Preset selector */}
        {themePresets.length > 0 && (
          <Box mb={4}>
            <Text fontWeight="semibold" mb={2}>Předlohy z loga</Text>
            <SimpleGrid columns={{ base: 1, md: 5 }} spacing={3}>
              {themePresets.map((p, i) => (
                <Box key={p.name + i} borderWidth={selectedPreset === i ? '2px' : '1px'} borderColor={selectedPreset === i ? 'blue.400' : 'gray.200'} borderRadius="md" p={3} cursor="pointer" onClick={() => applyPreset(i)}>
                  <Box mb={2} display="flex" gap="6px" alignItems="center">
                    <Box flex="1" h="48px" borderRadius="6px" bg={p.primary} display="flex" alignItems="center" justifyContent="center" color={p.text}>{/* primary */}</Box>
                    <Box w="48px" h="48px" borderRadius="6px" bg={p.secondary} />
                    <Box w="48px" h="48px" borderRadius="6px" bg={p.accent} />
                  </Box>
                  <Text fontSize="sm" fontWeight="semibold">{p.name}</Text>
                  <Text fontSize="xs" color="gray.500">Primární / Sekundární / Akcent</Text>
                </Box>
              ))}
            </SimpleGrid>
            <Button mt={3} variant="ghost" onClick={regenerateFromLogo}>Znovu z loga</Button>
          </Box>
        )}
        <SimpleGrid columns={[1, 1, 2]} spacing={6}>
          <FormControl>
            <FormLabel>Primární
              <Tooltip label="Hlavní barva značky (tlačítka, odkazy, zvýraznění)." hasArrow><InfoOutlineIcon ml={2} /></Tooltip>
            </FormLabel>
            <Input type="color" value={primaryColor} onChange={(e) => startTransition(() => setPrimaryColor(e.target.value))} />
            <Text fontSize="xs" color="gray.500" mt={1}>Používá se na hlavních prvcích.</Text>
          </FormControl>
          <FormControl>
            <FormLabel>Sekundární
              <Tooltip label="Doplňková barva pro méně důležité prvky a plochy." hasArrow><InfoOutlineIcon ml={2} /></Tooltip>
            </FormLabel>
            <Input type="color" value={secondaryColor} onChange={(e) => startTransition(() => setSecondaryColor(e.target.value))} />
            <Text fontSize="xs" color="gray.500" mt={1}>Podpůrné zvýraznění.</Text>
          </FormControl>
          <FormControl>
            <FormLabel>Akcent
              <Tooltip label="Kontrastní barva pro odznaky, štítky a malé akce." hasArrow><InfoOutlineIcon ml={2} /></Tooltip>
            </FormLabel>
            <Input type="color" value={accentColor} onChange={(e) => startTransition(() => setAccentColor(e.target.value))} />
            <Text fontSize="xs" color="gray.500" mt={1}>Menší prvky a upozornění.</Text>
          </FormControl>
          <FormControl>
            <FormLabel>Pozadí</FormLabel>
            <Input type="color" value={backgroundColor} onChange={(e) => startTransition(() => setBackgroundColor(e.target.value))} />
            <Text fontSize="xs" color="gray.500" mt={1}>Barva ploch stránky.</Text>
          </FormControl>
          <FormControl>
            <FormLabel>Text</FormLabel>
            <Input type="color" value={textColor} onChange={(e) => startTransition(() => setTextColor(e.target.value))} />
            <Text fontSize="xs" color="gray.500" mt={1}>Základní barva textu.</Text>
          </FormControl>
        </SimpleGrid>

        {/* Contrast warnings */}
        {!isBgTextAccessible && (
          <Alert status="warning" mt={4} borderRadius="md">
            <AlertIcon />
            Slabý kontrast textu vůči pozadí (poměr {bgTextContrast?.toFixed(2)}). Pro čitelnost upravte barvy nebo
            <Button variant="link" colorScheme="blue" ml={2} onClick={autofixTextForBg}>automaticky opravit barvu textu</Button>.
          </Alert>
        )}
        {primaryTextContrast !== null && primaryTextContrast < 4.5 && (
          <Alert status="warning" mt={3} borderRadius="md">
            <AlertIcon />
            Text na primární barvě má nízký kontrast (poměr {primaryTextContrast.toFixed(2)}). Zvažte jinou barvu textu nebo primární barvy.
          </Alert>
        )}

        <Divider my={6} />

        <Heading as="h3" size="md" mb={2} fontFamily={fontHeading}>📱 Sociální sítě a fotogalerie</Heading>
        <Text fontSize="sm" mb={3} color="gray.600">Zadejte odkazy na profily klubu a volitelně na fotogalerii. Lze později upravit v administraci.</Text>
        <SimpleGrid columns={[1, 1, 2]} spacing={6} mb={2}>
          <FormControl>
            <FormLabel>Facebook URL</FormLabel>
            <Input placeholder="https://www.facebook.com/vas.klub" value={facebookUrl} onChange={(e) => setFacebookUrl(e.target.value)} />
          </FormControl>
          <FormControl>
            <FormLabel>Instagram URL</FormLabel>
            <Input placeholder="https://www.instagram.com/vas.klub" value={instagramUrl} onChange={(e) => setInstagramUrl(e.target.value)} />
          </FormControl>
          <FormControl>
            <FormLabel>YouTube URL</FormLabel>
            <Input placeholder="https://www.youtube.com/@vas_klub" value={youtubeUrl} onChange={(e) => setYoutubeUrl(e.target.value)} />
          </FormControl>
          <FormControl>
            <FormLabel>URL fotogalerie</FormLabel>
            <Input placeholder="https://photos.example.com/club" value={galleryUrl} onChange={(e) => setGalleryUrl(e.target.value)} />
            <FormHelperText>Můžete použít libovolný web (SmugMug, Flickr, Google Photos, Zonerama...).</FormHelperText>
          </FormControl>
          <FormControl>
            <FormLabel>Popisek odkazu fotogalerie</FormLabel>
            <Input placeholder="Fotogalerie" value={galleryLabel} onChange={(e) => setGalleryLabel(e.target.value)} />
          </FormControl>
        </SimpleGrid>

        <Divider my={6} />

        <Heading as="h3" size="md" mb={2} fontFamily={fontHeading}>✍️ Písmo a typografie</Heading>
        <Text fontSize="sm" mb={3} color="gray.600">Vyberte vzhled písma pro váš web. Náhled se aplikuje okamžitě na celou stránku.</Text>
        <Box mb={4}>
          <SimpleGrid columns={{ base: 1, md: 3 }} spacing={3}>
            {FONT_PAIRINGS.map((font) => (
              <Box 
                key={font.id} 
                borderWidth={selectedFont === font.id ? '2px' : '1px'} 
                borderColor={selectedFont === font.id ? 'blue.400' : 'gray.200'} 
                borderRadius="md" 
                p={3} 
                cursor="pointer" 
                onClick={() => setSelectedFont(font.id)}
              >
                <VStack align="stretch" spacing={2}>
                  <HStack justify="space-between">
                    <Text fontSize="sm" fontWeight="medium">{font.name}</Text>
                    <Badge colorScheme={getFontStyleColor(font.style)}>{font.style}</Badge>
                  </HStack>
                  <Text fontFamily={font.cssHeading} fontSize="lg" fontWeight="bold">Nadpis</Text>
                  <Text fontFamily={font.cssBody} fontSize="sm">Text běžného odstavce</Text>
                </VStack>
              </Box>
            ))}
          </SimpleGrid>
          <Text fontSize="xs" color="gray.500" mt={2}>Zobrazeno {FONT_PAIRINGS.length} dostupných stylů písma.</Text>
        </Box>

        <Divider my={6} />

        <Heading as="h3" size="md" mb={2} fontFamily={fontHeading}>📍 GPS poloha a mapa</Heading>
        <Text fontSize="sm" mb={4} color="gray.600">Nastavte polohu vašeho stadionu. Můžete vložit odkaz z mapy, nebo zadat souřadnice ručně. Vyberte také styl mapy.</Text>
        
        <Box mb={4}>
          <MapLinkImporter
            currentLatitude={typeof gpsLat === 'number' ? gpsLat : undefined}
            currentLongitude={typeof gpsLng === 'number' ? gpsLng : undefined}
            currentZoom={15}
            mapStyle={mapStyle}
            onMapStyleChange={setMapStyle}
            clubPrimaryColor={primaryColor}
            clubSecondaryColor={accentColor}
            clubName={clubName || 'Váš klub'}
            onImport={(coords: MapCoordinates) => {
              setGpsLat(coords.latitude);
              setGpsLng(coords.longitude);
              // Auto-fill address fields if available from geocoding
              if (coords.street) setContactStreet(coords.street);
              if (coords.city) setContactCity(coords.city);
              if (coords.zip) setContactPostalCode(coords.zip);
              if (coords.country) setContactCountry(coords.country);
              toast({
                title: 'Poloha importována',
                description: coords.city ? `GPS souřadnice a adresa (${coords.city}) načteny` : 'GPS souřadnice načteny',
                status: 'success',
                duration: 3000,
              });
            }}
          />
        </Box>

        <Divider my={6} />

        <Heading as="h3" size="md" mb={2} fontFamily={fontHeading}>📧 Kontaktní údaje</Heading>
        <Text fontSize="sm" mb={3} color="gray.600">Tyto údaje se automaticky vyplní při importu z mapy. Můžete je upravit nebo doplnit ručně.</Text>
        <SimpleGrid columns={[1, 1, 2]} spacing={4} mb={4}>
          <FormControl>
            <FormLabel>Adresa (ulice a číslo)</FormLabel>
            <Input placeholder="Hlavní 123" value={contactStreet} onChange={(e) => setContactStreet(e.target.value)} />
          </FormControl>
          <FormControl>
            <FormLabel>Město</FormLabel>
            <Input placeholder="Krnov" value={contactCity} onChange={(e) => setContactCity(e.target.value)} />
          </FormControl>
          <FormControl>
            <FormLabel>PSČ</FormLabel>
            <Input placeholder="794 01" value={contactPostalCode} onChange={(e) => setContactPostalCode(e.target.value)} />
          </FormControl>
          <FormControl>
            <FormLabel>Země</FormLabel>
            <Input placeholder="Česká republika" value={contactCountry} onChange={(e) => setContactCountry(e.target.value)} />
          </FormControl>
          <FormControl>
            <FormLabel>Telefon</FormLabel>
            <Input type="tel" placeholder="+420 123 456 789" value={contactPhone} onChange={(e) => setContactPhone(e.target.value)} />
            <FormHelperText>Hlavní kontaktní telefon klubu</FormHelperText>
          </FormControl>
          <FormControl>
            <FormLabel>E-mail</FormLabel>
            <Input type="email" placeholder="kontakt@klub.cz" value={contactEmail} onChange={(e) => setContactEmail(e.target.value)} />
            <FormHelperText>Hlavní kontaktní e-mail klubu</FormHelperText>
          </FormControl>
        </SimpleGrid>

        <Divider my={6} />

        <Heading as="h3" size="md" mb={4} fontFamily={fontHeading}>🔒 Zabezpečení a SMTP</Heading>
        <SimpleGrid columns={[1, 1, 2]} spacing={6}>
          <FormControl>
            <FormLabel>JWT tajemství</FormLabel>
            <Input value={jwtSecret} onChange={(e) => setJwtSecret(e.target.value)} placeholder="Ponechte prázdné pro stávající hodnotu" />
            <Button mt={2} size="sm" onClick={() => setJwtSecret(generateJwtSecret())}>Vygenerovat bezpečné tajemství</Button>
          </FormControl>
          <Box>
            <FormControl mb={3}>
              <FormLabel>SMTP hostitel</FormLabel>
              <Input value={smtpHost} onChange={(e) => setSmtpHost(e.target.value)} placeholder="smtp.example.com" />
            </FormControl>
            <FormControl mb={3}>
              <FormLabel>SMTP port</FormLabel>
              <Input type="number" value={smtpPort} onChange={(e) => setSmtpPort(e.target.value ? Number(e.target.value) : '')} placeholder="587" />
            </FormControl>
            <FormControl mb={3}>
              <FormLabel>SMTP uživatelské jméno</FormLabel>
              <Input value={smtpUser} onChange={(e) => setSmtpUser(e.target.value)} />
            </FormControl>
            <FormControl mb={3}>
              <FormLabel>SMTP heslo</FormLabel>
              <InputGroup>
                <Input type={showSmtpPass ? 'text' : 'password'} value={smtpPass} onChange={(e) => setSmtpPass(e.target.value)} />
                <InputRightElement width="4.5rem">
                  <Button h="1.75rem" size="sm" onClick={() => setShowSmtpPass((s) => !s)}>{showSmtpPass ? 'Skrýt' : 'Zobrazit'}</Button>
                </InputRightElement>
              </InputGroup>
            </FormControl>
            <FormControl mb={3}>
              <FormLabel>Jméno odesílatele</FormLabel>
              <Input value={smtpFromName} onChange={(e) => setSmtpFromName(e.target.value)} placeholder="Název klubu (např. Fotbal Club)" />
              <FormHelperText>Jako adresu použijeme váš SMTP username (e‑mail). Zde vyplňte pouze zobrazované jméno.</FormHelperText>
            </FormControl>
            <Checkbox isChecked={smtpTLS} onChange={(e) => setSmtpTLS(e.target.checked)}>Použít TLS</Checkbox>
            <HStack mt={3} spacing={3}>
              <Button
                size="sm"
                onClick={async () => {
                  const host = smtpHost.trim();
                  const port = typeof smtpPort === 'number' ? smtpPort : 0;
                  if (!host || !port) {
                    toast({ title: 'Zadejte SMTP host a port', status: 'warning' });
                    return;
                  }
                  setTestingSMTP(true);
                  try {
                    // Compose From as "Name <username>" for validation, if possible
                    const composedFrom = smtpFromName && smtpUser ? `${smtpFromName} <${smtpUser}>` : (smtpFromName || undefined);
                    const res = await validateSMTP({
                      host,
                      port,
                      username: smtpUser || undefined,
                      password: smtpPass || undefined,
                      from: composedFrom,
                      use_tls: smtpTLS,
                    });
                    if (res.ok) {
                      toast({ title: 'SMTP ověřeno', description: 'Připojení a případná autentizace proběhly v pořádku.', status: 'success' });
                    } else {
                      toast({ title: 'SMTP selhalo', description: res.error || 'Zkontrolujte prosím údaje (host, port, šifrování, jméno/heslo).', status: 'error', duration: 7000 });
                    }
                  } catch (e: any) {
                    const msg = e?.response?.data?.error || e?.message || 'Neznámá chyba';
                    toast({ title: 'SMTP selhalo', description: msg, status: 'error', duration: 7000 });
                  } finally {
                    setTestingSMTP(false);
                  }
                }}
                isLoading={testingSMTP}
              >Otestovat SMTP</Button>
              <Tooltip label="Pro port 465 použijte implicitní SSL (ponechte zaškrtnuté). Pro 587 obvykle STARTTLS (také zaškrtnout).">
                <InfoOutlineIcon />
              </Tooltip>
            </HStack>
            <Alert status="info" mt={4} borderRadius="md">
              <AlertIcon />
              <Box>
                <Text fontWeight="medium">Před dokončením nastavení otestujte SMTP připojení.</Text>
                <Text fontSize="sm" mt={1}>Nejčastější chyba: nesprávné heslo. Ujistěte se, že heslo je zkopírováno přesně bez mezer.</Text>
              </Box>
            </Alert>
          </Box>
        </SimpleGrid>

        <Button type="submit" colorScheme="blue" mt={8} isLoading={submitting} loadingText="Ukládám…">Dokončit nastavení</Button>
      </Box>
    </Box>
  );
};

// Lightweight preview of overall site style during setup
const SetupStylePreview: React.FC<{ styleKey: 'unified' | 'magazine' | 'pro' | 'edge' }> = ({ styleKey }) => {
  // Try to render a screenshot if present in /dist/img
  const [imgError, setImgError] = useState(false);
  const fileMap: Record<string, string> = {
    unified: 'style-unified.png',
    magazine: 'style-magazine.png',
    pro: 'style-pro.png',
    edge: 'style-edge.png',
  };
  const imgSrc = assetUrl(`/dist/img/${fileMap[styleKey] || fileMap.unified}`);

  if (!imgError && imgSrc) {
    return (
      <Box borderWidth="1px" borderRadius="md" overflow="hidden">
        <Image src={imgSrc} alt={`Náhled stylu: ${styleKey}`} onError={() => setImgError(true)} width="100%" objectFit="cover" />
      </Box>
    );
  }

  if (styleKey === 'magazine') {
    return (
      <Box className="magazine" borderRadius="md" overflow="hidden" borderWidth="1px" borderColor="gray.200">
        <Box className="mag-bars" />
        <Box p={3}>
          <HStack justify="space-between">
            <Text fontWeight="bold">Magazínová hlavička</Text>
            <Text fontSize="sm" color="gray.500">2 barvy klubu</Text>
          </HStack>
          <SimpleGrid columns={{ base: 1, md: 3 }} spacing={2} mt={3}>
            <Box h="100px" bg="gray.100" borderRadius="md" />
            <Box h="48px" bg="gray.100" borderRadius="md" />
            <Box h="48px" bg="gray.100" borderRadius="md" />
          </SimpleGrid>
        </Box>
      </Box>
    );
  }
  if (styleKey === 'pro') {
    return (
      <Box className="pro" borderRadius="md" overflow="hidden" borderWidth="1px" borderColor="gray.200">
        <Box className="pro-hero" height="120px" position="relative">
          <Box position="absolute" inset={0} bg="gray.300" />
          <Box position="absolute" inset={0} display="flex" alignItems="center" justifyContent="center">
            <Text fontWeight="bold" color="white">Fullscreen Hero (náhled)</Text>
          </Box>
        </Box>
        <Box p={3}>
          <SimpleGrid columns={{ base: 1, md: 3 }} spacing={3}>
            <Box borderWidth="1px" borderRadius="md" p={3}>Zápasy</Box>
            <Box borderWidth="1px" borderRadius="md" p={3}>Aktuality</Box>
            <Box borderWidth="1px" borderRadius="md" p={3}>Vstupenka</Box>
          </SimpleGrid>
        </Box>
      </Box>
    );
  }
  if (styleKey === 'edge') {
    return (
      <Box borderRadius="md" overflow="hidden" borderWidth="1px" borderColor="gray.200" p={3}>
        <Text fontWeight="bold" mb={2}>Edge: Full‑width minimal</Text>
        <Box h="80px" bg="gray.200" borderRadius="md" mb={2} />
        <SimpleGrid columns={{ base: 1, md: 2 }} spacing={2}>
          <Box h="48px" bg="gray.100" borderRadius="md" />
          <Box h="48px" bg="gray.100" borderRadius="md" />
        </SimpleGrid>
      </Box>
    );
  }
  return (
    <Box borderWidth="1px" borderRadius="md" p={3}>
      <Text fontSize="sm" color="gray.600">Stávající styl (Unified): Grid hero, sekce Nejbližší zápas, tři sloupce a sponzoři.</Text>
    </Box>
  );
};

export default SetupPage;
