import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  ActivityIndicator,
  StyleSheet,
  Keyboard,
  KeyboardAvoidingView,
  Platform,
  Image,
  Animated,
  ScrollView,
} from 'react-native';
import { useAuth } from '../hooks';
import { usePushNotifications } from '../hooks/usePushNotifications';
import { useDubs } from '../provider';
import { AuthContext } from '../auth-context';
import { useDubsTheme } from './theme';
import { AvatarEditor, generateSeed, getAvatarUrl } from './AvatarEditor';
import type { AuthStatus } from '../types';
import type { DubsClient } from '../client';

// ── Public Types ──

export interface RegistrationScreenProps {
  onRegister: (username: string, referralCode?: string, avatarUrl?: string) => void;
  registering: boolean;
  error: Error | null;
  client: DubsClient;
}

export interface ConnectWalletScreenProps {
  /** Call this to trigger the wallet connection flow */
  onConnect: () => void;
  /** True while the wallet is connecting/signing */
  connecting: boolean;
  /** Error from a failed connection attempt */
  error: Error | null;
}

export interface AuthGateProps {
  children: React.ReactNode;
  onSaveToken: (token: string | null) => void | Promise<void>;
  onLoadToken: () => string | null | Promise<string | null>;
  renderLoading?: (status: AuthStatus) => React.ReactNode;
  renderError?: (error: Error, retry: () => void) => React.ReactNode;
  renderRegistration?: (props: RegistrationScreenProps) => React.ReactNode;
  /**
   * Render your own connect-wallet screen.
   * Receives { onConnect, connecting, error }.
   * If omitted, the default ConnectWalletScreen is shown.
   */
  renderConnectWallet?: (props: ConnectWalletScreenProps) => React.ReactNode;
  appName?: string;
  /** Override accent color for registration screens (from developer UI config) */
  accentColor?: string;
}

// ── AuthGate Component ──

export function AuthGate({
  children,
  onSaveToken,
  onLoadToken,
  renderLoading,
  renderError,
  renderRegistration,
  renderConnectWallet,
  appName = 'Dubs',
  accentColor,
}: AuthGateProps) {
  const { client, pushEnabled, uiConfig } = useDubs();
  const auth = useAuth();
  const [phase, setPhase] = useState<'init' | 'active'>('init');
  const [registrationPhase, setRegistrationPhase] = useState(false);
  const [showPushSetup, setShowPushSetup] = useState(false);
  const [isRestoredSession, setIsRestoredSession] = useState(false);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const savedToken = await onLoadToken();
        if (cancelled) return;
        if (savedToken) {
          const restored = await auth.restoreSession(savedToken);
          if (cancelled) return;
          if (restored) { setIsRestoredSession(true); setPhase('active'); return; }
          await onSaveToken(null);
        }
        if (cancelled) return;
        setPhase('active');
        await auth.authenticate();
      } catch {
        if (!cancelled) setPhase('active');
      }
    })();
    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (auth.status === 'needsRegistration') setRegistrationPhase(true);
  }, [auth.status]);

  // Show push setup after new registration completes (not restored sessions).
  // Gated on pushConfigured.android — if the developer hasn't uploaded FCM credentials
  // for this app in the dev portal, push can't be delivered, so don't prompt.
  useEffect(() => {
    if (
      pushEnabled &&
      uiConfig.pushConfigured?.android &&
      auth.status === 'authenticated' &&
      registrationPhase &&
      !isRestoredSession
    ) {
      setShowPushSetup(true);
    }
  }, [pushEnabled, uiConfig.pushConfigured?.android, auth.status, registrationPhase, isRestoredSession]);

  useEffect(() => {
    if (auth.token) onSaveToken(auth.token);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [auth.token]);

  const retry = useCallback(() => {
    setRegistrationPhase(false);
    auth.reset();
    auth.authenticate();
  }, [auth]);

  const handleRegister = useCallback(
    (username: string, referralCode?: string, avatarUrl?: string) => {
      auth.register(username, referralCode, avatarUrl);
    },
    [auth],
  );

  // ── Render ──

  if (phase === 'init') {
    if (renderLoading) return <>{renderLoading('authenticating')}</>;
    return <DefaultLoadingScreen status="authenticating" appName={appName} accentColor={accentColor} />;
  }

  // Keep the registration screen mounted through the push step so the transition
  // from step 3 (referral) → step 4 (push) animates as a continuation of the same flow.
  const inRegistrationFlow =
    registrationPhase &&
    (auth.status === 'needsRegistration' ||
      auth.status === 'registering' ||
      (auth.status === 'authenticated' && showPushSetup));

  if (auth.status === 'authenticated' && !inRegistrationFlow) {
    return (
      <AuthContext.Provider value={auth}>
        {pushEnabled && <PushTokenRestorer />}
        {children}
      </AuthContext.Provider>
    );
  }

  if (inRegistrationFlow) {
    const isRegistering = auth.status === 'registering';
    const regError = auth.status === 'error' ? auth.error : null;
    if (renderRegistration) {
      return <>{renderRegistration({ onRegister: handleRegister, registering: isRegistering, error: regError, client })}</>;
    }
    return (
      <DefaultRegistrationScreen
        onRegister={handleRegister}
        registering={isRegistering}
        error={regError}
        client={client}
        appName={appName}
        accentColor={accentColor}
        pushStepActive={showPushSetup}
        onPushComplete={() => setShowPushSetup(false)}
      />
    );
  }

  if (auth.status === 'error' && auth.error) {
    if (renderError) return <>{renderError(auth.error, retry)}</>;
    return <DefaultErrorScreen error={auth.error} onRetry={retry} appName={appName} accentColor={accentColor} />;
  }

  // idle = waiting for user to connect — show connect wallet screen
  if (auth.status === 'idle') {
    const connectProps: ConnectWalletScreenProps = {
      onConnect: auth.authenticate,
      connecting: false,
      error: null,
    };
    if (renderConnectWallet) return <>{renderConnectWallet(connectProps)}</>;
    // Fall through to default loading (existing behaviour if no renderConnectWallet)
  }

  if (renderLoading) return <>{renderLoading(auth.status)}</>;
  return <DefaultLoadingScreen status={auth.status} appName={appName} accentColor={accentColor} />;
}

