import { useState, useRef, useCallback, useEffect } from 'react';
import {
  View,
  Text,
  Modal,
  FlatList,
  TextInput,
  Pressable,
  Keyboard,
  Platform,
  ActivityIndicator,
  Animated,
  PanResponder,
  useWindowDimensions,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { apiFetch } from '../lib/api';
import { formatRelativeTime } from '../lib/formatTime';
import { useColors } from '../lib/theme';
import type { CommunityComment } from '../stores/community';

const EMOJIS = ['❤️', '🙌', '🔥', '👏', '😢', '😍', '😮', '😂'];
const SNAP_THRESHOLD = 50;

type Props = {
  postId: string | null;
  visible: boolean;
  onClose: () => void;
};

export function PostCommentsSheet({ postId, visible, onClose }: Props) {
  const { t } = useTranslation();
  const colors = useColors();
  const insets = useSafeAreaInsets();
  const queryClient = useQueryClient();
  const inputRef = useRef<TextInput>(null);
  const [text, setText] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [replyTarget, setReplyTarget] = useState<{ id: string; nickname: string } | null>(null);
  const [keyboardHeight, setKeyboardHeight] = useState(0);

  // useWindowDimensions: live-tracking. Auf Android schrumpft `height` wenn die
  // Tastatur aufgeht (windowSoftInputMode=adjustResize) — daher dynamisch statt
  // `Dimensions.get` (statisch beim Modul-Load).
  const { height: SCREEN_HEIGHT } = useWindowDimensions();
  const COLLAPSED_HEIGHT = SCREEN_HEIGHT * 0.65;
  const EXPANDED_HEIGHT = SCREEN_HEIGHT * 0.92;
  const MIN_HEIGHT = SCREEN_HEIGHT * 0.35;

  // Sheet-Höhe animiert (height-based, bottom: 0 fix → Input bleibt immer am Edge sichtbar).
  // Plus separater translateY für die Dismiss-Slide-Animation (native).
  const sheetHeight = useRef(new Animated.Value(COLLAPSED_HEIGHT)).current;
  const dismissY = useRef(new Animated.Value(0)).current;
  const currentHeight = useRef(COLLAPSED_HEIGHT);

  const handleClose = useCallback(() => {
    Keyboard.dismiss();
    setText('');
    setReplyTarget(null);
    sheetHeight.setValue(COLLAPSED_HEIGHT);
    dismissY.setValue(0);
    currentHeight.current = COLLAPSED_HEIGHT;
    onClose();
  }, [onClose, sheetHeight, dismissY]);

  useEffect(() => {
    if (visible) {
      sheetHeight.setValue(COLLAPSED_HEIGHT);
      dismissY.setValue(0);
      currentHeight.current = COLLAPSED_HEIGHT;
    }
  }, [visible, sheetHeight, dismissY]);

  const panResponder = useRef(
    PanResponder.create({
      // Claim Gesture sofort, kein Wartet-bis-5px
      onStartShouldSetPanResponder: () => true,
      onStartShouldSetPanResponderCapture: () => true,
      onMoveShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponderCapture: () => true,
      onPanResponderTerminationRequest: () => false,
      onPanResponderMove: (_, g) => {
        // Drag rauf (g.dy < 0) → height grösser. Drag runter → height kleiner.
        const next = currentHeight.current - g.dy;
        const clamped = Math.max(MIN_HEIGHT - 100, Math.min(EXPANDED_HEIGHT + 20, next));
        sheetHeight.setValue(clamped);
      },
      onPanResponderRelease: (_, g) => {
        const finalH = currentHeight.current - g.dy;
        const velocity = g.vy; // Pixel pro ms (negativ = nach oben, positiv = nach unten)

        // Unter MIN_HEIGHT oder schneller Flick nach unten → dismiss
        if (finalH < MIN_HEIGHT || velocity > 1.5) {
          Animated.timing(dismissY, {
            toValue: SCREEN_HEIGHT,
            duration: 200,
            useNativeDriver: true,
          }).start(() => {
            handleClose();
          });
          return;
        }

        // Schneller Flick nach oben → auf Maximum schnappen
        let target = finalH;
        if (velocity < -1.5) {
          target = EXPANDED_HEIGHT;
        }

        // Clamp auf gültigen Bereich, sonst bleibt's wo der User losgelassen hat
        const clamped = Math.max(MIN_HEIGHT, Math.min(EXPANDED_HEIGHT, target));

        Animated.spring(sheetHeight, {
          toValue: clamped,
          useNativeDriver: false,
          friction: 9,
          tension: 70,
        }).start();
        currentHeight.current = clamped;
      },
    }),
  ).current;

  useEffect(() => {
    const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
    const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
    const showSub = Keyboard.addListener(showEvent, (e) => {
      setKeyboardHeight(e.endCoordinates.height);
    });
    const hideSub = Keyboard.addListener(hideEvent, () => {
      setKeyboardHeight(0);
    });
    return () => {
      showSub.remove();
      hideSub.remove();
    };
  }, []);

  const { data: comments = [], isLoading } = useQuery<CommunityComment[]>({
    queryKey: ['post-comments', postId],
    queryFn: () => apiFetch(`/api/community/${postId}/comments`),
    enabled: !!postId && visible,
    staleTime: 30_000,
  });

  const topLevel = comments.filter((c) => !c.parentCommentId);
  const repliesFor = (id: string) => comments.filter((c) => c.parentCommentId === id);

  const submit = useCallback(async () => {
    if (!text.trim() || !postId) return;
    setSubmitting(true);
    try {
      await apiFetch('/api/community/comment', {
        method: 'POST',
        body: {
          postId,
          content: text.trim(),
          ...(replyTarget ? { parentCommentId: replyTarget.id } : {}),
        },
      });
      setText('');
      setReplyTarget(null);
      queryClient.invalidateQueries({ queryKey: ['post-comments', postId] });
      queryClient.invalidateQueries({ queryKey: ['community-posts'] });
    } catch {
      // ignore
    } finally {
      setSubmitting(false);
    }
  }, [text, postId, replyTarget, queryClient]);

  const likeComment = useCallback(
    async (comment: CommunityComment) => {
      try {
        await apiFetch('/api/community/comment-like', {
          method: 'POST',
          body: { commentId: comment.id },
        });
        queryClient.invalidateQueries({ queryKey: ['post-comments', postId] });
      } catch {
        // ignore
      }
    },
    [postId, queryClient],
  );

  // Bei offener Tastatur → automatisch expanded
  useEffect(() => {
    if (keyboardHeight > 0 && currentHeight.current !== EXPANDED_HEIGHT) {
      Animated.spring(sheetHeight, {
        toValue: EXPANDED_HEIGHT,
        useNativeDriver: false,
        friction: 9,
        tension: 70,
      }).start();
      currentHeight.current = EXPANDED_HEIGHT;
    }
  }, [keyboardHeight, sheetHeight]);

  return (
    <Modal
      visible={visible}
      onRequestClose={handleClose}
      animationType="slide"
      transparent
      statusBarTranslucent
    >
      {/* Backdrop — sehr leichter Dim damit man Posts vom Drawer unterscheidet */}
      <Pressable
        onPress={handleClose}
        style={{
          flex: 1,
          backgroundColor: 'rgba(0, 0, 0, 0.12)',
        }}
      />

      {/* Outer: animated height (non-native driver) */}
      <Animated.View
        style={{
          position: 'absolute',
          bottom: 0,
          left: 0,
          right: 0,
          height: sheetHeight,
        }}
      >
        {/* Inner: animated transform (native driver) — getrennt damit kein Driver-Mix */}
        <Animated.View
          style={{
            flex: 1,
            backgroundColor: colors.bg,
            borderTopLeftRadius: 24,
            borderTopRightRadius: 24,
            overflow: 'hidden',
            // Android: windowSoftInputMode=adjustResize schrumpft schon das Window
            // → KEIN paddingBottom mehr (sonst doppelter Offset, Drawer schießt nach oben).
            // iOS: kein adjustResize-Equivalent, padding muss hier kompensieren.
            paddingBottom: Platform.OS === 'ios' ? keyboardHeight : 0,
            transform: [{ translateY: dismissY }],
            shadowColor: '#000',
            shadowOffset: { width: 0, height: -2 },
            shadowOpacity: 0.08,
            shadowRadius: 8,
          }}
        >
        {/* Drag-Bar — drag-down dismisst via PanResponder */}
        <View
          {...panResponder.panHandlers}
          style={{ alignItems: 'center', paddingTop: 8, paddingBottom: 6 }}
        >
          <View
            style={{
              width: 36,
              height: 5,
              borderRadius: 3,
              backgroundColor: colors.border,
            }}
          />
        </View>

        {/* Header — auch drag-area, kein X-Button */}
        <View
          {...panResponder.panHandlers}
          style={{
            paddingHorizontal: 20,
            paddingTop: 6,
            paddingBottom: 12,
            borderBottomWidth: 1,
            borderBottomColor: colors.border,
          }}
        >
          <Text style={{ fontSize: 16, fontFamily: 'Nunito_700Bold', color: colors.text }}>
            {t('community.comments_title')}
          </Text>
        </View>

        {/* Comments-Liste */}
        {isLoading ? (
          <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <ActivityIndicator color={colors.brandOrange} />
          </View>
        ) : (
          <FlatList
            data={topLevel}
            keyExtractor={(item) => item.id}
            style={{ flex: 1 }}
            contentContainerStyle={{ paddingVertical: 8, paddingHorizontal: 16 }}
            keyboardShouldPersistTaps="handled"
            ListEmptyComponent={
              <View style={{ alignItems: 'center', paddingVertical: 48 }}>
                <Text style={{ fontSize: 14, color: '#a3a3a3', fontFamily: 'Nunito_400Regular' }}>
                  {t('community.comments_empty')}
                </Text>
              </View>
            }
            renderItem={({ item: comment }) => (
              <View>
                <CommentRow
                  comment={comment}
                  onReply={() => {
                    setReplyTarget({ id: comment.id, nickname: comment.authorNickname });
                    inputRef.current?.focus();
                  }}
                  onLike={() => likeComment(comment)}
                />
                {repliesFor(comment.id).map((reply) => (
                  <View key={reply.id} style={{ marginLeft: 44 }}>
                    <CommentRow comment={reply} isReply onLike={() => likeComment(reply)} />
                  </View>
                ))}
              </View>
            )}
          />
        )}

        {/* Emoji-Bar */}
        <View
          style={{
            flexDirection: 'row',
            justifyContent: 'space-around',
            paddingHorizontal: 16,
            paddingVertical: 8,
            borderTopWidth: 1,
            borderTopColor: colors.border,
          }}
        >
          {EMOJIS.map((e) => (
            <Pressable key={e} onPress={() => setText((t) => t + e)}>
              <Text style={{ fontSize: 22 }}>{e}</Text>
            </Pressable>
          ))}
        </View>

        {/* Reply-Context */}
        {replyTarget && (
          <View
            style={{
              flexDirection: 'row',
              alignItems: 'center',
              justifyContent: 'space-between',
              paddingHorizontal: 16,
              paddingVertical: 8,
              backgroundColor: colors.surface,
            }}
          >
            <Text style={{ fontSize: 12, color: colors.textMuted, fontFamily: 'Nunito_400Regular' }}>
              {t('community.reply_to')}{' '}
              <Text style={{ fontFamily: 'Nunito_700Bold' }}>@{replyTarget.nickname}</Text>
            </Text>
            <Pressable onPress={() => setReplyTarget(null)}>
              <Ionicons name="close-circle" size={16} color="#a3a3a3" />
            </Pressable>
          </View>
        )}

        {/* Input + Send-Button */}
        <View
          style={{
            flexDirection: 'row',
            alignItems: 'center',
            paddingHorizontal: 16,
            paddingTop: 10,
            // Bei offener Tastatur kleines Padding (kein Home-Indicator sichtbar),
            // sonst Safe-Area
            paddingBottom: keyboardHeight > 0 ? 8 : Math.max(12, insets.bottom),
            borderTopWidth: 1,
            borderTopColor: colors.border,
          }}
        >
          <TextInput
            ref={inputRef}
            value={text}
            onChangeText={setText}
            placeholder={t('community.comment_placeholder')}
            placeholderTextColor={colors.textMuted}
            style={{
              flex: 1,
              backgroundColor: colors.surface,
              borderWidth: 1,
              borderColor: colors.border,
              borderRadius: 999,
              paddingHorizontal: 16,
              paddingVertical: 10,
              fontSize: 14,
              fontFamily: 'Nunito_400Regular',
              color: colors.text,
              marginRight: 8,
            }}
            returnKeyType="send"
            onSubmitEditing={submit}
            blurOnSubmit={false}
          />
          <Pressable
            onPress={submit}
            disabled={!text.trim() || submitting}
            style={({ pressed }) => ({
              opacity: pressed || !text.trim() || submitting ? 0.5 : 1,
            })}
          >
            <View style={{
              width: 40,
              height: 40,
              borderRadius: 20,
              backgroundColor: colors.brandOrange,
              alignItems: 'center',
              justifyContent: 'center',
            }}>
            {submitting ? (
              <ActivityIndicator size="small" color="#fff" />
            ) : (
              <Ionicons name="paper-plane" size={16} color="#fff" />
            )}
            </View>
          </Pressable>
        </View>
        </Animated.View>
      </Animated.View>
    </Modal>
  );
}

type CommentRowProps = {
  comment: CommunityComment;
  isReply?: boolean;
  onReply?: () => void;
  onLike: () => void;
};

function CommentRow({ comment, isReply = false, onReply, onLike }: CommentRowProps) {
  const { t } = useTranslation();
  const colors = useColors();
  const heartScale = useRef(new Animated.Value(1)).current;
  const handleLikeWithPop = useCallback(() => {
    heartScale.setValue(1);
    Animated.sequence([
      Animated.timing(heartScale, { toValue: 1.4, duration: 120, useNativeDriver: true }),
      Animated.spring(heartScale, { toValue: 1, friction: 4, tension: 80, useNativeDriver: true }),
    ]).start();
    onLike();
  }, [heartScale, onLike]);

  return (
    <View style={{ flexDirection: 'row', gap: 12, paddingVertical: 8 }}>
      <View
        style={{
          width: isReply ? 24 : 32,
          height: isReply ? 24 : 32,
          borderRadius: isReply ? 12 : 16,
          backgroundColor: colors.surfaceElevated,
          alignItems: 'center',
          justifyContent: 'center',
          marginTop: 2,
        }}
      >
        <Text style={{ fontSize: isReply ? 9 : 11, fontFamily: 'Nunito_700Bold', color: colors.textMuted }}>
          {(comment.authorNickname ?? 'AN').slice(0, 2).toUpperCase()}
        </Text>
      </View>

      <View style={{ flex: 1, minWidth: 0 }}>
        <Text style={{ fontSize: 12, fontFamily: 'Nunito_700Bold', color: colors.text }}>
          {comment.authorNickname ?? t('community.anonymous_label')}
        </Text>
        <Text
          style={{
            fontSize: 14,
            fontFamily: 'Nunito_400Regular',
            color: colors.textMuted,
            lineHeight: 20,
            marginTop: 2,
          }}
        >
          {comment.content}
        </Text>
        <View style={{ flexDirection: 'row', alignItems: 'center', gap: 16, marginTop: 6 }}>
          <Text style={{ fontSize: 10, color: colors.textMuted, fontFamily: 'Nunito_400Regular' }}>
            {formatRelativeTime(comment.createdAt)}
          </Text>
          {!isReply && onReply && (
            <Pressable onPress={onReply}>
              <Text style={{ fontSize: 11, color: colors.textMuted, fontFamily: 'Nunito_600SemiBold' }}>
                {t('community.reply')}
              </Text>
            </Pressable>
          )}
        </View>
      </View>

      <Pressable onPress={handleLikeWithPop} style={{ alignItems: 'center', gap: 2, paddingTop: 2 }}>
        <Animated.View style={{ transform: [{ scale: heartScale }] }}>
          <Ionicons
            name={comment.userLike ? 'heart' : 'heart-outline'}
            size={16}
            color={comment.userLike ? '#dc2626' : '#a3a3a3'}
          />
        </Animated.View>
        {comment.likesCount > 0 && (
          <Text style={{ fontSize: 9, color: '#a3a3a3', fontFamily: 'Nunito_400Regular' }}>
            {comment.likesCount}
          </Text>
        )}
      </Pressable>
    </View>
  );
}
