import { useState, useRef, useEffect, useCallback } from 'react';
import {
  View,
  Text,
  FlatList,
  TouchableOpacity,
  Platform,
  ActivityIndicator,
  Image,
  StyleSheet,
} from 'react-native';
import { KeyboardAvoidingView } from 'react-native-keyboard-controller';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { useRouter, useLocalSearchParams } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { apiFetch } from '../lib/api';
import { supabase } from '../lib/supabase';
import { ChatBubble, type ChatMsg } from '../components/chat/ChatBubble';
import { resolveAvatar } from '../lib/resolveAvatar';
import { ChatInput, type SendPayload } from '../components/chat/ChatInput';
import { DmChatBackground } from '../components/chat/DmChatBackground';
import { useDmRealtime } from '../hooks/useChatRealtime';
import { useColors } from '../lib/theme';
import { useThemeStore } from '../stores/theme';

type DmHistoryResponse = {
  partner: {
    id: string;
    nickname: string;
    username?: string;
    avatar?: string | null;
  };
  messages: Array<{
    id: string;
    content: string;
    createdAt: string;
    isOwn: boolean;
    readAt: string | null;
    senderId?: string;
    receiverId?: string;
    likesCount?: number;
    likedByMe?: boolean;
    attachmentUrl?: string | null;
    attachmentType?: string | null;
    attachmentName?: string | null;
    replyTo?: any;
  }>;
};

const GROUP_GAP_MS = 5 * 60 * 1000;

