import { useState, useRef, useCallback, useEffect } from 'react';
import {
  View,
  Text,
  Modal,
  FlatList,
  TextInput,
  TouchableOpacity,
  Keyboard,
  Platform,
  ActivityIndicator,
  Animated,
  Image,
  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 { resolveAvatar } from '../lib/resolveAvatar';
import { useColors } from '../lib/theme';
import type { CommunityComment } from '../stores/community';

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

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 MAX_HEIGHT = SCREEN_HEIGHT * 0.75;
  const MIN_HEIGHT = SCREEN_HEIGHT * 0.35;
  const INITIAL_HEIGHT = SCREEN_HEIGHT * 0.65;

  // Sheet-Höhe animiert (height-based, bottom: 0 fix).
  // Separater translateY für die Dismiss-Slide-Animation (native driver).
  const sheetHeight = useRef(new Animated.Value(INITIAL_HEIGHT)).current;
  const dismissY = useRef(new Animated.Value(0)).current;
  const currentHeight = useRef(INITIAL_HEIGHT);

  // PanResponder braucht stabile Refs auf die berechneten Limits,
  // weil er nur einmal erstellt wird (useRef-Semantik).
  const maxHeightRef = useRef(MAX_HEIGHT);
  const minHeightRef = useRef(MIN_HEIGHT);
  const screenHeightRef = useRef(SCREEN_HEIGHT);
  useEffect(() => {
    maxHeightRef.current = MAX_HEIGHT;
    minHeightRef.current = MIN_HEIGHT;
    screenHeightRef.current = SCREEN_HEIGHT;
  }, [MAX_HEIGHT, MIN_HEIGHT, SCREEN_HEIGHT]);

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

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

  // PanResponder NUR für Grabber-Bar + Header — nicht für den Content-Bereich.
  // onStartShouldSetPanResponderCapture würde FlatList-Scroll brechen.
  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dy) > 4,
      onPanResponderTerminationRequest: () => false,
      onPanResponderMove: (_, g) => {
        const next = currentHeight.current - g.dy;
        const clamped = Math.max(
          minHeightRef.current - 80,
          Math.min(maxHeightRef.current + 16, next),
        );
        sheetHeight.setValue(clamped);
      },
      onPanResponderRelease: (_, g) => {
        const finalH = currentHeight.current - g.dy;
        const v = g.vy;

        if (finalH < minHeightRef.current || v > 1.5) {
          Animated.timing(dismissY, {
            toValue: screenHeightRef.current,
            duration: 200,
            useNativeDriver: true,
          }).start(() => {
            Keyboard.dismiss();
            setText('');
            setReplyTarget(null);
            sheetHeight.setValue(INITIAL_HEIGHT);
            dismissY.setValue(0);
            currentHeight.current = INITIAL_HEIGHT;
            onClose();
          });
          return;
        }

        let target = finalH;
        if (v < -1.5) target = maxHeightRef.current;
        const clamped = Math.max(minHeightRef.current, Math.min(maxHeightRef.current, 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) => {
      const h = e.endCoordinates.height;
      setKeyboardHeight(h);
      const expanded = Math.min(currentHeight.current + h, maxHeightRef.current);
      Animated.spring(sheetHeight, {
        toValue: expanded,
        useNativeDriver: false,
        friction: 9,
        tension: 70,
      }).start();
    });
    const hideSub = Keyboard.addListener(hideEvent, () => {
      setKeyboardHeight(0);
      Animated.spring(sheetHeight, {
        toValue: currentHeight.current,
        useNativeDriver: false,
        friction: 9,
        tension: 70,
      }).start();
    });
    return () => {
      showSub.remove();
      hideSub.remove();
    };
  }, [sheetHeight]);

  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],
  );

  const dragHandlers = panResponder.panHandlers;

  return (
    <Modal
      visible={visible}
      onRequestClose={handleClose}
      animationType="slide"
      transparent
      statusBarTranslucent
    >
      {/* Backdrop */}
      <TouchableOpacity
        activeOpacity={1}
        onPress={handleClose}
        style={{ flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.12)' }}
      />

      {/* 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: 24,
            borderTopRightRadius: 24,
            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 — drag-area */}
          <View
            {...dragHandlers}
            style={{ alignItems: 'center', paddingTop: 8, paddingBottom: 6 }}
          >
            <View
              style={{
                width: 36,
                height: 5,
                borderRadius: 3,
                backgroundColor: colors.border,
              }}
            />
          </View>

          {/* Header — auch drag-area */}
          <View
            {...dragHandlers}
            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) => (
              <TouchableOpacity key={e} activeOpacity={0.7} onPress={() => setText((prev) => prev + e)}>
                <Text style={{ fontSize: 22 }}>{e}</Text>
              </TouchableOpacity>
            ))}
          </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>
              <TouchableOpacity activeOpacity={0.7} onPress={() => setReplyTarget(null)}>
                <Ionicons name="close-circle" size={16} color="#a3a3a3" />
              </TouchableOpacity>
            </View>
          )}

          {/* Input + Send-Button */}
          <View
            style={{
              flexDirection: 'row',
              alignItems: 'center',
              paddingHorizontal: 16,
              paddingTop: 10,
              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}
            />
            <TouchableOpacity
              onPress={submit}
              disabled={!text.trim() || submitting}
              activeOpacity={0.5}
              style={{ opacity: !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>
            </TouchableOpacity>
          </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]);

  const avatarSize = isReply ? 24 : 32;
  const avatarRadius = avatarSize / 2;
  const resolvedAvatar = comment.authorAvatar
    ? resolveAvatar(comment.authorAvatar, comment.authorNickname ?? 'anonym')
    : null;

  return (
    <View style={{ flexDirection: 'row', gap: 12, paddingVertical: 8 }}>
      <View
        style={{
          width: avatarSize,
          height: avatarSize,
          borderRadius: avatarRadius,
          backgroundColor: colors.surfaceElevated,
          alignItems: 'center',
          justifyContent: 'center',
          marginTop: 2,
          overflow: 'hidden',
        }}
      >
        {resolvedAvatar ? (
          <Image
            source={{ uri: resolvedAvatar }}
            style={{ width: avatarSize, height: avatarSize, borderRadius: avatarRadius }}
          />
        ) : (
          <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 && (
            <TouchableOpacity activeOpacity={0.7} onPress={onReply}>
              <Text
                style={{
                  fontSize: 11,
                  color: colors.textMuted,
                  fontFamily: 'Nunito_600SemiBold',
                }}
              >
                {t('community.reply')}
              </Text>
            </TouchableOpacity>
          )}
        </View>
      </View>

      <TouchableOpacity
        activeOpacity={0.7}
        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>
        )}
      </TouchableOpacity>
    </View>
  );
}