// ── Default Loading Screen ──

function DefaultLoadingScreen({ status, appName, accentColor }: { status: AuthStatus; appName: string; accentColor?: string }) {
  const t = useDubsTheme();
  const accent = accentColor || t.accent;
  const statusText: Record<AuthStatus, string> = {
    idle: 'Initializing...',
    authenticating: 'Connecting...',
    signing: 'Approve in your wallet...',
    verifying: 'Verifying...',
    registering: 'Creating account...',
    needsRegistration: 'Almost there...',
    authenticated: 'Ready!',
    error: 'Something went wrong',
  };
  return (
    <View style={[s.container, { backgroundColor: t.background }]}>
      <View style={s.centerContent}>
        <View style={s.brandingSection}>
          <View style={[s.logoCircle, { backgroundColor: accent }]}>
            <Text style={s.logoText}>D</Text>
          </View>
          <Text style={[s.appNameText, { color: t.text }]}>{appName}</Text>
        </View>
        <View style={s.loadingSection}>
          <ActivityIndicator size="large" color={accent} />
          <Text style={[s.statusText, { color: t.textMuted }]}>{statusText[status] || 'Loading...'}</Text>
        </View>
      </View>
    </View>
  );
}

// ── Default Error Screen ──

function DefaultErrorScreen({ error, onRetry, appName, accentColor }: { error: Error; onRetry: () => void; appName: string; accentColor?: string }) {
  const t = useDubsTheme();
  const accent = accentColor || t.accent;
  return (
    <View style={[s.container, { backgroundColor: t.background }]}>
      <View style={s.spreadContent}>
        <View style={s.brandingSection}>
          <View style={[s.logoCircle, { backgroundColor: accent }]}>
            <Text style={s.logoText}>D</Text>
          </View>
          <Text style={[s.appNameText, { color: t.text }]}>{appName}</Text>
        </View>
        <View style={{ gap: 16 }}>
          <View style={[s.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }]}>
            <Text style={[s.errorText, { color: t.errorText }]}>{error.message}</Text>
          </View>
          <TouchableOpacity style={[s.primaryBtn, { backgroundColor: accent }]} onPress={onRetry} activeOpacity={0.8}>
            <Text style={s.primaryBtnText}>Try Again</Text>
          </TouchableOpacity>
        </View>
      </View>
    </View>
  );
}

