import { ReactNode, useEffect, useRef, useState } from 'react';
import {
  Animated,
  Dimensions,
  Easing,
  Keyboard,
  Modal,
  Platform,
  TouchableOpacity,
  StyleProp,
  View,
  ViewStyle,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useColors } from '../lib/theme';

/**
 * Universal-Bottom-Sheet für Forms mit TextInput.
 *
 * Pattern (verifiziert auf PostCommentsSheet + EditMailAccountSheet):
 *
 * 1. Outer-Animated.View hat animated `height` (JS-driver) — Sheet WÄCHST
 *    bei Tastatur-Open um genau die Tastatur-Höhe.
 * 2. Inner-Animated.View hat `transform: translateY` (Native-driver) —
 *    Slide-In/Out smooth. Driver-Mix-Trennung verhindert
 *    "Style property 'height' is not supported by native animated module"-Crash.
 * 3. iOS: `paddingBottom: keyboardHeight` shifted Form innerhalb des
 *    gewachsenen Sheets über die Tastatur. Android: `windowSoftInputMode=adjustResize`
 *    im Manifest schrumpft das Window selbst.
 * 4. Flex-Spacer drückt `children` (Form) automatisch an den Sheet-Bottom-Edge —
 *    sitzt direkt über der Tastatur ohne Gap.
 *
 * Anti-Pattern (siehe `docs/internal/RECOVERY_LOG_2026-05-10.md` §7.2):
 *  - `useKeyboardAnimation()` aus `react-native-keyboard-controller` liefert
 *    in iOS-Modals keine Höhe (separate UIWindow). Hier: plain RN
 *    `Keyboard.addListener` für die Höhe.
 *  - `Animated.subtract`/`marginBottom: keyboardHeight` mischen JS+Native-Driver
 *    auf demselben View → Bouncing oder Crash.
 *
 * Usage:
 * ```tsx
 * <KeyboardAwareSheet
 *   visible={visible}
 *   onClose={onClose}
 *   collapsedHeight={280}
 *   header={<HeaderRow title="Passwort" onCancel={onClose} />}
 * >
 *   <View style={{ padding: 20, gap: 14 }}>
 *     <TextInput ... />
 *     <SaveButton ... />
 *   </View>
 * </KeyboardAwareSheet>
 * ```
 */
export interface KeyboardAwareSheetProps {
  visible: boolean;
  onClose: () => void;
  /** Sheet-Höhe wenn Tastatur zu. Eng auf Inhalt zuschneiden — typisch 220-340px. */
  collapsedHeight: number;
  /** Optionaler Header (Cancel/Title-Row). Rendert direkt unter dem Drag-Handle. */
  header?: ReactNode;
  /** Form-Inhalt. Wird per Flex-Spacer an den Sheet-Bottom gedrückt — sitzt
   *  damit direkt über der Tastatur sobald die offen ist. */
  children: ReactNode;
  /** Default true — Tap auf Backdrop schließt das Sheet. */
  dismissOnBackdrop?: boolean;
  /** Default true — kleiner Drag-Handle ganz oben am Sheet. */
  showDragHandle?: boolean;
  /** Default true — fügt unten eine Safe-Area-Spacer-Höhe ein (insets.bottom). */
  showSafeAreaSpacer?: boolean;
  /** Default true — interner Flex-Spacer drückt children zum Sheet-Bottom.
   *  Auf false setzen wenn der Inhalt seine eigene Scroll-/Flex-Logik hat
   *  (z.B. ScrollView mit Provider-Grid, Listen). */
  pushChildrenToBottom?: boolean;
  /** Border-Radius oben. Default 20. */
  topRadius?: number;
  /** Optional zusätzlicher Style für den Sheet-Container. */
  containerStyle?: StyleProp<ViewStyle>;
}

