import { useCallback, useEffect, useRef, useState } from 'react';
import { Animated, AppState, Platform, ScrollView, Text, View, Alert, ActivityIndicator, TouchableOpacity } from 'react-native';
import { useRouter } from 'expo-router';
import { useBottomTabBarHeight } from 'react-native-bottom-tabs';
import { useTranslation } from 'react-i18next';
import { Ionicons } from '@expo/vector-icons';
import { AppHeader } from '../../components/AppHeader';
import { LayerSwitchCard } from '../../components/blocker/LayerSwitchCard';
import { ProtectionLockedCard } from '../../components/blocker/ProtectionLockedCard';
import { CooldownBanner } from '../../components/blocker/CooldownBanner';
import { DomainGrid } from '../../components/blocker/DomainGrid';
import { AddDomainSheet } from '../../components/blocker/AddDomainSheet';
import { ProtectionDetailsSheet } from '../../components/blocker/ProtectionDetailsSheet';
import { DeactivationExplainerSheet } from '../../components/blocker/DeactivationExplainerSheet';
import { PermissionDeniedSheet } from '../../components/PermissionDeniedSheet';
import { ProtectionOffSheet } from '../../components/ProtectionOffSheet';
import { useProtectionState } from '../../hooks/useProtectionState';
import { useCustomDomains } from '../../hooks/useCustomDomains';
import { useBlocklistSync } from '../../hooks/useBlocklistSync';
import { useDomainSubmissionRealtime } from '../../hooks/useDomainSubmissionRealtime';
import { protection } from '../../lib/protection';
import { useColors, type ColorScheme } from '../../lib/theme';