// ── Step Indicator ──

function StepIndicator({ currentStep }: { currentStep: number }) {
  const t = useDubsTheme();
  const steps = [0, 1, 2, 3];
  return (
    <View style={s.stepRow}>
      {steps.map((i) => (
        <React.Fragment key={i}>
          {i > 0 && (
            <View style={[s.stepLine, { backgroundColor: i <= currentStep ? t.success : t.border }]} />
          )}
          <View
            style={[
              s.stepCircle,
              i < currentStep
                ? { backgroundColor: t.success }
                : i === currentStep
                ? { backgroundColor: t.accent }
                : { backgroundColor: 'transparent', borderWidth: 2, borderColor: t.border },
            ]}
          >
            {i < currentStep ? (
              <Text style={s.stepCheck}>&#10003;</Text>
            ) : (
              <Text style={[s.stepNum, { color: i === currentStep ? '#FFF' : t.textMuted }]}>{i + 1}</Text>
            )}
          </View>
        </React.Fragment>
      ))}
    </View>
  );
}

// ── Default Registration Screen (3-Step Onboarding) ──

function DefaultRegistrationScreen({
  onRegister,
  registering,
  error,
  client,
  appName,
  accentColor,
  pushStepActive,
  onPushComplete,
}: RegistrationScreenProps & {
  appName: string;
  accentColor?: string;
  pushStepActive?: boolean;
  onPushComplete?: () => void;
}) {
  const t = useDubsTheme();
  const accent = accentColor || t.accent;
  const push = usePushNotifications();

  // ── Shared state ──
  const [step, setStep] = useState(0);
  const [avatarSeed, setAvatarSeed] = useState(generateSeed);
  const [avatarStyle, setAvatarStyle] = useState('adventurer');
  const [avatarBg, setAvatarBg] = useState('1a1a2e');
  const [showStyles, setShowStyles] = useState(false);
  const [username, setUsername] = useState('');
  const [referralCode, setReferralCode] = useState('');
  const [checking, setChecking] = useState(false);
  const [availability, setAvailability] = useState<{ available: boolean; reason?: string } | null>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  // ── Animation ──
  const fadeAnim = useRef(new Animated.Value(1)).current;
  const slideAnim = useRef(new Animated.Value(0)).current;

  const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed, avatarBg);

  // Debounced username check
  useEffect(() => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    const trimmed = username.trim();
    if (trimmed.length < 3) { setAvailability(null); setChecking(false); return; }
    setChecking(true);
    debounceRef.current = setTimeout(async () => {
      try {
        const result = await client.checkUsername(trimmed);
        setAvailability(result);
      } catch { setAvailability(null); }
      finally { setChecking(false); }
    }, 500);
    return () => { if (debounceRef.current) clearTimeout(debounceRef.current); };
  }, [username, client]);

  const animateToStep = useCallback((newStep: number) => {
    const dir = newStep > step ? 1 : -1;
    Keyboard.dismiss();
    Animated.parallel([
      Animated.timing(fadeAnim, { toValue: 0, duration: 120, useNativeDriver: true }),
      Animated.timing(slideAnim, { toValue: -dir * 40, duration: 120, useNativeDriver: true }),
    ]).start(() => {
      setStep(newStep);
      slideAnim.setValue(dir * 40);
      Animated.parallel([
        Animated.timing(fadeAnim, { toValue: 1, duration: 200, useNativeDriver: true }),
        Animated.timing(slideAnim, { toValue: 0, duration: 200, useNativeDriver: true }),
      ]).start();
    });
  }, [step, fadeAnim, slideAnim]);

  const canContinueUsername =
    username.trim().length >= 3 && availability?.available === true && !checking;

  const handleSubmit = () => {
    Keyboard.dismiss();
    onRegister(username.trim(), referralCode.trim() || undefined, avatarUrl);
  };

  // ── Step 1: Avatar ──
  const renderAvatarStep = () => (
    <View style={s.stepContainer}>
      <View style={s.stepTop}>
        <Text style={[s.title, { color: t.text }]}>Choose Your Avatar</Text>
        <Text style={[s.subtitle, { color: t.textMuted }]}>Pick a look that represents you</Text>
        <StepIndicator currentStep={0} />

        <View style={s.avatarCenter}>
          <View style={[s.avatarFrame, { borderColor: accent }]}>
            <Image source={{ uri: avatarUrl }} style={s.avatarLarge} />
            <View style={[s.checkBadge, { backgroundColor: t.success }]}>
              <Text style={s.checkBadgeText}>&#10003;</Text>
            </View>
          </View>
        </View>

        <View style={s.avatarActions}>
          <TouchableOpacity
            style={[s.outlineBtn, { borderColor: t.border }]}
            onPress={() => setAvatarSeed(generateSeed())}
            activeOpacity={0.7}
          >
            <Text style={[s.outlineBtnText, { color: t.text }]}>&#8635;  Shuffle</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={[s.outlineBtn, { borderColor: accent, backgroundColor: accent + '15' }]}
            onPress={() => setShowStyles(!showStyles)}
            activeOpacity={0.7}
          >
            <Text style={[s.outlineBtnText, { color: accent }]}>&#9786;  Customize</Text>
          </TouchableOpacity>
        </View>

        {showStyles && (
          <View style={s.styleScroll}>
            <AvatarEditor
              style={avatarStyle}
              seed={avatarSeed}
              bg={avatarBg}
              onStyleChange={setAvatarStyle}
              onSeedChange={setAvatarSeed}
              onBgChange={setAvatarBg}
              accentColor={accent}
            />
          </View>
        )}
      </View>

      <View style={s.bottomRow}>
        <TouchableOpacity
          style={[s.primaryBtn, { backgroundColor: accent, flex: 1 }]}
          onPress={() => animateToStep(1)}
          activeOpacity={0.8}
        >
          <Text style={s.primaryBtnText}>Continue  &#8250;</Text>
        </TouchableOpacity>
      </View>
    </View>
  );

  // ── Step 2: Username ──
  const renderUsernameStep = () => (
    <View style={s.stepContainer}>
      <View style={s.stepTop}>
        <View style={s.headerRow}>
          <TouchableOpacity onPress={() => animateToStep(0)} hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}>
            <Text style={[s.backChevron, { color: t.text }]}>&#8249;</Text>
          </TouchableOpacity>
          <Text style={[s.titleInline, { color: t.text }]}>Pick a Username</Text>
        </View>
        <Text style={[s.subtitle, { color: t.textMuted }]}>This is how others will see you</Text>
        <StepIndicator currentStep={1} />

        <View style={s.avatarCenter}>
          <View style={[s.avatarFrameSmall, { borderColor: accent }]}>
            <Image source={{ uri: avatarUrl }} style={s.avatarSmall} />
            <View style={[s.checkBadgeSm, { backgroundColor: t.success }]}>
              <Text style={s.checkBadgeTextSm}>&#10003;</Text>
            </View>
          </View>
        </View>

        <View style={s.inputGroup}>
          <Text style={[s.inputLabel, { color: t.text }]}>
            Username <Text style={{ color: t.errorText }}>*</Text>
          </Text>
          <TextInput
            style={[s.input, { backgroundColor: t.surface, color: t.text, borderColor: accent }]}
            placeholder="Enter username"
            placeholderTextColor={t.textDim}
            value={username}
            onChangeText={setUsername}
            autoCapitalize="none"
            autoCorrect={false}
            autoFocus
          />
          {checking ? (
            <Text style={[s.hint, { color: t.textDim }]}>Checking...</Text>
          ) : availability ? (
            <Text style={[s.hint, { color: availability.available ? t.success : t.errorText }]}>
              {availability.available ? '\u2713 Available!' : (availability.reason || 'Username taken')}
            </Text>
          ) : username.trim().length > 0 && username.trim().length < 3 ? (
            <Text style={[s.hint, { color: t.textDim }]}>At least 3 characters</Text>
          ) : null}
        </View>
      </View>

      <View style={s.bottomRow}>
        <TouchableOpacity
          style={[s.secondaryBtn, { borderColor: t.border }]}
          onPress={() => animateToStep(0)}
          activeOpacity={0.7}
        >
          <Text style={[s.secondaryBtnText, { color: t.text }]}>&#8249;  Back</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[s.primaryBtn, { backgroundColor: accent, flex: 1, opacity: canContinueUsername ? 1 : 0.4 }]}
          onPress={() => animateToStep(2)}
          disabled={!canContinueUsername}
          activeOpacity={0.8}
        >
          <Text style={s.primaryBtnText}>Continue  &#8250;</Text>
        </TouchableOpacity>
      </View>
    </View>
  );

  // ── Step 3: Referral + Create ──
  const renderReferralStep = () => (
    <View style={s.stepContainer}>
      <View style={s.stepTop}>
        <View style={s.headerRow}>
          <TouchableOpacity onPress={() => animateToStep(1)} hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}>
            <Text style={[s.backChevron, { color: t.text }]}>&#8249;</Text>
          </TouchableOpacity>
          <Text style={[s.titleInline, { color: t.text }]}>Almost There!</Text>
        </View>
        <Text style={[s.subtitle, { color: t.textMuted }]}>Got a referral code? (optional)</Text>
        <StepIndicator currentStep={2} />

        {/* Profile preview card */}
        <View style={[s.profileCard, { borderColor: t.border }]}>
          <Text style={[s.profileLabel, { color: t.textMuted }]}>Your Profile</Text>
          <View style={s.profileRow}>
            <Image source={{ uri: avatarUrl }} style={s.profileAvatar} />
            <View style={{ gap: 4 }}>
              <Text style={[s.profileUsername, { color: t.text }]}>@{username}</Text>
              <Text style={[s.profileReady, { color: t.success }]}>{'\u2713'} Ready to go!</Text>
            </View>
          </View>
        </View>

        {error ? (
          <View style={[s.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }]}>
            <Text style={[s.errorText, { color: t.errorText }]}>{error.message}</Text>
          </View>
        ) : null}

        <View style={s.inputGroup}>
          <Text style={[s.inputLabel, { color: t.text }]}>
            Referral Code <Text style={{ color: t.textMuted }}>(optional)</Text>
          </Text>
          <TextInput
            style={[s.input, { backgroundColor: t.surface, color: t.text, borderColor: t.border }]}
            placeholder="Enter referral code"
            placeholderTextColor={t.textDim}
            value={referralCode}
            onChangeText={setReferralCode}
            autoCapitalize="none"
            autoCorrect={false}
            editable={!registering}
          />
          <Text style={[s.hint, { color: t.textMuted }]}>
            {'\uD83C\uDF81'} If a friend invited you, enter their code to give them credit!
          </Text>
        </View>
      </View>

      <View style={s.bottomRow}>
        <TouchableOpacity
          style={[s.secondaryBtn, { borderColor: t.border }]}
          onPress={() => animateToStep(1)}
          disabled={registering}
          activeOpacity={0.7}
        >
          <Text style={[s.secondaryBtnText, { color: t.text }]}>&#8249;  Back</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[s.primaryBtn, { backgroundColor: accent, flex: 1, opacity: registering ? 0.7 : 1 }]}
          onPress={handleSubmit}
          disabled={registering}
          activeOpacity={0.8}
        >
          {registering ? (
            <ActivityIndicator color="#FFFFFF" size="small" />
          ) : (
            <Text style={s.primaryBtnText}>Create Account</Text>
          )}
        </TouchableOpacity>
      </View>
    </View>
  );

  // Advance to the push step when the parent signals (after auth completes).
  // Uses the same animateToStep transition as steps 0→1→2 so it feels like
  // a continuation, not a separate modal swap.
  useEffect(() => {
    if (pushStepActive && step !== 3) {
      animateToStep(3);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pushStepActive]);

  // ── Step 4: Push Notifications ──
  const handleEnablePush = async () => {
    try { await push.register(); } catch {}
    onPushComplete?.();
  };

  const renderPushStep = () => (
    <View style={s.stepContainer}>
      <View style={s.stepTop}>
        <Text style={[s.title, { color: t.text }]}>Enable Notifications</Text>
        <Text style={[s.subtitle, { color: t.textMuted }]}>
          Stay in the loop with real-time updates
        </Text>
        <StepIndicator currentStep={3} />

        <View style={pushStyles.iconContainer}>
          <View style={[pushStyles.bellCircle, { backgroundColor: accent + '20' }]}>
            <Text style={[pushStyles.bellIcon, { color: accent }]}>{'🔔'}</Text>
          </View>
        </View>

        <View style={pushStyles.benefitsList}>
          <Text style={[pushStyles.benefitsHeader, { color: t.text }]}>
            Get real-time updates when:
          </Text>
          {[
            'A fight you picked on goes LIVE',
            'Your pick wins or loses',
            'Final results and rankings',
          ].map((item, i) => (
            <View key={i} style={pushStyles.benefitRow}>
              <View style={[pushStyles.bulletDot, { backgroundColor: accent }]} />
              <Text style={[pushStyles.benefitText, { color: t.textMuted }]}>{item}</Text>
            </View>
          ))}
        </View>
      </View>

      <View style={s.bottomRow}>
        <TouchableOpacity
          style={[s.secondaryBtn, { borderColor: t.border }]}
          onPress={onPushComplete}
          activeOpacity={0.7}
        >
          <Text style={[s.secondaryBtnText, { color: t.textMuted }]}>Maybe Later</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[s.primaryBtn, { backgroundColor: accent, flex: 1, opacity: push.loading ? 0.7 : 1 }]}
          onPress={handleEnablePush}
          disabled={push.loading}
          activeOpacity={0.8}
        >
          {push.loading ? (
            <ActivityIndicator color="#FFFFFF" size="small" />
          ) : (
            <Text style={s.primaryBtnText}>Enable Notifications</Text>
          )}
        </TouchableOpacity>
      </View>
    </View>
  );

  const renderStep = () => {
    switch (step) {
      case 0: return renderAvatarStep();
      case 1: return renderUsernameStep();
      case 2: return renderReferralStep();
      case 3: return renderPushStep();
      default: return null;
    }
  };

  return (
    <KeyboardAvoidingView
      style={[s.container, { backgroundColor: t.background }]}
      behavior={Platform.OS === 'ios' ? 'padding' : undefined}
    >
      <ScrollView
        contentContainerStyle={{ flexGrow: 1 }}
        keyboardShouldPersistTaps="handled"
        bounces={false}
      >
        <Animated.View
          style={[
            { flex: 1 },
            { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
          ]}
        >
          {renderStep()}
        </Animated.View>
      </ScrollView>
    </KeyboardAvoidingView>
  );
}

