import { ReactNode, useEffect, useRef, useState } from 'react';
import {
  Animated,
  Keyboard,
  Modal,
  PanResponder,
  Platform,
  Pressable,
  Text,
  View,
  useWindowDimensions,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useColors } from '../lib/theme';

/**
 * App-weites Bottom-Sheet — DAS eine Pattern für alle Custom-Modals.
 *
 * Verallgemeinert das verifizierte `PostCommentsSheet`-Pattern:
 *  - `<Modal transparent>` mit hellem (oder ganz ohne) Backdrop — verdunkelt den
 *    Main-Screen nie stark.
 *  - **Standard-Header**: Grabber-Bar mittig + Titel **links**. KEINE
 *    „Fertig"/„Abbrechen"/„Zurück"-Buttons — Schließen = runterswipen / Backdrop-Tap.
 *  - **Resizable**: Drag am Handle/Header zieht das Sheet größer/kleiner;
 *    Drag nach unten unter `minHeightPct` (oder schneller Flick) → dismiss.
 *  - **Höhe ≤ 75 % Screen**, IMMER (Drag + Keyboard-Expand sind hart gedeckelt).
 *  - **Keyboard-aware**: Tastatur auf → Sheet wächst um Tastatur-Höhe (gedeckelt),
 *    `paddingBottom: keyboardHeight` (iOS) schiebt den Inhalt exakt über die
 *    Tastatur. Android: `windowSoftInputMode=adjustResize` im Manifest macht das.
 *
 * Driver-Trennung (sonst „Style property 'height' is not supported by native
 * animated module"-Crash): äußere View animiert `height` im JS-Driver, innere
 * View animiert `transform: translateY` (Slide/Dismiss) im Native-Driver.
 *
 * Der Inhalt (`children`) wird in einem `flex:1`-Wrapper unter dem Header
 * gerendert — der Caller layoutet selbst (z.B. `flex:1`-ScrollView + Bottom-Bar
 * für eine Input-Zeile, die dann automatisch über der Tastatur sitzt).
 *
 * Für progressive Mehr-Feld-Formulare (Mail-Account, Domain hinzufügen) kommt
 * `<SheetFieldStack>` als Inhalt rein (Phase 2).
 */

const MAX_HEIGHT_PCT = 0.75; // harter Cap — nie höher
const DRAG_FLICK_VELOCITY = 1.5;

export interface FormSheetProps {
  visible: boolean;
  onClose: () => void;
  /** Titel links im Header. */
  title: string;
  children: ReactNode;
  /** Start-Höhe als Anteil der Screen-Höhe (0..0.75). Default 0.5. */
  initialHeightPct?: number;
  /** Drag-down unter diesen Anteil (oder Flick) → dismiss. Default 0.3. */
  minHeightPct?: number;
  /** Backdrop-Deckkraft (0 = kein Dim). Default 0.12 — Main-Screen bleibt sichtbar. */
  backdropOpacity?: number;
  /** Default true — Tap auf Backdrop schließt das Sheet. */
  dismissOnBackdrop?: boolean;
  /** Default true — fügt unten einen Safe-Area-Spacer ein wenn die Tastatur zu ist. */
  safeAreaBottom?: boolean;
  /** Default true — Sheet wächst/expandiert wenn die Tastatur aufgeht. Für
   *  Sheets ohne Input egal; auf false setzen wenn man's bewusst nicht will. */
  growWithKeyboard?: boolean;
  /** Border-Radius oben. Default 24. */
  topRadius?: number;
}