export default function BlockerScreen() {
  const router = useRouter();
  const { t } = useTranslation();
  const colors = useColors();
  // react-native-bottom-tabs Tab-Bar ist iOS-nativ + translucent → unsere Content-View
  // erstreckt sich UNTER den Tab-Bar. Ohne diese Höhe würden FAB + Bottom-Padding
  // hinterm Tab-Bar verschwinden.
  const tabBarHeight = useBottomTabBarHeight();
  const {
    state,
    loading,
    cooldownRemainingFormatted,
    refresh,
    activateUrlFilter,
    activateFamilyControls,
    requestDeactivation,
    cancelDeactivation,
  } = useProtectionState();

  const plan = state?.plan ?? 'free';
  const {
    domains,
    tier,
    countsByType,
    limits,
    addDomain,
    submitDomain,
    refresh: refreshDomains,
  } = useCustomDomains(plan);
  const { sync: syncBlocklist } = useBlocklistSync();

  // Realtime: Domain-Submission-Status (approved/rejected/in_review) live patchen.
  const onDomainChange = useCallback(async () => {
    await refreshDomains();
    if (urlFilterActiveRef.current) {
      const sync = await syncBlocklist();
      console.log('[blocker] resync after domain change:', sync);
      await refresh();
    }
  }, [refreshDomains, syncBlocklist, refresh]);
  useDomainSubmissionRealtime(onDomainChange, true);

  const [mailOpen, setMailOpen] = useState(false);
  const [addSheetOpen, setAddSheetOpen] = useState(false);

  const [detailsOpen, setDetailsOpen] = useState(false);
  const [explainerOpen, setExplainerOpen] = useState(false);
  const [permissionDeniedOpen, setPermissionDeniedOpen] = useState(false);
  const [familyControlsErrorOpen, setFamilyControlsErrorOpen] = useState(false);
  const [protectionOffOpen, setProtectionOffOpen] = useState(false);

  const urlFilterActive = state?.layers.urlFilter === true;
  const familyControlsActive = state?.layers.familyControls === true;
  const appDeletionLockActive = (state?.layers.appDeletionLock ?? familyControlsActive) === true;
  // "lockedIn" = beide Layer aktiv: URL-Filter (echter Schutz) UND App-Lock
  // (Hardening). Family-Controls ALLEINE = kein Schutz, nur denyAppRemoval —
  // ohne URL-Filter sieht der User trotzdem Glücksspielseiten. Daher BEIDE
  // müssen an sein damit der "Schutz aktiv"-Banner gezeigt wird.
  const lockedIn = urlFilterActive && appDeletionLockActive;

  const urlFilterActiveRef = useRef(urlFilterActive);
  useEffect(() => { urlFilterActiveRef.current = urlFilterActive; }, [urlFilterActive]);

  // Auto-Sync wenn URL-Filter beim Page-Mount/-Resume schon aktiv ist.
  const syncedOnceRef = useRef(false);
  useEffect(() => {
    if (!urlFilterActive) return;
    if (syncedOnceRef.current) return;
    syncedOnceRef.current = true;
    syncBlocklist().then((res) => {
      console.log('[blocker] auto-sync on mount:', res);
      if (res.ok) refresh();
    });
  }, [urlFilterActive, syncBlocklist, refresh]);

  // Wenn User aus System-Settings zurückkommt (z.B. nach a11y-Aktivierung) → State neu laden.
  useEffect(() => {
    const sub = AppState.addEventListener('change', (next) => {
      if (next === 'active') refresh();
    });
    return () => sub.remove();
  }, [refresh]);

  // ─── Activate-Handler pro Layer ──────────────────────────────────────

  async function handleActivateUrlFilter() {
    try {
      const result = await activateUrlFilter();
      console.log('[blocker] activateUrlFilter:', result);
      if (!result.enabled) {
        // iOS-spezifisch: NEFilterErrorDomain code 5 = User hat „Nicht erlauben"
        // im System-Dialog getippt → iOS cached den Denied-State. Special-Sheet
        // statt rohem Alert (Recovery via removeFromPreferences + Settings-Deep-Link).
        const isPermissionDenied =
          Platform.OS === 'ios' &&
          typeof result.error === 'string' &&
          /NEFilterErrorDomain:\s*5/i.test(result.error);
        if (isPermissionDenied) {
          setPermissionDeniedOpen(true);
          return result;
        }
        Alert.alert(
          t('blocker.activate_url_failed_title'),
          result.error ?? t('blocker.activate_url_failed_msg'),
          [
            { text: t('common.ok') },
            { text: t('blocker.activate_settings_btn'), onPress: () => protection.openSystemSettings() },
          ],
        );
      } else {
        const sync = await syncBlocklist();
        console.log('[blocker] post-activate sync:', sync);
        if (sync.ok) {
          await refresh();
        } else {
          Alert.alert(
            t('blocker.sync_list_failed_title'),
            sync.error ?? t('blocker.sync_list_failed_msg'),
          );
        }
      }
      return result;
    } catch (e: any) {
      console.error('[blocker] activateUrlFilter threw:', e);
      Alert.alert(t('blocker.activation_failed_title'), e?.message ?? t('common.unknown_error'));
      return { enabled: false };
    }
  }

  async function handleActivateFamilyControls() {
    try {
      const result = await activateFamilyControls();
      console.log('[blocker] activateFamilyControls:', result);
      // `accessibility_pending` = a11y-Berechtigung fehlt noch → System-Settings wurden
      // geöffnet. Kein Fehler-Modal (sonst Modal-Loop bei jedem Tap).
      if (!result.enabled && result.error !== 'accessibility_pending') {
        // iOS: NSCocoaErrorDomain code 4099 = XPC-Communication-Failure zum
        // FamilyControls-Daemon (häufig nach „Don't Allow" oder bei iOS-Auth-
        // Daemon-State-Issue). Recovery-Sheet statt rohem Alert — mit Anleitung
        // (Restart Device / Settings / App reinstall).
        const isXpcFailure =
          Platform.OS === 'ios' &&
          typeof result.error === 'string' &&
          /NSCocoaErrorDomain:\s*4099/i.test(result.error);
        if (isXpcFailure) {
          setFamilyControlsErrorOpen(true);
          return result;
        }
        Alert.alert(
          t('blocker.activate_app_lock_failed_title'),
          result.error ?? t('blocker.activate_app_lock_failed_msg'),
        );
      }
      return result;
    } catch (e: any) {
      console.error('[blocker] activateFamilyControls threw:', e);
      Alert.alert(t('blocker.activation_failed_title'), e?.message ?? t('common.unknown_error'));
    }
    return { enabled: false };
  }

  // ─── 3-Click Cooldown-Trigger ────────────────────────────────────────

  function openDetails() {
    setDetailsOpen(true);
  }

  function fromDetailsToExplainer() {
    setDetailsOpen(false);
    setTimeout(() => setExplainerOpen(true), 250);
  }

  function deflectToLyra() {
    setDetailsOpen(false);
    setTimeout(() => router.push('/lyra' as any), 250);
  }

  function deflectToBreathe() {
    setExplainerOpen(false);
    setTimeout(() => router.push('/urge' as any), 250);
  }

  async function handleStartCooldown(reason: string) {
    await requestDeactivation(reason);
  }

  async function handleCancelCooldown() {
    try {
      await cancelDeactivation();
    } catch (e: any) {
      Alert.alert(t('common.error'), e?.message ?? t('blocker.deactivation_cancel_failed'));
    }
  }

  const bypassAlertShownRef = useRef(false);
  useEffect(() => {
    if (state?.phase !== 'recoveringFromBypass') {
      bypassAlertShownRef.current = false;
      return;
    }
    if (bypassAlertShownRef.current) return;
    bypassAlertShownRef.current = true;
    setProtectionOffOpen(true);
  }, [state?.phase]);

  // ─── Render ──────────────────────────────────────────────────────────

  return (
    <View className="flex-1 bg-neutral-50">
      <AppHeader />

      {loading && !state ? (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <ActivityIndicator size="large" color="#737373" />
        </View>
      ) : state ? (
        <>
          <ScrollView
            contentContainerStyle={{
              padding: 16,
              paddingBottom: tabBarHeight + 80,
              gap: 14,
            }}
            showsVerticalScrollIndicator={false}
          >
            {/* Locked-In Mode (FC aktiv) → NUR Schutz-Status + Cooldown-Pfad */}
            {lockedIn ? (
              <ProtectionLockedCard state={state} onPressSettings={openDetails} />
            ) : (
              <View style={{ gap: 10 }}>
                <LayerSwitchCard
                  icon="globe-outline"
                  title={t('blocker.layers_url_filter_title')}
                  subtitle={
                    urlFilterActive
                      ? t('blocker.layers_url_filter_subtitle_active')
                      : t('blocker.layers_url_filter_subtitle_inactive')
                  }
                  active={urlFilterActive}
                  onActivate={handleActivateUrlFilter}
                />
                {Platform.OS === 'android' ? (
                  <LayerSwitchCard
                    icon="lock-closed-outline"
                    title={t('blocker.layers_app_lock_title')}
                    subtitle={
                      state.layers.accessibility === true
                        ? t('blocker.layers_a11y_subtitle_active')
                        : t('blocker.layers_a11y_subtitle_inactive')
                    }
                    active={state.layers.accessibility === true}
                    onActivate={handleActivateFamilyControls}
                    warning={t('blocker.layers_app_lock_warning')}
                  />
                ) : (
                  <LayerSwitchCard
                    icon="lock-closed-outline"
                    title={t('blocker.layers_app_lock_title')}
                    subtitle={
                      appDeletionLockActive
                        ? t('blocker.layers_app_lock_subtitle_active')
                        : t('blocker.layers_app_lock_subtitle_inactive')
                    }
                    active={appDeletionLockActive}
                    onActivate={handleActivateFamilyControls}
                    warning={t('blocker.layers_app_lock_warning')}
                    lockedHint={t('blocker.layers_app_lock_locked_hint')}
                  />
                )}
              </View>
            )}

            {/* CooldownBanner */}
            {state.cooldown.active && (
              <CooldownBanner
                remainingFormatted={cooldownRemainingFormatted}
                onCancel={handleCancelCooldown}
              />
            )}

            {/* Free: Erwartungs-Transparenz-Hinweis */}
            {plan === 'free' && (
              <View
                style={{
                  backgroundColor: colors.surface,
                  borderRadius: 12,
                  padding: 12,
                  borderWidth: 1,
                  borderColor: colors.border,
                  flexDirection: 'row',
                  alignItems: 'flex-start',
                  gap: 8,
                }}
              >
                <Ionicons name="shield-outline" size={15} color={colors.textMuted} style={{ marginTop: 1 }} />
                <Text style={{ flex: 1, fontSize: 12, color: colors.textMuted, fontFamily: 'Nunito_400Regular', lineHeight: 17 }}>
                  {t('plan_limit.blocker_basic_protection')}
                </Text>
              </View>
            )}

            {/* Custom-Filter-Slot-Übersicht */}
            <CustomFilterOverview
              webCount={countsByType.web}
              mailCount={countsByType.mail}
              webLimit={limits.web}
              mailLimit={limits.mail}
              onAddPress={() => setAddSheetOpen(true)}
              colors={colors}
              t={t}
            />

            {/* Section 1: Eigene Domains */}
            <DomainSection
              title={t('blocker.section_domains')}
              count={countsByType.web}
              max={limits.web}
              atLimit={countsByType.web >= limits.web}
            >
              <DomainGrid
                domains={domains}
                tier={tier}
                kind="web"
                onSubmit={submitDomain}
                onUpgradePro={() => Alert.alert(t('blocker.upgrade_alert_title'), t('blocker.upgrade_alert_desc'))}
              />
            </DomainSection>

            {/* Section 2: Eigene Mails */}
            <DomainSection
              title={t('blocker.section_mails')}
              count={countsByType.mail}
              max={limits.mail}
              collapsible
              open={mailOpen}
              onToggle={() => setMailOpen((v) => !v)}
              atLimit={countsByType.mail >= limits.mail}
            >
              <DomainGrid
                domains={domains}
                tier={tier}
                kind="mail"
                onSubmit={submitDomain}
                onUpgradePro={() => Alert.alert(t('blocker.upgrade_alert_title'), t('blocker.upgrade_alert_desc'))}
              />
            </DomainSection>
          </ScrollView>

          {/* Sheets */}
          <AddDomainSheet
            visible={addSheetOpen}
            tier={tier}
            onClose={() => {
              setAddSheetOpen(false);
              refreshDomains();
            }}
            onAdd={async (pattern, kind) => {
              const result = await addDomain(pattern, kind);
              if (result.ok) {
                const sync = await syncBlocklist();
                if (sync.ok) refresh();
              }
              return result;
            }}
          />

          <ProtectionDetailsSheet
            visible={detailsOpen}
            state={state}
            onClose={() => setDetailsOpen(false)}
            onRequestDeactivation={fromDetailsToExplainer}
            onTalkToLyra={deflectToLyra}
          />

          <DeactivationExplainerSheet
            visible={explainerOpen}
            onClose={() => setExplainerOpen(false)}
            onBreathe={deflectToBreathe}
            onStartCooldown={handleStartCooldown}
          />

          <PermissionDeniedSheet
            visible={permissionDeniedOpen}
            onClose={() => setPermissionDeniedOpen(false)}
            onRetry={async () => {
              const res = await protection.resetUrlFilter();
              if (res.enabled) {
                await refresh();
              }
              return res;
            }}
          />

          <PermissionDeniedSheet
            visible={familyControlsErrorOpen}
            onClose={() => setFamilyControlsErrorOpen(false)}
            variant="family_controls"
            onRetry={async () => {
              const res = await protection.activateFamilyControls();
              if (res.enabled) {
                await refresh();
              }
              return res;
            }}
          />

          <ProtectionOffSheet
            visible={protectionOffOpen}
            onClose={() => setProtectionOffOpen(false)}
            onReactivate={() => handleActivateUrlFilter()}
          />
        </>
      ) : null}
    </View>
  );
}