// ── Push Token Restorer (silent, zero UI) ──
// Runs inside DubsContext + AuthGate when user is authenticated.
// Silently re-registers the push token for returning users who already granted permission.
// Does NOT prompt — the prompt only happens in step 4 of DefaultRegistrationScreen during onboarding.

function PushTokenRestorer() {
  const push = usePushNotifications();
  const restored = useRef(false);

  useEffect(() => {
    if (restored.current) return;
    restored.current = true;
    push.restoreIfGranted();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return null;
}

const pushStyles = StyleSheet.create({
  iconContainer: { alignItems: 'center', marginVertical: 24 },
  bellCircle: { width: 100, height: 100, borderRadius: 50, justifyContent: 'center', alignItems: 'center' },
  bellIcon: { fontSize: 48 },
  benefitsList: { paddingHorizontal: 24, gap: 12, marginTop: 8 },
  benefitsHeader: { fontSize: 17, fontWeight: '700', marginBottom: 4 },
  benefitRow: { flexDirection: 'row', alignItems: 'center', gap: 12 },
  bulletDot: { width: 8, height: 8, borderRadius: 4 },
  benefitText: { fontSize: 16, flex: 1 },
});

// ── Styles ──

const s = StyleSheet.create({
  container: { flex: 1 },
  // Loading / Error
  centerContent: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 32, gap: 48 },
  spreadContent: { flex: 1, justifyContent: 'space-between', paddingHorizontal: 32, paddingTop: 120, paddingBottom: 80 },
  brandingSection: { alignItems: 'center', gap: 12 },
  logoCircle: { width: 80, height: 80, borderRadius: 40, justifyContent: 'center', alignItems: 'center', marginBottom: 8 },
  logoText: { fontSize: 36, fontWeight: '800', color: '#FFFFFF' },
  appNameText: { fontSize: 32, fontWeight: '800' },
  loadingSection: { alignItems: 'center', gap: 16 },
  statusText: { fontSize: 16, textAlign: 'center' },
  errorBox: { borderWidth: 1, borderRadius: 12, paddingHorizontal: 16, paddingVertical: 12 },
  errorText: { fontSize: 14, textAlign: 'center' },
  // Step indicator
  stepRow: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 24, marginVertical: 16 },
  stepLine: { flex: 1, height: 2 },
  stepCircle: { width: 36, height: 36, borderRadius: 18, justifyContent: 'center', alignItems: 'center' },
  stepCheck: { color: '#FFF', fontSize: 16, fontWeight: '700' },
  stepNum: { fontSize: 14, fontWeight: '700' },
  // Onboarding layout
  stepContainer: { flex: 1, justifyContent: 'space-between', paddingBottom: 40 },
  stepTop: { gap: 8, paddingTop: 64 },
  headerRow: { flexDirection: 'row', alignItems: 'center', gap: 8, paddingHorizontal: 24 },
  backChevron: { fontSize: 32, fontWeight: '300', lineHeight: 36, marginTop: -2 },
  title: { fontSize: 28, fontWeight: '800', paddingHorizontal: 24 },
  titleInline: { fontSize: 28, fontWeight: '800' },
  subtitle: { fontSize: 15, paddingHorizontal: 24, lineHeight: 20 },
  // Avatar
  avatarCenter: { alignItems: 'center', marginVertical: 12 },
  avatarFrame: { borderWidth: 3, borderRadius: 20, padding: 4 },
  avatarLarge: { width: 160, height: 160, borderRadius: 16, backgroundColor: '#E5E5EA' },
  checkBadge: { position: 'absolute', bottom: -6, right: -6, width: 28, height: 28, borderRadius: 14, justifyContent: 'center', alignItems: 'center' },
  checkBadgeText: { color: '#FFF', fontSize: 15, fontWeight: '700' },
  avatarFrameSmall: { borderWidth: 3, borderRadius: 14, padding: 3 },
  avatarSmall: { width: 100, height: 100, borderRadius: 12, backgroundColor: '#E5E5EA' },
  checkBadgeSm: { position: 'absolute', bottom: -4, right: -4, width: 22, height: 22, borderRadius: 11, justifyContent: 'center', alignItems: 'center' },
  checkBadgeTextSm: { color: '#FFF', fontSize: 12, fontWeight: '700' },
  avatarActions: { flexDirection: 'row', justifyContent: 'center', gap: 12, paddingHorizontal: 24 },
  outlineBtn: { borderWidth: 1.5, borderRadius: 12, paddingHorizontal: 20, paddingVertical: 12 },
  outlineBtnText: { fontSize: 15, fontWeight: '600' },
  styleScroll: { paddingHorizontal: 24, marginTop: 4 },
  styleThumbWrap: { borderWidth: 2, borderRadius: 12, padding: 3, marginRight: 10 },
  styleThumb: { width: 52, height: 52, borderRadius: 10, backgroundColor: '#E5E5EA' },
  // Input
  inputGroup: { paddingHorizontal: 24, gap: 6 },
  inputLabel: { fontSize: 15, fontWeight: '600' },
  input: { height: 56, borderRadius: 16, borderWidth: 1.5, paddingHorizontal: 16, fontSize: 16 },
  hint: { fontSize: 13, paddingLeft: 4 },
  // Profile card
  profileCard: { marginHorizontal: 24, borderWidth: 1, borderRadius: 16, padding: 16, gap: 12 },
  profileLabel: { fontSize: 13 },
  profileRow: { flexDirection: 'row', alignItems: 'center', gap: 14 },
  profileAvatar: { width: 56, height: 56, borderRadius: 12, backgroundColor: '#E5E5EA' },
  profileUsername: { fontSize: 20, fontWeight: '800' },
  profileReady: { fontSize: 14, fontWeight: '600' },
  // Buttons
  bottomRow: { flexDirection: 'row', gap: 12, paddingHorizontal: 24 },
  primaryBtn: { height: 56, borderRadius: 16, justifyContent: 'center', alignItems: 'center' },
  primaryBtnText: { color: '#FFFFFF', fontSize: 18, fontWeight: '700' },
  secondaryBtn: { height: 56, borderRadius: 16, borderWidth: 1.5, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 24 },
  secondaryBtnText: { fontSize: 16, fontWeight: '600' },
});