export function KeyboardAwareSheet({
  visible,
  onClose,
  collapsedHeight,
  header,
  children,
  dismissOnBackdrop = true,
  showDragHandle = true,
  showSafeAreaSpacer = true,
  pushChildrenToBottom = true,
  topRadius = 20,
  containerStyle,
}: KeyboardAwareSheetProps) {
  const colors = useColors();
  const insets = useSafeAreaInsets();

  const slideY = useRef(new Animated.Value(collapsedHeight)).current;
  const backdropOpacity = useRef(new Animated.Value(0)).current;
  const sheetHeight = useRef(new Animated.Value(collapsedHeight)).current;
  const [keyboardHeight, setKeyboardHeight] = useState(0);

  // Slide-In + Backdrop-Fade bei `visible=true`
  useEffect(() => {
    if (visible) {
      slideY.setValue(collapsedHeight);
      backdropOpacity.setValue(0);
      Animated.parallel([
        Animated.timing(slideY, {
          toValue: 0,
          duration: 280,
          easing: Easing.out(Easing.cubic),
          useNativeDriver: true,
        }),
        Animated.timing(backdropOpacity, {
          toValue: 1,
          duration: 220,
          useNativeDriver: true,
        }),
      ]).start();
    }
  }, [visible, slideY, backdropOpacity, collapsedHeight]);

  // Sheet-Höhe wächst/schrumpft mit Tastatur
  useEffect(() => {
    const maxHeight = Dimensions.get('window').height - insets.top - 20;
    const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
    const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
    const showSub = Keyboard.addListener(showEvent, (e) => {
      const h = e.endCoordinates.height;
      setKeyboardHeight(h);
      Animated.timing(sheetHeight, {
        toValue: Math.min(collapsedHeight + h, maxHeight),
        duration: Platform.OS === 'ios' ? (e.duration ?? 250) : 220,
        easing: Easing.out(Easing.cubic),
        useNativeDriver: false,
      }).start();
    });
    const hideSub = Keyboard.addListener(hideEvent, (e) => {
      setKeyboardHeight(0);
      Animated.timing(sheetHeight, {
        toValue: collapsedHeight,
        duration: Platform.OS === 'ios' ? (e?.duration ?? 250) : 220,
        easing: Easing.out(Easing.cubic),
        useNativeDriver: false,
      }).start();
    });
    return () => {
      showSub.remove();
      hideSub.remove();
    };
  }, [sheetHeight, collapsedHeight, insets.top]);

  return (
    <Modal visible={visible} transparent animationType="none" onRequestClose={onClose}>
      {/* Backdrop */}
      <Animated.View
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          backgroundColor: 'rgba(0,0,0,0.4)',
          opacity: backdropOpacity,
        }}
      >
        {dismissOnBackdrop && <TouchableOpacity activeOpacity={1} style={{ flex: 1 }} onPress={onClose} />}
      </Animated.View>

      {/* Outer: animated height (JS-driver) */}
      <Animated.View
        style={{
          position: 'absolute',
          left: 0,
          right: 0,
          bottom: 0,
          height: sheetHeight,
        }}
      >
        {/* Inner: animated transform (Native-driver). Driver-Mix vermeiden
            durch zwei verschachtelte Animated.Views. */}
        <Animated.View
          style={[
            {
              flex: 1,
              backgroundColor: colors.bg,
              borderTopLeftRadius: topRadius,
              borderTopRightRadius: topRadius,
              transform: [{ translateY: slideY }],
              paddingBottom: Platform.OS === 'ios' ? keyboardHeight : 0,
            },
            containerStyle,
          ]}
        >
          <View style={{ flex: 1 }}>
            {showDragHandle && (
              <View style={{ alignItems: 'center', paddingTop: 8, paddingBottom: 4 }}>
                <View
                  style={{
                    width: 36,
                    height: 4,
                    borderRadius: 2,
                    backgroundColor: colors.border,
                  }}
                />
              </View>
            )}
            {header}
            {pushChildrenToBottom ? (
              <>
                {/* Flex-Spacer drückt children an den Sheet-Bottom */}
                <View style={{ flex: 1 }} />
                {children}
              </>
            ) : (
              <View style={{ flex: 1 }}>{children}</View>
            )}
            {showSafeAreaSpacer && <View style={{ height: insets.bottom }} />}
          </View>
        </Animated.View>
      </Animated.View>
    </Modal>
  );
}
