import { useState, useRef, useCallback, useEffect } from 'react';
import {
  View,
  Text,
  Modal,
  FlatList,
  TextInput,
  TouchableOpacity,
  Keyboard,
  ActivityIndicator,
  Animated,
  Dimensions,
  PanResponder,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useKeyboardHandler } from 'react-native-keyboard-controller';
import { runOnJS } from 'react-native-reanimated';
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 { supabase } from '../lib/supabase';
import type { RealtimeChannel } from '@supabase/supabase-js';
import type { CommunityComment } from '../stores/community';
import { UserAvatar } from './UserAvatar';

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

  // Dimensions.get('screen') = physische Screen-Höhe, statisch, ignoriert
  // Keyboard-Resize. MAX bis unter App-Nav-Header (~56dp) damit User per Drag
  // bis ganz oben ziehen kann (User-Feedback: "wie alle andere sheets").
  const SCREEN_HEIGHT = Dimensions.get('screen').height;
  const MAX_HEIGHT = Math.max(300, SCREEN_HEIGHT - insets.top - 56);
  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) {
      // State-Reset bei Re-Open. Wichtig: keyboardHeight zurücksetzen, weil
      // applyKbdHeight wegen `if (!visible) return` das `h=0`-Hide-Event nicht
      // verarbeitet hat → sonst öffnet Sheet beim 2. Mal mit altem paddingBottom.
      setKeyboardHeight(0);
      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;

  // keyboard-controller: Modal-aware Frame-Werte für iOS+Android (siehe Memory
  // feedback_use_keyboard_controller). Manuelles Keyboard.addListener war auf
  // Android im Modal unzuverlässig (paddingBottom=0 → Input hinter Tastatur).
  const applyKbdHeight = (h: number) => {
    if (!visible) return;
    setKeyboardHeight(h);
    const target = h > 0
      ? Math.min(currentHeight.current + h, maxHeightRef.current)
      : currentHeight.current;
    Animated.spring(sheetHeight, {
      toValue: target,
      useNativeDriver: false,
      friction: 9,
      tension: 70,
    }).start();
  };
  useKeyboardHandler({
    onStart: (e) => {
      'worklet';
      runOnJS(applyKbdHeight)(e.height);
    },
    onEnd: (e) => {
      'worklet';
      runOnJS(applyKbdHeight)(e.height);
    },
  });

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

  // Realtime: revalidate comment list when any like on this post's comments changes.
  // Requires rebreak.comment_likes to be in supabase_realtime publication — see
  // backend migration TODO below.
  useEffect(() => {
    if (!postId || !visible) return;
    let channel: RealtimeChannel | null = null;
    let cancelled = false;

    async function subscribe() {
      const { data } = await supabase.auth.getSession();
      if (!data.session?.access_token || cancelled) return;

      channel = supabase
        .channel(`comment-likes:${postId}:${Date.now()}`)
        .on(
          'postgres_changes',
          { event: '*', schema: 'rebreak', table: 'comment_likes' },
          () => {
            queryClient.invalidateQueries({ queryKey: ['post-comments', postId] });
          },
        )
        .subscribe();
    }

    subscribe();

    return () => {
      cancelled = true;
      if (channel) supabase.removeChannel(channel);
    };
  }, [postId, visible, queryClient]);

  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'] });
      // Sheet schließen nach erfolgreicher Comment-Abgabe (User-Feedback).
      handleClose();
    } catch {
      // ignore
    } finally {
      setSubmitting(false);
    }
  }, [text, postId, replyTarget, queryClient, handleClose]);

  const likeComment = useCallback(
    async (comment: CommunityComment) => {
      const queryKey = ['post-comments', postId];
      const optimisticLiked = !comment.userLike;
      const countDelta = optimisticLiked ? 1 : -1;

      queryClient.setQueryData<CommunityComment[]>(queryKey, (prev) =>
        prev?.map((c) =>
          c.id === comment.id
            ? { ...c, userLike: optimisticLiked, likesCount: Math.max(0, c.likesCount + countDelta) }
            : c,
        ),
      );

      try {
        await apiFetch('/api/community/comment-like', {
          method: 'POST',
          body: { commentId: comment.id },
        });
        queryClient.invalidateQueries({ queryKey });
      } catch {
        queryClient.setQueryData<CommunityComment[]>(queryKey, (prev) =>
          prev?.map((c) =>
            c.id === comment.id
              ? { ...c, userLike: comment.userLike, likesCount: comment.likesCount }
              : c,
          ),
        );
      }
    },
    [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: keyboardHeight,
            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]);

  return (
    <View style={{ flexDirection: 'row', gap: 12, paddingVertical: 8 }}>
      <View style={{ marginTop: 2 }}>
        <UserAvatar
          userId={!isReply ? (comment.authorId ?? null) : null}
          avatar={comment.authorAvatar ?? null}
          nickname={comment.authorNickname ?? 'AN'}
          size="sm"
          showOnlineIndicator={!isReply}
        />
      </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={20}
            color={comment.userLike ? '#dc2626' : '#a3a3a3'}
          />
        </Animated.View>
        {comment.likesCount > 0 && (
          <Text style={{ fontSize: 9, color: '#a3a3a3', fontFamily: 'Nunito_400Regular' }}>
            {comment.likesCount}
          </Text>
        )}
      </TouchableOpacity>
    </View>
  );
}
