import { useState } from 'react';
import {
  ActivityIndicator,
  Linking,
  ScrollView,
  Switch,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { useMailConnect, type MailProvider } from '../../hooks/useMailConnect';
import { humanizeMailError } from '../../lib/mailErrors';
import { apiFetch } from '../../lib/api';
import { useColors } from '../../lib/theme';
import { FormSheet } from '../FormSheet';
import { useMailConnectDraft } from '../../stores/mailConnectDraft';

const CONSENT_VERSION = 'art9-mail-v1-2026-05-13';
const PRIVACY_URL = 'https://rebreak.org/datenschutz';

type Props = {
  visible: boolean;
  onClose: () => void;
  onSuccess: () => void;
};

type ProviderConfig = {
  id: MailProvider;
  labelKey: string;
  icon: React.ComponentProps<typeof Ionicons>['name'];
  color: string;
  guideKey: string;
  guideUrl: string;
  disabled?: boolean;
  disabledLabelKey?: string;
  authMethod?: 'imap' | 'oauth_microsoft';
};

const PROVIDERS: ProviderConfig[] = [
  {
    id: 'gmail',
    labelKey: 'mail.provider_gmail',
    icon: 'mail',
    color: '#EA4335',
    guideKey: 'mail.app_password_guide_gmail',
    guideUrl: 'https://myaccount.google.com/apppasswords',
  },
  {
    id: 'icloud',
    labelKey: 'mail.provider_icloud',
    icon: 'cloud',
    color: '#007AFF',
    guideKey: 'mail.app_password_guide_icloud',
    guideUrl: 'https://appleid.apple.com/account/manage',
  },
  {
    id: 'outlook',
    labelKey: 'mail.provider_outlook',
    icon: 'mail-open',
    color: '#0078D4',
    guideKey: 'mail.app_password_guide_outlook',
    guideUrl: 'https://account.microsoft.com/security',
    authMethod: 'oauth_microsoft',
  },
  {
    id: 'yahoo',
    labelKey: 'mail.provider_yahoo',
    icon: 'at',
    color: '#7C3AED',
    guideKey: 'mail.app_password_guide_yahoo',
    guideUrl: 'https://login.yahoo.com/account/security',
  },
  {
    id: 'gmx',
    labelKey: 'mail.provider_gmx',
    icon: 'mail-unread',
    color: '#E87A22',
    guideKey: 'mail.app_password_guide_gmx',
    guideUrl: 'https://www.gmx.net/mail/security',
  },
  {
    id: 'other',
    labelKey: 'mail.provider_other',
    icon: 'server',
    color: '#737373',
    guideKey: 'mail.app_password_guide_other',
    guideUrl: '',
  },
];

/**
 * Bottom-Sheet zum Verbinden eines Postfachs.
 *
 * Drei Ansichten im selben Sheet (kein Navigations-Header):
 *  1. Consent-Screen (Art. 9 DSGVO) — MUSS zuerst bestätigt werden
 *  2. Provider-Grid (6 Tiles) — nach Consent-Bestätigung freigeschaltet
 *  3. Formular: Email → App-Passwort → Bezeichnung (eine ScrollView)
 */
export function ConnectMailSheet({ visible, onClose, onSuccess }: Props) {
  const { t } = useTranslation();
  const colors = useColors();
  const { connect, connecting, error: connectError } = useMailConnect();

  const {
    view,
    consentGiven,
    selectedProvider,
    email,
    title,
    pendingOAuthConnectionId,
    setView,
    setConsentGiven,
    setSelectedProvider,
    setEmail,
    setTitle,
    setPendingOAuthConnectionId,
    reset: resetDraft,
  } = useMailConnectDraft();

  const [password, setPassword] = useState('');
  const [passwordVisible, setPasswordVisible] = useState(false);
  const [formError, setFormError] = useState<string | null>(null);
  const [oauthRunning, setOauthRunning] = useState(false);
  const [oauthError, setOauthError] = useState<string | null>(null);

  function handleClose() {
    resetDraft();
    setPassword('');
    setPasswordVisible(false);
    setFormError(null);
    setOauthRunning(false);
    setOauthError(null);
    onClose();
  }

  function defaultTitleForProvider(provider: ProviderConfig | null): string {
    if (!provider) return '';
    const labelMap: Record<string, string> = {
      gmail: 'Mein Gmail',
      icloud: 'Mein iCloud',
      outlook: 'Mein Outlook',
      yahoo: 'Mein Yahoo',
      gmx: 'Mein GMX',
      other: '',
    };
    return labelMap[provider.id] ?? '';
  }

  function handleConsentNext() {
    setView('grid');
  }

  function handleProviderSelect(provider: ProviderConfig) {
    setSelectedProvider(provider);
    setEmail('');
    setPassword('');
    setTitle(defaultTitleForProvider(provider));
    setFormError(null);
    setOauthError(null);
    if (provider.authMethod === 'oauth_microsoft') {
      setView('oauth_warning');
    } else {
      setView('form');
    }
  }

  async function handleOAuthStart() {
    setOauthRunning(true);
    setOauthError(null);
    setView('oauth_pending');
    try {
      const { authorizationUrl } = await apiFetch<{ authorizationUrl: string }>(
        '/api/mail/oauth/microsoft/init',
        { method: 'POST', body: email.trim() ? { email: email.trim() } : {} }
      );

      try {
        await WebBrowser.dismissAuthSession();
      } catch {}

      const result = await WebBrowser.openAuthSessionAsync(
        authorizationUrl,
        'rebreak://auth/mail-oauth-callback'
      );

      console.log('[oauth] WebBrowser result.type=', result.type);
      if (result.type !== 'success') {
        setOauthError(t('mail.oauth.error_aborted'));
        setView('oauth_warning');
        setOauthRunning(false);
        return;
      }

      console.log('[oauth] result.url=', (result as any).url);
      const url = new URL((result as any).url);
      const code = url.searchParams.get('code');
      const state = url.searchParams.get('state');
      const msError = url.searchParams.get('error');
      const msErrorDescription = url.searchParams.get('error_description');
      console.log('[oauth] code?=', !!code, 'state?=', !!state, 'msError=', msError, 'desc=', msErrorDescription);

      if (msError) {
        // Microsoft hat einen expliziten Error im Redirect zurückgegeben (z.B.
        // access_denied wenn User Consent abbricht, invalid_redirect_uri wenn
        // Azure-App-Config nicht stimmt). Zeig dem User den echten Grund.
        setOauthError(`Microsoft: ${msError}${msErrorDescription ? ` — ${msErrorDescription}` : ''}`);
        setView('oauth_warning');
        setOauthRunning(false);
        return;
      }

      if (!code || !state) {
        setOauthError(t('mail.oauth.error_no_code'));
        setView('oauth_warning');
        setOauthRunning(false);
        return;
      }

      const conn = await apiFetch<{ connectionId: string; email: string; provider: string; title: null }>(
        '/api/mail/oauth/microsoft/callback',
        { method: 'POST', body: { code, state } }
      );

      setPendingOAuthConnectionId(conn.connectionId);
      setOauthRunning(false);
      handleClose();
      onSuccess();
    } catch (e: any) {
      // Den echten Backend-Fehler sichtbar machen statt nur generischen Text
      // (apiFetch wirft `Error("API <status>: <body>")` — Status + Body landen
      // dann sowohl in Metro-Logs als auch im UI-Banner).
      const detail = (e?.message ?? String(e)) || 'unknown';
      console.log('[oauth] callback API call failed — error=', detail);
      setOauthError(`${t('mail.oauth.error_callback_failed')}\n${detail}`);
      setView('oauth_warning');
      setOauthRunning(false);
    }
  }

  async function handleConnect() {
    setFormError(null);

    try {
      await apiFetch('/api/mail-connections/consent', {
        method: 'POST',
        body: { consentVersion: CONSENT_VERSION },
      });
    } catch {
      // Backend macht Consent atomar beim Connect-Endpoint — Fehler hier ignorieren.
    }

    const result = await connect({ email: email.trim(), password });
    if (result.ok) {
      if (title.trim()) {
        try {
          const connections = await apiFetch<{ id: string; email: string }[]>('/api/mail-connections');
          const match = connections.find((c) => c.email === email.trim());
          if (match) {
            await apiFetch(`/api/mail-connections/${match.id}`, {
              method: 'PATCH',
              body: { title: title.trim() },
            });
          }
        } catch {
          // Title-PATCH ist best-effort — Connection selbst ist OK
        }
      }
      handleClose();
      onSuccess();
    } else if (result.error?.includes('412') || result.error?.includes('consent_required')) {
      setView('consent');
      setConsentGiven(false);
    } else {
      setFormError(t(humanizeMailError(result.error)));
    }
  }

  const sheetTitle =
    view === 'form' && selectedProvider
      ? t(selectedProvider.labelKey)
      : view === 'oauth_warning' || view === 'oauth_pending'
        ? t('mail.provider_outlook')
        : t('mail.connect_sheet_title');

  return (
    <FormSheet
      visible={visible}
      onClose={handleClose}
      title={sheetTitle}
      // Fixed 0.85 über ALLE Steps (Consent/Grid/Form/OAuth) — Auto-Fit hatte
      // pro Step gehüpft (kleiner Grid + großes Form), schlechtes Multi-Step-UX.
      // User kann manuell per Drag-Grabber hoch- oder runterziehen.
      initialHeightPct={0.85}
      growWithKeyboard
    >
      {view === 'consent' ? (
        <ConsentStep
          consentGiven={consentGiven}
          onToggleConsent={setConsentGiven}
          onNext={handleConsentNext}
          t={t}
          colors={colors}
        />
      ) : view === 'grid' ? (
        <ProviderGrid providers={PROVIDERS} onSelect={handleProviderSelect} t={t} />
      ) : view === 'oauth_warning' ? (
        <OAuthWarningStep
          error={oauthError}
          onContinue={handleOAuthStart}
          onCancel={() => setView('grid')}
          t={t}
          colors={colors}
        />
      ) : view === 'oauth_pending' ? (
        <OAuthPendingStep t={t} colors={colors} />
      ) : (
        <FormView
          selectedProvider={selectedProvider}
          email={email}
          setEmail={setEmail}
          password={password}
          setPassword={setPassword}
          passwordVisible={passwordVisible}
          setPasswordVisible={setPasswordVisible}
          title={title}
          setTitle={setTitle}
          formError={formError}
          setFormError={setFormError}
          connectError={connectError}
          connecting={connecting}
          onConnect={handleConnect}
          t={t}
          colors={colors}
        />
      )}
    </FormSheet>
  );
}

// ---------------------------------------------------------------------------
// Sub-View: Form (email → password → title, eine ScrollView)
// ---------------------------------------------------------------------------

function FormView({
  selectedProvider,
  email,
  setEmail,
  password,
  setPassword,
  passwordVisible,
  setPasswordVisible,
  title,
  setTitle,
  formError,
  setFormError,
  connectError,
  connecting,
  onConnect,
  t,
  colors,
}: {
  selectedProvider: { id: string; guideKey: string; guideUrl: string } | null;
  email: string;
  setEmail: (v: string) => void;
  password: string;
  setPassword: (v: string) => void;
  passwordVisible: boolean;
  setPasswordVisible: (v: boolean) => void;
  title: string;
  setTitle: (v: string) => void;
  formError: string | null;
  setFormError: (v: string | null) => void;
  connectError: string | null;
  connecting: boolean;
  onConnect: () => void;
  t: (key: string) => string;
  colors: ReturnType<typeof useColors>;
}) {
  const errorText = formError ?? (connectError ? t(humanizeMailError(connectError)) : null);

  return (
    <View style={{ flex: 1 }}>
      <ScrollView
        style={{ flex: 1 }}
        contentContainerStyle={{ padding: 16, gap: 16, paddingBottom: 24 }}
        keyboardShouldPersistTaps="handled"
        showsVerticalScrollIndicator={false}
      >
        {/* App-Password-Banner — provider-spezifisch, nicht für 'other' */}
        {selectedProvider && selectedProvider.id !== 'other' && (
          <View
            style={{
              flexDirection: 'row',
              gap: 10,
              padding: 12,
              backgroundColor: '#f0f7ff',
              borderRadius: 12,
              borderWidth: 1,
              borderColor: '#bfdbfe',
            }}
          >
            <Ionicons
              name="information-circle"
              size={18}
              color="#1d4ed8"
              style={{ marginTop: 1 }}
            />
            <View style={{ flex: 1, gap: 4 }}>
              <Text style={{ fontSize: 12, fontFamily: 'Nunito_600SemiBold', color: '#1e3a8a' }}>
                {t('mail.app_password_required_title')}
              </Text>
              <Text
                style={{
                  fontSize: 12,
                  fontFamily: 'Nunito_400Regular',
                  color: '#1d4ed8',
                  lineHeight: 17,
                }}
              >
                {t(selectedProvider.guideKey)}
              </Text>
              {selectedProvider.guideUrl.length > 0 && (
                <TouchableOpacity
                  activeOpacity={0.7}
                  onPress={() => Linking.openURL(selectedProvider.guideUrl)}
                >
                  <Text
                    style={{
                      fontSize: 12,
                      fontFamily: 'Nunito_600SemiBold',
                      color: '#007AFF',
                      marginTop: 2,
                    }}
                  >
                    {t('mail.app_password_open_link')} →
                  </Text>
                </TouchableOpacity>
              )}
            </View>
          </View>
        )}

        {/* E-Mail */}
        <View style={{ gap: 6 }}>
          <Text style={{ fontSize: 12, fontFamily: 'Nunito_600SemiBold', color: colors.textMuted }}>
            {t('mail.form_email_label')}
          </Text>
          <View
            style={{
              backgroundColor: colors.surfaceElevated,
              borderRadius: 12,
              paddingHorizontal: 14,
            }}
          >
            <TextInput
              value={email}
              onChangeText={(v) => { setEmail(v); setFormError(null); }}
              placeholder={t('mail.form_email_placeholder')}
              placeholderTextColor={colors.textMuted}
              keyboardType="email-address"
              autoCapitalize="none"
              autoCorrect={false}
              style={{
                paddingVertical: 12,
                fontSize: 15,
                fontFamily: 'Nunito_400Regular',
                color: colors.text,
              }}
            />
          </View>
        </View>

        {/* App-Passwort */}
        <View style={{ gap: 6 }}>
          <Text style={{ fontSize: 12, fontFamily: 'Nunito_600SemiBold', color: colors.textMuted }}>
            {t('mail.form_password_label')}
          </Text>
          <View
            style={{
              flexDirection: 'row',
              alignItems: 'center',
              backgroundColor: colors.surfaceElevated,
              borderRadius: 12,
              paddingHorizontal: 14,
            }}
          >
            <TextInput
              value={password}
              onChangeText={(v) => { setPassword(v); setFormError(null); }}
              placeholder={t('mail.form_password_placeholder')}
              placeholderTextColor={colors.textMuted}
              secureTextEntry={!passwordVisible}
              autoCapitalize="none"
              autoCorrect={false}
              style={{
                flex: 1,
                paddingVertical: 12,
                fontSize: 15,
                fontFamily: 'Nunito_400Regular',
                color: colors.text,
              }}
            />
            <TouchableOpacity
              activeOpacity={0.7}
              onPress={() => setPasswordVisible(!passwordVisible)}
              hitSlop={8}
            >
              <Ionicons
                name={passwordVisible ? 'eye-off-outline' : 'eye-outline'}
                size={20}
                color="#a3a3a3"
              />
            </TouchableOpacity>
          </View>
          {/* AES-Verschlüsselungs-Hinweis als Footnote */}
          <View style={{ flexDirection: 'row', alignItems: 'center', gap: 4, marginTop: 2 }}>
            <Ionicons name="shield-checkmark" size={11} color="#16a34a" />
            <Text
              style={{
                fontSize: 11,
                fontFamily: 'Nunito_400Regular',
                color: colors.textMuted,
                flex: 1,
                lineHeight: 15,
              }}
            >
              {t('mail.form_privacy_note')}
            </Text>
          </View>
        </View>

        {/* Bezeichnung */}
        <View style={{ gap: 6 }}>
          <Text style={{ fontSize: 12, fontFamily: 'Nunito_600SemiBold', color: colors.textMuted }}>
            {t('mail.title_label')}
          </Text>
          <View
            style={{
              backgroundColor: colors.surfaceElevated,
              borderRadius: 12,
              paddingHorizontal: 14,
            }}
          >
            <TextInput
              value={title}
              onChangeText={setTitle}
              placeholder={t('mail.title_placeholder')}
              placeholderTextColor={colors.textMuted}
              autoCapitalize="sentences"
              autoCorrect={false}
              style={{
                paddingVertical: 12,
                fontSize: 15,
                fontFamily: 'Nunito_400Regular',
                color: colors.text,
              }}
            />
          </View>
        </View>

        {/* Fehler */}
        {errorText && (
          <Text
            style={{
              fontSize: 13,
              fontFamily: 'Nunito_400Regular',
              color: '#dc2626',
            }}
          >
            {errorText}
          </Text>
        )}

        {/* Connect-Button */}
        <TouchableOpacity
          activeOpacity={0.85}
          onPress={onConnect}
          disabled={connecting}
          style={{ marginTop: 4, marginBottom: 12 }}
        >
          <View
            style={{
              backgroundColor: connecting ? '#d4d4d4' : '#007AFF',
              borderRadius: 14,
              paddingVertical: 14,
              alignItems: 'center',
            }}
          >
            {connecting ? (
              <ActivityIndicator color="#fff" />
            ) : (
              <Text style={{ fontSize: 15, fontFamily: 'Nunito_700Bold', color: '#fff' }}>
                {t('mail.form_connect_btn')}
              </Text>
            )}
          </View>
        </TouchableOpacity>
      </ScrollView>
    </View>
  );
}

// ---------------------------------------------------------------------------
// Sub-View: Consent (Art. 9 DSGVO) — muss als erster Schritt bestätigt werden
// ---------------------------------------------------------------------------

function ConsentStep({
  consentGiven,
  onToggleConsent,
  onNext,
  t,
  colors,
}: {
  consentGiven: boolean;
  onToggleConsent: (v: boolean) => void;
  onNext: () => void;
  t: (key: string) => string;
  colors: ReturnType<typeof useColors>;
}) {
  return (
    <ScrollView
      style={{ flex: 1 }}
      contentContainerStyle={{ padding: 20, gap: 16 }}
      keyboardShouldPersistTaps="handled"
      showsVerticalScrollIndicator={false}
    >
      <Text
        style={{
          fontSize: 14,
          fontFamily: 'Nunito_400Regular',
          color: colors.text,
          lineHeight: 21,
        }}
      >
        {t('mail.consent.intro')}
      </Text>

      <View
        style={{
          backgroundColor: '#fefce8',
          borderRadius: 12,
          borderWidth: 1,
          borderColor: '#fde68a',
          padding: 14,
          gap: 12,
        }}
      >
        <View style={{ flexDirection: 'row', alignItems: 'flex-start', gap: 10 }}>
          <Ionicons
            name="document-text-outline"
            size={18}
            color="#92400e"
            style={{ marginTop: 1 }}
          />
          <Text
            style={{
              flex: 1,
              fontSize: 13,
              fontFamily: 'Nunito_400Regular',
              color: '#78350f',
              lineHeight: 19,
            }}
          >
            {t('mail.consent.legal_text')}
          </Text>
        </View>

        <View
          style={{
            flexDirection: 'row',
            alignItems: 'center',
            gap: 12,
            paddingTop: 4,
            borderTopWidth: 1,
            borderTopColor: '#fde68a',
          }}
        >
          <Switch
            value={consentGiven}
            onValueChange={onToggleConsent}
            trackColor={{ false: '#d1d5db', true: '#16a34a' }}
            thumbColor="#fff"
          />
          <TouchableOpacity
            activeOpacity={0.7}
            onPress={() => onToggleConsent(!consentGiven)}
            style={{ flex: 1 }}
          >
            <Text
              style={{
                fontSize: 13,
                fontFamily: 'Nunito_600SemiBold',
                color: '#78350f',
                lineHeight: 18,
              }}
            >
              {t('mail.consent.checkbox_label')}
            </Text>
          </TouchableOpacity>
        </View>
      </View>

      <TouchableOpacity
        activeOpacity={0.7}
        onPress={() => Linking.openURL(PRIVACY_URL)}
      >
        <Text
          style={{
            fontSize: 13,
            fontFamily: 'Nunito_600SemiBold',
            color: '#007AFF',
            textAlign: 'center',
          }}
        >
          {t('mail.consent.more_link')} →
        </Text>
      </TouchableOpacity>

      <TouchableOpacity
        activeOpacity={consentGiven ? 0.85 : 1}
        onPress={consentGiven ? onNext : undefined}
        disabled={!consentGiven}
        style={{ marginTop: 4, marginBottom: 12 }}
      >
        <View
          style={{
            backgroundColor: consentGiven ? '#007AFF' : '#d4d4d4',
            borderRadius: 14,
            paddingVertical: 14,
            alignItems: 'center',
          }}
        >
          <Text style={{ fontSize: 15, fontFamily: 'Nunito_700Bold', color: '#fff' }}>
            {t('mail.consent.cta_next')}
          </Text>
        </View>
      </TouchableOpacity>
    </ScrollView>
  );
}

// ---------------------------------------------------------------------------
// Sub-View: OAuth Warning (DSB Memo Section 6.1 — Outing-Effekt-Hinweis)
// ---------------------------------------------------------------------------

function OAuthWarningStep({
  error,
  onContinue,
  onCancel,
  t,
  colors,
}: {
  error: string | null;
  onContinue: () => void;
  onCancel: () => void;
  t: (key: string) => string;
  colors: ReturnType<typeof useColors>;
}) {
  return (
    <ScrollView
      style={{ flex: 1 }}
      contentContainerStyle={{ padding: 20, gap: 16 }}
      keyboardShouldPersistTaps="handled"
      showsVerticalScrollIndicator={false}
    >
      <View
        style={{
          backgroundColor: '#fffbeb',
          borderRadius: 12,
          borderWidth: 1,
          borderColor: '#fde68a',
          padding: 14,
          gap: 10,
        }}
      >
        <View style={{ flexDirection: 'row', alignItems: 'flex-start', gap: 10 }}>
          <Ionicons name="information-circle-outline" size={20} color="#92400e" style={{ marginTop: 1 }} />
          <Text
            style={{
              flex: 1,
              fontSize: 13,
              fontFamily: 'Nunito_700Bold',
              color: '#92400e',
            }}
          >
            {t('mail.oauth.warning_title')}
          </Text>
        </View>
        <Text
          style={{
            fontSize: 13,
            fontFamily: 'Nunito_400Regular',
            color: '#78350f',
            lineHeight: 19,
          }}
        >
          {t('mail.oauth.warning_body')}
        </Text>
      </View>

      {error ? (
        <Text
          style={{
            fontSize: 13,
            fontFamily: 'Nunito_400Regular',
            color: '#dc2626',
            textAlign: 'center',
          }}
        >
          {error}
        </Text>
      ) : null}

      <TouchableOpacity
        activeOpacity={0.85}
        onPress={onContinue}
        style={{ marginTop: 4 }}
      >
        <View
          style={{
            backgroundColor: '#0078D4',
            borderRadius: 14,
            paddingVertical: 14,
            alignItems: 'center',
          }}
        >
          <Text style={{ fontSize: 15, fontFamily: 'Nunito_700Bold', color: '#fff' }}>
            {t('mail.oauth.warning_continue')}
          </Text>
        </View>
      </TouchableOpacity>

      <TouchableOpacity
        activeOpacity={0.7}
        onPress={onCancel}
        style={{ marginBottom: 12, alignItems: 'center', paddingVertical: 10 }}
      >
        <Text
          style={{
            fontSize: 14,
            fontFamily: 'Nunito_600SemiBold',
            color: colors.textMuted,
          }}
        >
          {t('mail.oauth.warning_cancel')}
        </Text>
      </TouchableOpacity>
    </ScrollView>
  );
}

// ---------------------------------------------------------------------------
// Sub-View: OAuth Pending (Browser läuft gerade)
// ---------------------------------------------------------------------------

function OAuthPendingStep({
  t,
  colors,
}: {
  t: (key: string) => string;
  colors: ReturnType<typeof useColors>;
}) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', padding: 32, gap: 16 }}>
      <ActivityIndicator size="large" color="#0078D4" />
      <Text
        style={{
          fontSize: 15,
          fontFamily: 'Nunito_600SemiBold',
          color: colors.text,
          textAlign: 'center',
          lineHeight: 22,
        }}
      >
        {t('mail.oauth.pending_label')}
      </Text>
      <Text
        style={{
          fontSize: 13,
          fontFamily: 'Nunito_400Regular',
          color: colors.textMuted,
          textAlign: 'center',
          lineHeight: 19,
        }}
      >
        {t('mail.oauth.pending_hint')}
      </Text>
    </View>
  );
}