export default function DmScreen() {
  const { t } = useTranslation();
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const colors = useColors();
  const styles = makeStyles(colors);
  const queryClient = useQueryClient();
  const flatRef = useRef<FlatList>(null);
  const [myUserId, setMyUserId] = useState<string | undefined>(undefined);

  const colorScheme = useThemeStore((s) => s.colorScheme);
  const chatBg = colorScheme === 'dark' ? '#1a1f1e' : '#EDE8E1';

  const { userId } = useLocalSearchParams<{ userId: string }>();

  const [messages, setMessages] = useState<ChatMsg[]>([]);
  const [partner, setPartner] = useState<DmHistoryResponse['partner'] | null>(null);
  const partnerRef = useRef<DmHistoryResponse['partner'] | null>(null);
  const [replyTo, setReplyTo] = useState<{ id: string; nickname: string; content: string } | null>(
    null,
  );
  const [sending, setSending] = useState(false);

  // Reset aller conversation-spezifischen States wenn userId wechselt (Stack-Reuse)
  useEffect(() => {
    setMessages([]);
    setPartner(null);
    partnerRef.current = null;
    setReplyTo(null);
  }, [userId]);

  // Lade meine User-ID
  useEffect(() => {
    supabase.auth.getSession().then(({ data }) => {
      setMyUserId(data.session?.user.id);
    });
  }, []);

  // Lade DM-History — staleTime:0 erzwingt immer frischen Fetch (kein Cache-Hit-Bug)
  const { isLoading, isFetching } = useQuery({
    queryKey: ['dm-history', userId],
    queryFn: async () => {
      console.log('[dm] fetching history for partner', userId, 'me', myUserId);
      try {
        const data = await apiFetch<DmHistoryResponse>(`/api/chat/dm/${userId}`);
        console.log('[dm] partner:', data.partner?.nickname, 'msgs:', data.messages?.length);
        setPartner(data.partner);
        partnerRef.current = data.partner;
      const msgs: ChatMsg[] = data.messages.map((m: any) => ({
        id: m.id,
        userId: m.senderId ?? (m.isOwn ? myUserId ?? '' : userId),
        nickname: m.isOwn ? 'Du' : data.partner?.nickname ?? '?',
        avatar: m.isOwn ? null : data.partner?.avatar ?? null,
        content: m.content,
        replyTo: m.replyTo
          ? {
              id: m.replyTo.id,
              userId: m.replyTo.senderId,
              nickname:
                m.replyTo.senderId === myUserId ? 'Du' : data.partner?.nickname ?? '?',
              content: m.replyTo.content?.slice(0, 100) ?? '',
              attachmentType: m.replyTo.attachmentType ?? null,
            }
          : null,
        attachmentUrl: m.attachmentUrl ?? null,
        attachmentType: m.attachmentType ?? null,
        attachmentName: m.attachmentName ?? null,
        likesCount: m.likesCount ?? 0,
        likedByMe: m.likedByMe ?? false,
        createdAt: m.createdAt,
        isOwn: m.isOwn,
        readAt: m.readAt,
      }));
      setMessages(msgs);
      return data;
      } catch (err: any) {
        console.error('[dm] history fetch failed:', err?.message ?? err);
        throw err;
      }
    },
    enabled: !!userId && !!myUserId,
    staleTime: 0,
    gcTime: 0,
  });

  // Realtime: neue DMs vom Partner
  const onDmInsert = useCallback(
    (row: any) => {
      if (row.receiver_id !== myUserId) return;
      setMessages((prev) => {
        if (prev.some((m) => m.id === row.id)) return prev;
        const p = partnerRef.current;
        return [
          ...prev,
          {
            id: row.id,
            userId: row.sender_id,
            nickname: p?.nickname ?? '?',
            avatar: p?.avatar ?? null,
            content: row.content ?? '',
            replyTo: null,
            attachmentUrl: row.attachment_url ?? null,
            attachmentType: row.attachment_type ?? null,
            attachmentName: row.attachment_name ?? null,
            likesCount: row.likes_count ?? 0,
            likedByMe: false,
            createdAt: row.created_at,
            isOwn: false,
            readAt: null,
          },
        ];
      });
    },
    [myUserId],
  );
  useDmRealtime(userId, onDmInsert, !!myUserId);

  // Auto-Scroll bei neuen Messages
  useEffect(() => {
    if (messages.length > 0) {
      requestAnimationFrame(() => flatRef.current?.scrollToEnd({ animated: true }));
    }
  }, [messages.length]);

  async function handleSend(payload: SendPayload) {
    if (sending) return;
    setSending(true);
    try {
      const newMsg = await apiFetch<any>('/api/chat/dm', {
        method: 'POST',
        body: { receiverId: userId, ...payload },
      });
      setMessages((prev) => [
        ...prev,
        {
          id: newMsg.id,
          userId: myUserId ?? '',
          nickname: 'Du',
          avatar: null,
          content: newMsg.content,
          replyTo: newMsg.replyTo
            ? {
                id: newMsg.replyTo.id,
                userId: newMsg.replyTo.senderId,
                nickname:
                  newMsg.replyTo.senderId === myUserId ? 'Du' : partner?.nickname ?? '?',
                content: newMsg.replyTo.content?.slice(0, 100) ?? '',
                attachmentType: newMsg.replyTo.attachmentType ?? null,
              }
            : null,
          attachmentUrl: newMsg.attachmentUrl,
          attachmentType: newMsg.attachmentType,
          attachmentName: newMsg.attachmentName,
          likesCount: newMsg.likesCount ?? 0,
          likedByMe: false,
          createdAt: newMsg.createdAt,
          isOwn: true,
          readAt: null,
        },
      ]);
      setReplyTo(null);
      queryClient.invalidateQueries({ queryKey: ['dm-conversations'] });
    } catch (err) {
      console.error('DM send failed:', err);
    } finally {
      setSending(false);
    }
  }

  async function toggleLike(msg: ChatMsg) {
    try {
      const { liked } = await apiFetch<{ liked: boolean }>('/api/chat/like', {
        method: 'POST',
        body: { messageId: msg.id, type: 'dm' },
      });
      setMessages((prev) =>
        prev.map((m) =>
          m.id === msg.id
            ? { ...m, likedByMe: liked, likesCount: m.likesCount + (liked ? 1 : -1) }
            : m,
        ),
      );
    } catch {}
  }

  function startReply(msg: ChatMsg) {
    setReplyTo({
      id: msg.id,
      nickname: msg.nickname ?? '?',
      content: msg.content?.slice(0, 100) || (msg.attachmentType === 'image' ? 'Bild' : ''),
    });
  }

  function sameAuthor(a: ChatMsg | undefined, b: ChatMsg | undefined): boolean {
    if (!a || !b) return false;
    if (a.userId !== b.userId) return false;
    return Math.abs(new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) <= GROUP_GAP_MS;
  }

  return (
    <SafeAreaView style={styles.container} edges={['top']}>
      {/* Header */}
      <View style={styles.header}>
        <TouchableOpacity style={styles.backBtn} onPress={() => router.back()} hitSlop={8} activeOpacity={0.7}>
          <Ionicons name="chevron-back" size={22} color={colors.text} />
        </TouchableOpacity>
        <View style={styles.headerCenter}>
          <View style={styles.headerAvatar}>
            {partner?.avatar ? (
              <Image source={{ uri: resolveAvatar(partner.avatar, partner.nickname ?? '') }} style={styles.headerAvatarImg} />
            ) : (
              <Text style={styles.headerAvatarInitials}>
                {(partner?.nickname ?? '?').slice(0, 2).toUpperCase()}
              </Text>
            )}
          </View>
          <Text style={styles.headerName} numberOfLines={1}>
            {partner?.nickname ?? '…'}
          </Text>
        </View>
      </View>

      <KeyboardAvoidingView
        style={{ flex: 1 }}
        behavior="padding"
        keyboardVerticalOffset={0}
      >
        <View style={{ flex: 1, backgroundColor: chatBg }}>
          <DmChatBackground />
          {(isLoading || isFetching) && messages.length === 0 ? (
            <View style={styles.loadingBox}>
              <ActivityIndicator color={colors.brandOrange} />
            </View>
          ) : messages.length === 0 ? (
            <View style={styles.loadingBox}>
              <Ionicons name="chatbubble-outline" size={42} color="#d4d4d4" />
              <Text style={styles.emptyText}>{t('chat.no_chats')}</Text>
            </View>
          ) : (
            <FlatList
              ref={flatRef}
              data={messages}
              style={{ flex: 1 }}
              renderItem={({ item, index }) => (
                <ChatBubble
                  msg={item}
                  isFirstInGroup={!sameAuthor(messages[index - 1], item)}
                  isLastInGroup={!sameAuthor(item, messages[index + 1])}
                  onReply={startReply}
                  onLike={toggleLike}
                  onOpenImage={() => {}}
                />
              )}
              keyExtractor={(m) => m.id}
              contentContainerStyle={{ paddingTop: 12, paddingBottom: 8 }}
              showsVerticalScrollIndicator={false}
              onContentSizeChange={() => flatRef.current?.scrollToEnd({ animated: false })}
            />
          )}
        </View>

        <View style={{ paddingBottom: Math.max(insets.bottom - 8, 0) }}>
          <ChatInput
            replyTo={replyTo}
            sending={sending}
            onSend={handleSend}
            onCancelReply={() => setReplyTo(null)}
          />
        </View>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
}

function makeStyles(colors: ReturnType<typeof useColors>) {
  return StyleSheet.create({
    container: { flex: 1, backgroundColor: colors.bg },
    header: {
      flexDirection: 'row',
      alignItems: 'center',
      paddingHorizontal: 12,
      paddingVertical: 10,
      backgroundColor: colors.bg,
      borderBottomWidth: StyleSheet.hairlineWidth,
      borderBottomColor: colors.border,
    },
    backBtn: {
      width: 36,
      height: 36,
      borderRadius: 12,
      backgroundColor: colors.surfaceElevated,
      alignItems: 'center',
      justifyContent: 'center',
    },
    headerCenter: {
      flex: 1,
      flexDirection: 'row',
      alignItems: 'center',
      marginLeft: 8,
    },
    headerAvatar: {
      width: 32,
      height: 32,
      borderRadius: 16,
      backgroundColor: colors.surfaceElevated,
      alignItems: 'center',
      justifyContent: 'center',
      overflow: 'hidden',
      marginRight: 8,
    },
    headerAvatarImg: { width: 32, height: 32 },
    headerAvatarInitials: {
      fontSize: 11,
      fontFamily: 'Nunito_700Bold',
      color: colors.textMuted,
    },
    headerName: {
      fontSize: 15,
      fontFamily: 'Nunito_700Bold',
      color: colors.text,
      flexShrink: 1,
    },
    loadingBox: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
    },
    emptyText: {
      fontSize: 13,
      fontFamily: 'Nunito_600SemiBold',
      color: colors.textMuted,
      marginTop: 12,
    },
  });
}
