import { useEffect, useRef, useState } from 'react';
import { Alert, AppState, Image, Platform, Text, useWindowDimensions, View } from 'react-native';
import { useTranslation } from 'react-i18next';
import { useColors } from '../../../lib/theme';
import { apiFetch } from '../../../lib/api';
import { invalidateMe } from '../../../hooks/useMe';
import { protection } from '../../../lib/protection';
import RebreakProtection from '../../../modules/rebreak-protection';
import { getPermissionScreenshot } from '../../../lib/onboardingAssets';
import { OnboardingShell } from '../OnboardingShell';
import { LyraBubble } from '../LyraBubble';
import { CTABar } from '../CTABar';
import { ScreenshotPointer } from '../ScreenshotPointer';
import { PermissionDeniedSheet } from '../../PermissionDeniedSheet';
import i18n from '../../../lib/i18n';

/**
 * Onboarding-Schutz-Step.
 *
 * Platform.OS-Dispatch:
 *   iOS     → IosProtectionSlide   (NEFilter + Family-Controls)
 *   Android → AndroidProtectionSlide (VpnService + Accessibility-Tamper-Lock)
 *
 * Beide haben den gleichen Eltern-Vertrag (current/total/onDone) und nutzen
 * den gleichen Pre-Explainer + Lyra-Bubble + CTA-Pattern — die Innereien
 * unterscheiden sich nur in (a) welche Permission-Dialoge geöffnet werden
 * und (b) welche Screenshots gezeigt werden.
 */

export function ProtectionSlide(props: {
  onDone: () => void;
  current: number;
  total: number;
}) {
  if (Platform.OS === 'android') {
    return <AndroidProtectionSlide {...props} />;
  }
  return <IosProtectionSlide {...props} />;
}

// ─── iOS ────────────────────────────────────────────────────────────────────

type IosPhase = 'preexplain_url' | 'preexplain_lock' | 'done';

function IosProtectionSlide({
  onDone,
  current,
  total,
}: {
  onDone: () => void;
  current: number;
  total: number;
}) {
  const { t } = useTranslation();
  const [phase, setPhase] = useState<IosPhase>('preexplain_url');
  const [activating, setActivating] = useState(false);
  const [permissionDeniedOpen, setPermissionDeniedOpen] = useState(false);
  const [familyControlsErrorOpen, setFamilyControlsErrorOpen] = useState(false);

  async function activateUrlFilter() {
    if (activating) return;
    setActivating(true);
    try {
      const res = await protection.activateUrlFilter();
      if (!res.enabled) {
        const isCodeFive =
          typeof res.error === 'string' &&
          /NEFilterErrorDomain:\s*5/i.test(res.error);
        if (isCodeFive) {
          setPermissionDeniedOpen(true);
          return;
        }
        Alert.alert(
          t('onboarding.protection.error_title'),
          res.error ?? t('onboarding.protection.error_unknown'),
        );
        return;
      }
      setPhase('preexplain_lock');
    } finally {
      setActivating(false);
    }
  }

  async function activateAppLock() {
    if (activating) return;
    setActivating(true);
    try {
      const res = await protection.activateFamilyControls();
      if (!res.enabled) {
        // iOS NSCocoaErrorDomain:4099 = XPC-Communication-Failure (FamilyControls-Daemon
        // nicht erreichbar). Recovery-Sheet statt Alert-Loop — gibt User klare Anleitung
        // (Reboot/Settings/Reinstall) statt nur einen "Skip"-Button.
        const isXpcFailure =
          typeof res.error === 'string' && /NSCocoaErrorDomain:\s*4099/i.test(res.error);
        if (isXpcFailure) {
          setFamilyControlsErrorOpen(true);
          return;
        }
        Alert.alert(
          t('onboarding.protection.applock_failed_title'),
          res.error ?? t('onboarding.protection.applock_failed_msg'),
          [
            {
              text: t('onboarding.protection.applock_skip'),
              style: 'cancel',
              onPress: () => finishProtectionStep(),
            },
            { text: t('common.retry'), onPress: activateAppLock },
          ],
        );
        return;
      }
      finishProtectionStep();
    } finally {
      setActivating(false);
    }
  }

  async function finishProtectionStep() {
    await apiFetch('/api/profile/me/onboarding-step', {
      method: 'PATCH',
      body: { step: 'done' },
    }).catch(() => {});
    invalidateMe();
    setPhase('done');
    onDone();
  }

  if (phase === 'preexplain_url') {
    return (
      <PreExplainer
        key="ios-url"
        dialog="url_filter"
        lyraBodyKey="onboarding.lyra.protection_url.body"
        titleKey="onboarding.protection.url_title"
        ctaKey="onboarding.protection.cta_primary"
        buttonLabelKey="onboarding.protection.dialog_button_allow"
        markerHintKey="onboarding.protection.tap_marker_hint"
        activating={activating}
        onActivate={activateUrlFilter}
        current={current}
        total={total}
      >
        <PermissionDeniedSheet
          visible={permissionDeniedOpen}
          onClose={() => setPermissionDeniedOpen(false)}
          onRetry={async () => {
            const res = await protection.resetUrlFilter();
            if (res.enabled) setPhase('preexplain_lock');
            return res;
          }}
        />
      </PreExplainer>
    );
  }
  if (phase === 'preexplain_lock') {
    return (
      <PreExplainer
        key="ios-lock"
        dialog="screen_time"
        lyraBodyKey="onboarding.lyra.protection_lock.body"
        titleKey="onboarding.protection.lock_title"
        ctaKey="onboarding.protection.cta_primary"
        buttonLabelKey="onboarding.protection.dialog_button_continue"
        markerHintKey="onboarding.protection.tap_marker_hint"
        pointerAlignment="left"
        activating={activating}
        onActivate={activateAppLock}
        current={current}
        total={total}
      >
        <PermissionDeniedSheet
          visible={familyControlsErrorOpen}
          onClose={() => setFamilyControlsErrorOpen(false)}
          variant="family_controls"
          onRetry={async () => {
            const res = await protection.activateFamilyControls();
            if (res.enabled) {
              finishProtectionStep();
            }
            return res;
          }}
        />
      </PreExplainer>
    );
  }
  return null;
}