// ─── CustomFilterOverview ─────────────────────────────────────────────────────

function CustomFilterOverview({
  webCount,
  mailCount,
  webLimit,
  mailLimit,
  onAddPress,
  colors,
  t,
}: {
  webCount: number;
  mailCount: number;
  webLimit: number;
  mailLimit: number;
  onAddPress: () => void;
  colors: ColorScheme;
  t: (key: string, opts?: Record<string, unknown>) => string;
}) {
  const total = webCount + mailCount;
  const max = webLimit + mailLimit;
  const webFillAnim = useRef(new Animated.Value(0)).current;
  const mailFillAnim = useRef(new Animated.Value(0)).current;

  const webRatio = max > 0 ? Math.min(webCount / max, 1) : 0;
  const mailRatio = max > 0 ? Math.min(mailCount / max, 1) : 0;

  useEffect(() => {
    Animated.parallel([
      Animated.timing(webFillAnim, { toValue: webRatio, duration: 380, useNativeDriver: false }),
      Animated.timing(mailFillAnim, { toValue: mailRatio, duration: 380, useNativeDriver: false }),
    ]).start();
  }, [webRatio, mailRatio]);

  return (
    <View
      style={{
        backgroundColor: colors.surface,
        borderRadius: 16,
        borderWidth: 1,
        borderColor: colors.border,
        paddingHorizontal: 14,
        paddingVertical: 10,
        gap: 8,
      }}
    >
      {/* Top row: title + legend on left, count badge + add button on right */}
      <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
        <Text style={{ fontSize: 14, fontFamily: 'Nunito_700Bold', color: colors.text }}>
          {t('blocker.custom_filter_overview_title')}
        </Text>
        <View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
          <View style={{ width: 6, height: 6, borderRadius: 3, backgroundColor: colors.brandOrange }} />
          <Text style={{ fontSize: 11, fontFamily: 'Nunito_400Regular', color: colors.textMuted }}>
            {webCount} Web
          </Text>
        </View>
        <View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
          <View style={{ width: 6, height: 6, borderRadius: 3, backgroundColor: colors.success }} />
          <Text style={{ fontSize: 11, fontFamily: 'Nunito_400Regular', color: colors.textMuted }}>
            {mailCount} Mail
          </Text>
        </View>
        <View style={{ flex: 1 }} />
        <View
          style={{
            paddingHorizontal: 8,
            paddingVertical: 3,
            borderRadius: 999,
            backgroundColor: colors.surfaceElevated,
          }}
        >
          <Text style={{ fontSize: 11, fontFamily: 'Nunito_600SemiBold', color: colors.textMuted }}>
            {t('blocker.custom_filter_overview_count', { count: total, max })}
          </Text>
        </View>
        <TouchableOpacity
          onPress={onAddPress}
          activeOpacity={0.85}
          style={{
            width: 28,
            height: 28,
            borderRadius: 14,
            backgroundColor: colors.brandOrange,
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <Ionicons name="add" size={18} color="#fff" />
        </TouchableOpacity>
      </View>

      {/* Split progress bar — same height/pattern as DomainSection */}
      <View
        style={{
          height: 5,
          borderRadius: 3,
          backgroundColor: colors.surfaceElevated,
          flexDirection: 'row',
          overflow: 'hidden',
        }}
      >
        <Animated.View
          style={{
            height: '100%',
            backgroundColor: colors.brandOrange,
            width: webFillAnim.interpolate({ inputRange: [0, 1], outputRange: ['0%', '100%'] }),
          }}
        />
        <Animated.View
          style={{
            height: '100%',
            backgroundColor: colors.success,
            width: mailFillAnim.interpolate({ inputRange: [0, 1], outputRange: ['0%', '100%'] }),
          }}
        />
      </View>
    </View>
  );
}

// ─── DomainSection ────────────────────────────────────────────────────────────

function DomainSection({
  title,
  count,
  max,
  collapsible = false,
  open = true,
  onToggle,
  atLimit,
  children,
}: {
  title: string;
  count: number;
  max: number;
  collapsible?: boolean;
  open?: boolean;
  onToggle?: () => void;
  atLimit: boolean;
  children: React.ReactNode;
}) {
  const { t } = useTranslation();
  const colors = useColors();

  const fillAnim = useRef(new Animated.Value(0)).current;
  const ratio = max > 0 ? Math.min(count / max, 1) : 0;

  useEffect(() => {
    Animated.timing(fillAnim, {
      toValue: ratio,
      duration: 380,
      useNativeDriver: false,
    }).start();
  }, [ratio]);

  const pct = ratio * 100;
  const barColor = pct >= 90 ? '#dc2626' : pct >= 60 ? '#f59e0b' : '#16a34a';

  const badgeBg = atLimit ? '#fee2e2' : colors.surfaceElevated;
  const badgeFg = atLimit ? '#dc2626' : colors.textMuted;

  return (
    <View
      style={{
        backgroundColor: colors.surface,
        borderRadius: 16,
        borderWidth: 1,
        borderColor: colors.border,
        overflow: 'hidden',
      }}
    >
      {/* Section Header */}
      <TouchableOpacity
        onPress={collapsible ? onToggle : undefined}
        activeOpacity={collapsible ? 0.7 : 1}
        style={{
          flexDirection: 'row',
          alignItems: 'center',
          paddingHorizontal: 14,
          paddingVertical: 12,
          gap: 8,
        }}
      >
        <Text style={{ flex: 1, fontSize: 14, fontFamily: 'Nunito_700Bold', color: colors.text }}>
          {title}
        </Text>
        <View
          style={{
            paddingHorizontal: 8,
            paddingVertical: 3,
            borderRadius: 999,
            backgroundColor: badgeBg,
          }}
        >
          <Text style={{ fontSize: 11, fontFamily: 'Nunito_600SemiBold', color: badgeFg }}>
            {t('blocker.count_label', { count, max })}
          </Text>
        </View>
        {collapsible && (
          <Ionicons
            name={open ? 'chevron-up' : 'chevron-down'}
            size={16}
            color={colors.textMuted}
          />
        )}
      </TouchableOpacity>

      {(!collapsible || open) && (
        <View style={{ paddingHorizontal: 14, paddingBottom: 14, gap: 12 }}>
          {/* Progressbar */}
          <View
            style={{
              height: 5,
              borderRadius: 3,
              backgroundColor: colors.surfaceElevated,
              overflow: 'hidden',
            }}
          >
            <Animated.View
              style={{
                height: '100%',
                borderRadius: 3,
                backgroundColor: barColor,
                width: fillAnim.interpolate({
                  inputRange: [0, 1],
                  outputRange: ['0%', '100%'],
                }),
              }}
            />
          </View>

          {/* Grid */}
          {children}
        </View>
      )}
    </View>
  );
}
