import { useCallback, useEffect, useRef, useState } from 'react';
import { ScrollView, View, Alert, ActivityIndicator } from 'react-native';
import { useRouter } from 'expo-router';
import { useBottomTabBarHeight } from 'react-native-bottom-tabs';
import { useTranslation } from 'react-i18next';
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 { useProtectionState } from '../../hooks/useProtectionState';
import { useCustomDomains } from '../../hooks/useCustomDomains';
import { useBlocklistSync } from '../../hooks/useBlocklistSync';
import { useDomainSubmissionRealtime } from '../../hooks/useDomainSubmissionRealtime';
import { protection } from '../../lib/protection';

export default function BlockerScreen() {
  const router = useRouter();
  const { t } = useTranslation();
  // 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,
    addDomain,
    submitDomain,
    refresh: refreshDomains,
  } = useCustomDomains(plan);
  const { sync: syncBlocklist } = useBlocklistSync();

  // Realtime: Domain-Submission-Status (approved/rejected/in_review) live patchen.
  // Bei domain_rejected wird die Row backend-seitig hard-deleted → refetch
  // entfernt sie aus der Liste. Zusätzlich blocklist.bin neu syncen damit
  // die lokale Hash-Liste nicht aus dem Tritt gerät.
  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);

  // Sheet-States
  const [addSheetOpen, setAddSheetOpen] = useState(false);
  const [detailsOpen, setDetailsOpen] = useState(false);
  const [explainerOpen, setExplainerOpen] = useState(false);

  // Layer-Status (auf iOS): urlFilter + familyControls.
  // AppDeletionLock=true bedeutet "locked in" → keine Switches mehr, nur Cooldown-Pfad.
  const urlFilterActive = state?.layers.urlFilter === true;
  const familyControlsActive = state?.layers.familyControls === true;
  const appDeletionLockActive = (state?.layers.appDeletionLock ?? familyControlsActive) === true;
  const lockedIn = appDeletionLockActive;

  // Ref damit onDomainChange nicht neu rendert bei jedem urlFilter-Toggle
  const urlFilterActiveRef = useRef(urlFilterActive);
  useEffect(() => { urlFilterActiveRef.current = urlFilterActive; }, [urlFilterActive]);

  // Auto-Sync wenn URL-Filter beim Page-Mount/-Resume schon aktiv ist und
  // blocklist.bin leer/stale sein könnte. Dedupe via Ref damit wir nicht
  // bei jedem Re-Render neu syncen.
  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();  // Stats-Card neu rendern mit aktuellem Count
    });
  }, [urlFilterActive, syncBlocklist, refresh]);

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

  async function handleActivateUrlFilter() {
    try {
      const result = await activateUrlFilter();
      console.log('[blocker] activateUrlFilter:', result);
      if (!result.enabled) {
        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 {
        // Filter ist aktiv aber blocklist.bin ist initial leer — sofort syncen!
        // Sonst zeigt iOS "Läuft" aber blockt nichts.
        const sync = await syncBlocklist();
        console.log('[blocker] post-activate sync:', sync);
        if (sync.ok) {
          // Stats-Card neu rendern mit dem frisch geschriebenen Count
          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);
      if (!result.enabled) {
        Alert.alert(
          t('blocker.activate_app_lock_failed_title'),
          result.error ?? t('blocker.activate_app_lock_failed_msg'),
        );
      }
    } 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;
    Alert.alert(
      t('blocker.activate_app_lock_failed_title'),
      t('blocker.layers_app_lock_warning'),
      [{
        text: t('common.ok'),
        onPress: () => {
          void handleActivateFamilyControls();
        },
      }],
      { cancelable: false },
    );
  }, [state?.phase, t]);

  // ─── 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, // platz für FAB + Tab-Bar
              gap: 14,
            }}
            showsVerticalScrollIndicator={false}
          >
            {/* Locked-In Mode (FC aktiv) → NUR Schutz-Status + Cooldown-Pfad */}
            {lockedIn ? (
              <ProtectionLockedCard state={state} onPressSettings={openDetails} />
            ) : (
              // FC nicht aktiv → User kann pro Layer einzeln togglen
              <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}
                />
                <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')}
                />
              </View>
            )}

            {/* CooldownBanner — nur wenn Cooldown läuft */}
            {state.cooldown.active && (
              <CooldownBanner
                remainingFormatted={cooldownRemainingFormatted}
                onCancel={handleCancelCooldown}
              />
            )}

            {/* Domain Grid mit inline + Button neben SlotPill */}
            <View style={{ marginTop: 8 }}>
              <DomainGrid
                domains={domains}
                tier={tier}
                onAdd={() => setAddSheetOpen(true)}
                onSubmit={submitDomain}
                onUpgradePro={() => Alert.alert(t('blocker.upgrade_alert_title'), t('blocker.upgrade_alert_desc'))}
              />
            </View>
          </ScrollView>

          {/* Sheets */}
          <AddDomainSheet
            visible={addSheetOpen}
            tier={tier}
            onClose={() => {
              setAddSheetOpen(false);
              refreshDomains();
            }}
            onAdd={async (d) => {
              const result = await addDomain(d);
              if (result.ok) {
                // Neue Custom-Domain → Filter muss aktualisierten Hash-Set kriegen
                const sync = await syncBlocklist();
                if (sync.ok) refresh();  // Stats-Card mit neuem Count refreshen
              }
              return result;
            }}
          />

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

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