import { useCallback, useEffect, useRef, useState } from 'react';
import { View, ActivityIndicator, AppState, Platform } from 'react-native';
import { useRouter } from 'expo-router';
import * as Notifications from 'expo-notifications';
import { useTranslation } from 'react-i18next';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useAuthStore } from '../../stores/auth';
import { useNotificationStore } from '../../stores/notifications';
import { useMailConsentStore } from '../../stores/mailConsent';
import { useColors } from '../../lib/theme';
import { NativeTabs } from '../../components/NativeTabs';
import { MailConsentReminderSheet } from '../../components/mail/MailConsentReminderSheet';
import { ProtectionOnboardingSheet } from '../../components/ProtectionOnboardingSheet';
import { protection } from '../../lib/protection';
import { preloadTabIcons, getTabIcon } from '../../lib/tabIcons';
import { apiFetch } from '../../lib/api';
import { useQuery } from '@tanstack/react-query';
import { useMe } from '../../hooks/useMe';

const ONBOARDING_COMPLETED_KEY = '@rebreak/protection-onboarding-completed';

type DmConvUnreadSlice = { unreadCount?: number };

export default function AppLayout() {
  const router = useRouter();
  const { t } = useTranslation();
  const { session, loading } = useAuthStore();
  const colors = useColors();
  const loadNotifications = useNotificationStore((s) => s.load);
  const startRealtime = useNotificationStore((s) => s.startRealtime);
  const stopRealtime = useNotificationStore((s) => s.stopRealtime);
  const resetNotifications = useNotificationStore((s) => s.reset);
  const { visible: consentVisible, connections: consentConnections, show: showConsent, hide: hideConsent, markConsented } = useMailConsentStore();
  const rearmInFlightRef = useRef(false);
  const bypassNotifiedRef = useRef(false);

  // Android-only: Onboarding-Sheet bis beide Layer eingerichtet sind
  const [onboardingVisible, setOnboardingVisible] = useState(false);

  const checkAndShowOnboarding = useCallback(async () => {
    if (Platform.OS !== 'android') return;
    const completed = await AsyncStorage.getItem(ONBOARDING_COMPLETED_KEY);
    if (completed === '1') return;
    const layers = await protection.getDeviceState().catch(() => null);
    if (!layers) return;
    const vpnActive = layers.vpn === true;
    const a11yActive = layers.accessibility === true;
    if (vpnActive && a11yActive) {
      await AsyncStorage.setItem(ONBOARDING_COMPLETED_KEY, '1');
      return;
    }
    setOnboardingVisible(true);
  }, []);

  useEffect(() => {
    if (!session || Platform.OS !== 'android') return;
    checkAndShowOnboarding();
    const sub = AppState.addEventListener('change', (next) => {
      if (next === 'active') checkAndShowOnboarding();
    });
    return () => sub.remove();
  }, [session, checkAndShowOnboarding]);

  async function handleOnboardingComplete() {
    await AsyncStorage.setItem(ONBOARDING_COMPLETED_KEY, '1');
    setOnboardingVisible(false);
  }

  function handleOnboardingSkip() {
    setOnboardingVisible(false);
  }

  // Unread DMs → badge on the Chat tab. Same query key chat.tsx uses, so
  // React Query dedupes (no double fetch when both layouts mount).
  const { data: dmConvs = [] } = useQuery<DmConvUnreadSlice[]>({
    queryKey: ['dm-conversations'],
    queryFn: () => apiFetch('/api/chat/dm-conversations'),
    staleTime: 30_000,
    enabled: !!session,
  });
  const unreadDms = dmConvs.reduce((sum, c) => sum + (c.unreadCount ?? 0), 0);
  const chatBadge = unreadDms > 0 ? (unreadDms > 99 ? '99+' : String(unreadDms)) : undefined;

  // Android-Tab-Icons müssen async aus Ionicons-Font generiert werden (kein
  // SF-Symbol-Support). preloadTabIcons() läuft schon beim Modul-Import — hier
  // nur den ready-State tracken damit wir re-rendern wenn der Cache fertig ist.
  const [tabIconsReady, setTabIconsReady] = useState(Platform.OS !== 'android');
  useEffect(() => {
    if (Platform.OS === 'android' && !tabIconsReady) {
      preloadTabIcons().then(() => setTabIconsReady(true));
    }
  }, [tabIconsReady]);

  useEffect(() => {
    if (!loading && !session) {
      router.replace('/signin');
    }
  }, [session, loading]);

  // Onboarding-Routing-Gate (resume-on-relaunch via DB-State).
  // Aktuell nur Welcome-Branch — Nickname/Block/Pricing/DiGA-Stages werden im
  // kommenden Duo-Style Onboarding alle INNERHALB von /onboarding/* gehandhabt,
  // brauchen also keinen Re-Direct von (app) aus.
  const { me } = useMe();
  useEffect(() => {
    if (!session || !me) return;
    if (me.onboardingStep !== 'done') {
      router.replace('/onboarding');
    }
  }, [session, me?.onboardingStep]);

  useEffect(() => {
    if (!session) {
      resetNotifications();
      return;
    }
    loadNotifications();
    startRealtime();
    return () => {
      stopRealtime();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [session?.user?.id]);

  useEffect(() => {
    if (!session) return;
    apiFetch<{ id: string; email: string }[]>('/api/mail-connections/pending-consent')
      .then((pending) => {
        if (pending.length > 0) {
          showConsent(pending);
        }
      })
      .catch(() => {});
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [session?.user?.id]);

  useEffect(() => {
    if (!session || Platform.OS !== 'ios') return;

    let cancelled = false;
    let pollTimer: ReturnType<typeof setInterval> | null = null;

    async function notifyBypassDetected(): Promise<boolean> {
      const perms = await Notifications.getPermissionsAsync();
      let granted = perms.granted || perms.ios?.status === Notifications.IosAuthorizationStatus.PROVISIONAL;
      if (!granted) {
        const req = await Notifications.requestPermissionsAsync();
        granted = req.granted || req.ios?.status === Notifications.IosAuthorizationStatus.PROVISIONAL;
      }
      if (!granted) return false;

      await Notifications.scheduleNotificationAsync({
        content: {
          title: 'ReBreak Schutz manipuliert',
          body: 'Tippe hier, um den Schutz sofort wieder zu aktivieren.',
          sound: 'default',
          data: { type: 'protection_bypass_detected' },
        },
        trigger: null,
      });
      return true;
    }

    async function enforceProtection() {
      if (cancelled || rearmInFlightRef.current) return;
      try {
        // Self-Heal: wenn der Schutz an sein soll der VpnService aber tot ist
        // (Reinstall / OS-Kill) → neu starten, bevor wir den State lesen.
        await protection.reconcileVpn();
        if (cancelled) return;
        const state = await protection.getCombinedState();
        if (cancelled) return;
        if (state.phase !== 'recoveringFromBypass') {
          bypassNotifiedRef.current = false;
          return;
        }
        if (bypassNotifiedRef.current) return;

        bypassNotifiedRef.current = true;
        const notified = await notifyBypassDetected();
        if (!notified) {
          // Fallback wenn Notifications nicht erlaubt sind. Reaktivierung setzt
          // NUR den Filter/VPN wieder — kein a11y-Prompt (das passiert nur beim
          // ersten Einrichten).
          rearmInFlightRef.current = true;
          router.replace('/blocker');
          await protection.activate().catch(() => null);
        }
      } finally {
        rearmInFlightRef.current = false;
      }
    }

    async function onBypassNotificationTap() {
      if (rearmInFlightRef.current) return;
      rearmInFlightRef.current = true;
      try {
        router.replace('/blocker');
        // Reaktivierung = nur Filter/VPN wieder setzen (a11y nur beim ersten Mal).
        await protection.activate().catch(() => null);
      } finally {
        rearmInFlightRef.current = false;
      }
    }

    // Initial check + foreground re-check + periodisches Polling als Fallback.
    enforceProtection();
    const notifTapSub = Notifications.addNotificationResponseReceivedListener((response) => {
      const type = response.notification.request.content.data?.type;
      if (type === 'protection_bypass_detected') {
        void onBypassNotificationTap();
      }
    });
    Notifications.getLastNotificationResponseAsync().then((response) => {
      const type = response?.notification.request.content.data?.type;
      if (type === 'protection_bypass_detected') {
        void onBypassNotificationTap();
      }
    });
    const appStateSub = AppState.addEventListener('change', (s) => {
      if (s === 'active') {
        enforceProtection();
      }
    });
    pollTimer = setInterval(enforceProtection, 15000);

    return () => {
      cancelled = true;
      notifTapSub.remove();
      appStateSub.remove();
      if (pollTimer) clearInterval(pollTimer);
    };
  }, [session, router]);

  if (loading || !session) {
    return (
      <View style={{ flex: 1, backgroundColor: colors.bg, alignItems: 'center', justifyContent: 'center' }}>
        <ActivityIndicator color={colors.brandOrange} size="large" />
      </View>
    );
  }

  return (
    <>
    {consentVisible && (
      <MailConsentReminderSheet
        connections={consentConnections}
        onDismiss={hideConsent}
        onConsented={markConsented}
      />
    )}
    {Platform.OS === 'android' && (
      <ProtectionOnboardingSheet
        visible={onboardingVisible}
        onComplete={handleOnboardingComplete}
        onSkip={handleOnboardingSkip}
      />
    )}
    <NativeTabs
      sidebarAdaptable
      hapticFeedbackEnabled
      tabBarActiveTintColor={colors.brandOrange}
      tabBarInactiveTintColor="#d1d1d6"
      scrollEdgeAppearance="default"
      tabLabelStyle={{
        fontFamily: 'Nunito_600SemiBold',
        fontSize: 11,
      }}
    >
      <NativeTabs.Screen
        name="index"
        options={{
          title: t('tabs.home'),
          tabBarIcon: () =>
            Platform.OS === 'ios'
              ? { sfSymbol: 'house.fill' }
              : (getTabIcon('home') as any),
        }}
      />
      <NativeTabs.Screen
        name="chat"
        options={{
          title: t('tabs.chat'),
          tabBarBadge: chatBadge,
          tabBarIcon: () =>
            Platform.OS === 'ios'
              ? { sfSymbol: 'bubble.left.and.bubble.right.fill' }
              : (getTabIcon('chat') as any),
        }}
      />
      <NativeTabs.Screen
        name="coach"
        options={{
          title: t('tabs.coach'),
          tabBarIcon: () =>
            Platform.OS === 'ios'
              ? { sfSymbol: 'sparkles' }
              : (getTabIcon('coach') as any),
        }}
      />
      <NativeTabs.Screen
        name="blocker"
        options={{
          title: t('tabs.blocker'),
          tabBarIcon: () =>
            Platform.OS === 'ios'
              ? { sfSymbol: 'checkmark.shield.fill' }
              : (getTabIcon('blocker') as any),
        }}
      />
      <NativeTabs.Screen
        name="mail"
        options={{
          title: t('tabs.mail'),
          tabBarIcon: () =>
            Platform.OS === 'ios'
              ? { sfSymbol: 'envelope.fill' }
              : (getTabIcon('mail') as any),
        }}
      />
      <NativeTabs.Screen name="notifications" options={{ href: null }} />
    </NativeTabs>
    </>
  );
}