export function FormSheet({
  visible,
  onClose,
  title,
  children,
  initialHeightPct = 0.5,
  minHeightPct = 0.3,
  backdropOpacity = 0.12,
  dismissOnBackdrop = true,
  safeAreaBottom = true,
  growWithKeyboard = true,
  topRadius = 24,
}: FormSheetProps) {
  const colors = useColors();
  const insets = useSafeAreaInsets();
  // useWindowDimensions: live — auf Android schrumpft height bei offener Tastatur
  // (adjustResize), daher dynamisch statt Dimensions.get (statisch beim Modul-Load).
  const { height: SCREEN_H } = useWindowDimensions();

  const maxHeight = SCREEN_H * MAX_HEIGHT_PCT;
  const initialHeight = Math.min(SCREEN_H * initialHeightPct, maxHeight);
  const dismissHeight = SCREEN_H * minHeightPct;

  const sheetHeight = useRef(new Animated.Value(initialHeight)).current; // JS driver
  const dismissY = useRef(new Animated.Value(0)).current; // native driver
  const currentHeight = useRef(initialHeight); // letzte „Ruhe"-Höhe (Drag oder initial)
  const keyboardHeightRef = useRef(0);
  const [keyboardHeight, setKeyboardHeight] = useState(0);

  // Reset bei (Wieder-)Öffnen
  useEffect(() => {
    if (visible) {
      sheetHeight.setValue(initialHeight);
      dismissY.setValue(0);
      currentHeight.current = initialHeight;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [visible]);

  const handleClose = () => {
    Keyboard.dismiss();
    sheetHeight.setValue(initialHeight);
    dismissY.setValue(0);
    currentHeight.current = initialHeight;
    onClose();
  };

  // Keyboard: Sheet wächst (gedeckelt) + paddingBottom schiebt Inhalt über die Tastatur
  useEffect(() => {
    if (!growWithKeyboard) return;
    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;
      keyboardHeightRef.current = h;
      setKeyboardHeight(h);
      Animated.timing(sheetHeight, {
        toValue: Math.min(currentHeight.current + h, maxHeight),
        duration: Platform.OS === 'ios' ? e.duration ?? 250 : 200,
        useNativeDriver: false,
      }).start();
    });
    const hideSub = Keyboard.addListener(hideEvent, (e) => {
      keyboardHeightRef.current = 0;
      setKeyboardHeight(0);
      Animated.timing(sheetHeight, {
        toValue: Math.min(currentHeight.current, maxHeight),
        duration: Platform.OS === 'ios' ? e?.duration ?? 250 : 200,
        useNativeDriver: false,
      }).start();
    });
    return () => {
      showSub.remove();
      hideSub.remove();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [growWithKeyboard, maxHeight]);

  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponder: () => true,
      onPanResponderTerminationRequest: () => false,
      onPanResponderMove: (_, g) => {
        // Drag rauf (dy<0) → höher. Mit offener Tastatur rechnen wir vom
        // gewachsenen Stand aus.
        const base = currentHeight.current + keyboardHeightRef.current;
        const next = base - g.dy;
        sheetHeight.setValue(Math.max(dismissHeight - 60, Math.min(maxHeight + 16, next)));
      },
      onPanResponderRelease: (_, g) => {
        const base = currentHeight.current + keyboardHeightRef.current;
        const finalH = base - g.dy;
        const v = g.vy;
        if (finalH < dismissHeight || v > DRAG_FLICK_VELOCITY) {
          Animated.timing(dismissY, {
            toValue: SCREEN_H,
            duration: 200,
            useNativeDriver: true,
          }).start(() => handleClose());
          return;
        }
        let target = finalH;
        if (v < -DRAG_FLICK_VELOCITY) target = maxHeight;
        const clamped = Math.max(SCREEN_H * minHeightPct, Math.min(maxHeight, target));
        Animated.spring(sheetHeight, {
          toValue: clamped,
          useNativeDriver: false,
          friction: 9,
          tension: 70,
        }).start();
        // „Ruhe"-Höhe = ohne Tastatur-Anteil merken
        currentHeight.current = Math.max(0, clamped - keyboardHeightRef.current);
      },
    }),
  ).current;

  const dragHandlers = panResponder.panHandlers;

  return (
    <Modal visible={visible} transparent animationType="slide" onRequestClose={handleClose} statusBarTranslucent>
      {/* Backdrop */}
      <Pressable
        onPress={dismissOnBackdrop ? handleClose : undefined}
        style={{ flex: 1, backgroundColor: `rgba(0,0,0,${backdropOpacity})` }}
      />

      {/* Outer: animated height (JS driver) */}
      <Animated.View
        style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: sheetHeight }}
      >
        {/* Inner: animated transform (native driver) — getrennt, kein Driver-Mix */}
        <Animated.View
          style={{
            flex: 1,
            backgroundColor: colors.bg,
            borderTopLeftRadius: topRadius,
            borderTopRightRadius: topRadius,
            overflow: 'hidden',
            paddingBottom: Platform.OS === 'ios' ? keyboardHeight : 0,
            transform: [{ translateY: dismissY }],
            shadowColor: '#000',
            shadowOffset: { width: 0, height: -2 },
            shadowOpacity: 0.08,
            shadowRadius: 8,
          }}
        >
          {/* Grabber-Bar (mittig, drag-area) */}
          <View {...dragHandlers} style={{ alignItems: 'center', paddingTop: 8, paddingBottom: 6 }}>
            <View style={{ width: 36, height: 5, borderRadius: 3, backgroundColor: colors.border }} />
          </View>

          {/* Header: Titel links — keine Buttons. Auch drag-area. */}
          <View
            {...dragHandlers}
            style={{
              paddingHorizontal: 20,
              paddingTop: 4,
              paddingBottom: 12,
              borderBottomWidth: 1,
              borderBottomColor: colors.border,
            }}
          >
            <Text style={{ fontSize: 16, fontFamily: 'Nunito_700Bold', color: colors.text }}>
              {title}
            </Text>
          </View>

          {/* Inhalt */}
          <View style={{ flex: 1 }}>{children}</View>

          {/* Safe-Area-Spacer (nur wenn Tastatur zu) */}
          {safeAreaBottom && <View style={{ height: keyboardHeight > 0 ? 0 : insets.bottom }} />}
        </Animated.View>
      </Animated.View>
    </Modal>
  );
}