// ─── Android ────────────────────────────────────────────────────────────────

type AndroidPhase =
  | 'preexplain_vpn'
  | 'preexplain_a11y'
  | 'a11y_pending'
  | 'done';

function AndroidProtectionSlide({
  onDone,
  current,
  total,
}: {
  onDone: () => void;
  current: number;
  total: number;
}) {
  const { t } = useTranslation();
  const [phase, setPhase] = useState<AndroidPhase>('preexplain_vpn');
  const [activating, setActivating] = useState(false);
  // True wenn wir auf Settings-Rückkehr warten. AppState-Listener pollt dann
  // a11y-State + advanced automatisch wenn ReBreak-Schalter live ist.
  const awaitingReturnRef = useRef(false);
  const appStateRef = useRef(AppState.currentState);

  async function finishProtectionStep() {
    await apiFetch('/api/profile/me/onboarding-step', {
      method: 'PATCH',
      body: { step: 'done' },
    }).catch(() => {});
    invalidateMe();
    setPhase('done');
    onDone();
  }

  async function activateVpn() {
    if (activating) return;
    setActivating(true);
    try {
      const res = await protection.activateUrlFilter();
      if (!res.enabled) {
        Alert.alert(
          t('onboarding.protection.error_title'),
          res.error ?? t('onboarding.protection.error_unknown'),
        );
        return;
      }
      setPhase('preexplain_a11y');
    } finally {
      setActivating(false);
    }
  }

  async function activateA11y() {
    if (activating) return;
    setActivating(true);
    try {
      const res = await protection.activateFamilyControls();
      if (res.enabled) {
        // Selten: User hatte a11y schon manuell aktiviert → Lock direkt armed.
        finishProtectionStep();
        return;
      }
      if (res.error === 'accessibility_pending') {
        // Native hat Settings geöffnet; warte auf Rückkehr + poll.
        awaitingReturnRef.current = true;
        setPhase('a11y_pending');
        return;
      }
      Alert.alert(
        t('onboarding.protection.error_title'),
        res.error ?? t('onboarding.protection.error_unknown'),
      );
    } finally {
      setActivating(false);
    }
  }

  // Auto-Check beim Foreground-Return: wenn a11y jetzt aktiv → Lock armen + done.
  useEffect(() => {
    const sub = AppState.addEventListener('change', async (next) => {
      const prev = appStateRef.current;
      appStateRef.current = next;
      if (!awaitingReturnRef.current) return;
      if (prev.match(/inactive|background/) && next === 'active') {
        try {
          const a11y = await RebreakProtection.isAccessibilityEnabled();
          if (a11y.enabled) {
            // ReBreak-Service ist live → Tamper-Lock armen + finish.
            const res = await protection.activateFamilyControls();
            if (res.enabled) {
              awaitingReturnRef.current = false;
              finishProtectionStep();
            }
          }
        } catch {
          // Ignorieren — User kann manuell auf "Ich habe ReBreak aktiviert" tippen.
        }
      }
    });
    return () => sub.remove();
  }, []);

  if (phase === 'preexplain_vpn') {
    return (
      <PreExplainer
        key="android-vpn"
        dialog="android_vpn"
        lyraBodyKey="onboarding.lyra.protection_url_android.body"
        titleKey="onboarding.protection.url_title_android"
        ctaKey="onboarding.protection.cta_primary"
        buttonLabelKey="onboarding.protection.dialog_button_vpn_ok"
        markerHintKey="onboarding.protection.tap_marker_hint_android_vpn"
        activating={activating}
        onActivate={activateVpn}
        current={current}
        total={total}
      />
    );
  }
  if (phase === 'preexplain_a11y') {
    return (
      <PreExplainer
        key="android-a11y"
        dialog="android_a11y"
        lyraBodyKey="onboarding.lyra.protection_lock_android.body"
        titleKey="onboarding.protection.lock_title_android"
        ctaKey="onboarding.protection.cta_open_a11y"
        buttonLabelKey="onboarding.protection.dialog_button_a11y_toggle"
        markerHintKey="onboarding.protection.tap_marker_hint_android_a11y"
        activating={activating}
        onActivate={activateA11y}
        current={current}
        total={total}
      />
    );
  }
  if (phase === 'a11y_pending') {
    return (
      <A11yPendingView
        current={current}
        total={total}
        activating={activating}
        onRetry={activateA11y}
      />
    );
  }
  return null;
}