// ---------------------------------------------------------------------------
// Sub-View: Provider-Grid
// ---------------------------------------------------------------------------

function ProviderGrid({
  providers,
  onSelect,
  t,
}: {
  providers: ProviderConfig[];
  onSelect: (p: ProviderConfig) => void;
  t: (key: string) => string;
}) {
  const colors = useColors();
  return (
    <ScrollView
      style={{ flex: 1 }}
      contentContainerStyle={{ padding: 20, gap: 12 }}
      keyboardShouldPersistTaps="handled"
      showsVerticalScrollIndicator={false}
    >
      <Text
        style={{
          fontSize: 13,
          fontFamily: 'Nunito_400Regular',
          color: colors.textMuted,
          marginBottom: 4,
          lineHeight: 18,
        }}
      >
        {t('mail.connect_sheet_subtitle')}
      </Text>

      <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 10 }}>
        {providers.map((p) => (
          <TouchableOpacity
            key={p.id}
            onPress={p.disabled ? undefined : () => onSelect(p)}
            activeOpacity={p.disabled ? 1 : 0.7}
            disabled={p.disabled}
            style={{ width: '47%', opacity: p.disabled ? 0.45 : 1 }}
          >
            <View
              style={{
                flexDirection: 'row',
                alignItems: 'center',
                gap: 10,
                backgroundColor: colors.surface,
                borderWidth: 1,
                borderColor: colors.border,
                borderRadius: 14,
                padding: 14,
              }}
            >
              <View
                style={{
                  width: 36,
                  height: 36,
                  borderRadius: 10,
                  backgroundColor: p.color + '18',
                  alignItems: 'center',
                  justifyContent: 'center',
                }}
              >
                <Ionicons name={p.icon} size={18} color={p.color} />
              </View>
              <View style={{ flex: 1 }}>
                <Text
                  style={{ fontSize: 13, fontFamily: 'Nunito_700Bold', color: colors.text }}
                  numberOfLines={1}
                >
                  {t(p.labelKey)}
                </Text>
                {p.disabled && p.disabledLabelKey && (
                  <Text
                    style={{
                      fontSize: 10,
                      fontFamily: 'Nunito_600SemiBold',
                      color: '#737373',
                      marginTop: 2,
                    }}
                    numberOfLines={1}
                  >
                    {t(p.disabledLabelKey)}
                  </Text>
                )}
              </View>
              {!p.disabled && (
                <Ionicons name="chevron-forward" size={14} color={colors.border} />
              )}
            </View>
          </TouchableOpacity>
        ))}
      </View>
    </ScrollView>
  );
}