function A11yPendingView({
  current,
  total,
  activating,
  onRetry,
}: {
  current: number;
  total: number;
  activating: boolean;
  onRetry: () => void;
}) {
  const { t } = useTranslation();
  const colors = useColors();
  return (
    <OnboardingShell
      current={current}
      total={total}
      cta={
        <CTABar
          primaryLabel={t('onboarding.protection.cta_check_a11y')}
          onPrimary={onRetry}
          primaryLoading={activating}
        />
      }
    >
      <LyraBubble
        text={t('onboarding.protection.android_a11y_pending_body')}
        emotion="empathy"
      />
      <Text
        style={{
          marginTop: 14,
          fontFamily: 'Nunito_700Bold',
          fontSize: 12,
          letterSpacing: 0.6,
          color: colors.textMuted,
          textTransform: 'uppercase',
          textAlign: 'center',
        }}
      >
        {t('onboarding.protection.android_a11y_pending_title')}
      </Text>
    </OnboardingShell>
  );
}

// ─── PreExplainer (shared) ───────────────────────────────────────────────────

function PreExplainer({
  dialog,
  lyraBodyKey,
  titleKey,
  ctaKey,
  buttonLabelKey,
  markerHintKey,
  pointerAlignment = 'center',
  activating,
  onActivate,
  current,
  total,
  children,
}: {
  dialog: 'url_filter' | 'screen_time' | 'android_vpn' | 'android_a11y';
  lyraBodyKey: string;
  titleKey: string;
  ctaKey: string;
  buttonLabelKey: string;
  markerHintKey: string;
  pointerAlignment?: 'left' | 'center' | 'right';
  activating: boolean;
  onActivate: () => void;
  current: number;
  total: number;
  children?: React.ReactNode;
}) {
  const { t } = useTranslation();
  const colors = useColors();
  const { height: screenH } = useWindowDimensions();
  const lang = i18n.language || 'de';
  const screenshot = getPermissionScreenshot(dialog, lang);

  // Dynamische Screenshot-Höhe: Auf kleinen Phones (SE/mini ~667-844 pt)
  // capped damit alles + CTA-Bar ohne Scroll passt. Auf großen Phones/iPad
  // skaliert es mit. Min 200, Max 320.
  const screenshotHeight = Math.min(320, Math.max(200, screenH * 0.32));

  return (
    <OnboardingShell
      current={current}
      total={total}
      cta={
        <CTABar
          primaryLabel={t(ctaKey)}
          onPrimary={onActivate}
          primaryLoading={activating}
        />
      }
    >
      <LyraBubble text={t(lyraBodyKey)} emotion="empathy" />

      <Text
        style={{
          marginTop: 14,
          fontFamily: 'Nunito_700Bold',
          fontSize: 12,
          letterSpacing: 0.6,
          color: colors.textMuted,
          textTransform: 'uppercase',
          textAlign: 'center',
        }}
      >
        {t(titleKey)}
      </Text>

      <View
        style={{
          marginTop: 8,
          alignSelf: 'center',
          height: screenshotHeight,
          aspectRatio: 0.9,
        }}
      >
        <Image
          source={screenshot}
          style={{ width: '100%', height: '100%' }}
          resizeMode="contain"
        />
      </View>

      <ScreenshotPointer buttonLabel={t(buttonLabelKey)} alignment={pointerAlignment} />

      <Text
        style={{
          marginTop: 10,
          fontFamily: 'Nunito_400Regular',
          fontSize: 12,
          lineHeight: 17,
          color: colors.textMuted,
          textAlign: 'center',
          paddingHorizontal: 8,
        }}
      >
        {t(markerHintKey)}
      </Text>
      {children}
    </OnboardingShell>
  );
}
