import {
  View,
  Text,
  FlatList,
  TextInput,
  TouchableOpacity,
  KeyboardAvoidingView,
  Platform,
  ActivityIndicator,
  StyleSheet,
  RefreshControl,
} from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import { useLocalSearchParams, useRouter } from 'expo-router'
import { Ionicons } from '@expo/vector-icons'
import { useState, useRef, useMemo, useCallback } from 'react'
import { format } from 'date-fns'
import { de } from 'date-fns/locale'
import { trpc } from '@/lib/trpc'
import { useAuthStore } from '@/store/auth.store'

type Message = {
  id: string
  body: string
  createdAt: Date
  sender: { id: string; name: string; avatarUrl: string | null }
}

function MessageBubble({ msg, isMe }: { msg: Message; isMe: boolean }) {
  return (
    <View style={[styles.messageBubbleContainer, isMe ? styles.messageBubbleRight : styles.messageBubbleLeft]}>
      <View
        style={[
          styles.messageBubble,
          isMe ? styles.messageBubbleMe : styles.messageBubbleOther
        ]}
      >
        <Text style={[styles.messageText, isMe ? styles.messageTextMe : styles.messageTextOther]}>
          {msg.body}
        </Text>
        <Text
          style={[styles.messageTime, isMe ? styles.messageTimeMe : styles.messageTimeOther]}
        >
          {format(new Date(msg.createdAt), 'HH:mm', { locale: de })}
        </Text>
      </View>
    </View>
  )
}

export default function ConversationScreen() {
  const { id, name } = useLocalSearchParams<{ id: string; name: string }>()
  const router = useRouter()
  const session = useAuthStore((s) => s.session)
  const [text, setText] = useState('')
  const listRef = useRef<FlatList>(null)
  // Hide list until inverted FlatList has settled at correct position (prevents initial jump)
  const [listVisible, setListVisible] = useState(false)
  const onListLayout = useCallback(() => setListVisible(true), [])

  const [refreshing, setRefreshing] = useState(false)
  const onRefresh = useCallback(async () => {
    setRefreshing(true)
    try {
      await refetch()
    } finally {
      setRefreshing(false)
    }
  }, [])

  const { data, isLoading, refetch, isRefetching } = trpc.messages.getMessages.useQuery(
    { conversationId: id },
    {
      staleTime: 5_000,
      refetchInterval: 8_000,
      // Only re-render when message count or last message ID changes — not on every refetch
      select: (d) => d,
    }
  )

  // Stable deps: only recalculate when actual message content changes, not on every refetch
  const msgCount = data?.messages?.length ?? 0
  const lastId = data?.messages?.[msgCount - 1]?.id ?? ''
  const messages = useMemo(() => [...(data?.messages ?? [])].reverse(), [msgCount, lastId])

  // Stable "me" id: derived from real (non-optimistic) messages only
  const myMemberId = useMemo(
    () => messages.find((m: Message) => !m.id.startsWith('opt-') && m.sender.name === session?.user?.name)?.sender.id,
    [messages, session?.user?.name]
  )

  const utils = trpc.useUtils()
  const sendMutation = trpc.messages.sendMessage.useMutation({
    onMutate: ({ conversationId, body }) => {
      // Optimistically insert message immediately — no waiting for server
      const optimisticMsg: Message = {
        id: `opt-${Date.now()}`,
        body,
        createdAt: new Date(),
        sender: {
          id: myMemberId ?? `opt-sender`,
          name: session?.user?.name ?? '',
          avatarUrl: null,
        },
      }
      utils.messages.getMessages.setData(
        { conversationId },
        (old) => {
          if (!old) return old
          // Append at end — messages are stored ascending, reversed only in useMemo for display
          return { ...old, messages: [...old.messages, optimisticMsg] }
        }
      )
      setText('')
      return { optimisticId: optimisticMsg.id }
    },
    onSuccess: (newMsg, { conversationId }, context) => {
      // Replace optimistic placeholder with real server message
      utils.messages.getMessages.setData(
        { conversationId },
        (old) => {
          if (!old) return old
          return {
            ...old,
            messages: old.messages.map((m) =>
              m.id === context?.optimisticId ? newMsg : m
            ),
          }
        }
      )
      utils.messages.getConversations.invalidate()
    },
    onError: (_, { conversationId }, context) => {
      // Roll back optimistic message on error
      utils.messages.getMessages.setData(
        { conversationId },
        (old) => {
          if (!old) return old
          return {
            ...old,
            messages: old.messages.filter((m) => m.id !== context?.optimisticId),
          }
        }
      )
    },
  })

  function handleSend() {
    const body = text.trim()
    if (!body) return
    sendMutation.mutate({ conversationId: id, body })
  }

  return (
    <SafeAreaView style={styles.safeArea} edges={['top', 'bottom']}>
      <KeyboardAvoidingView
        style={styles.keyboardAvoid}
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}
      >
        {/* Header */}
        <View style={styles.header}>
          <TouchableOpacity onPress={() => router.back()} style={styles.backButton}>
            <Ionicons name="chevron-back" size={26} color="#003B7E" />
          </TouchableOpacity>
          <View style={styles.headerInfo}>
            <Text style={styles.headerName} numberOfLines={1}>
              {name ?? 'Chat'}
            </Text>
            <Text style={styles.headerStatus}>Mitglied</Text>
          </View>
        </View>
        <View style={styles.divider} />

        {/* Messages */}
        <View style={styles.content}>
          {isLoading ? (
            <View style={styles.centerCont}>
              <ActivityIndicator size="large" color="#003B7E" />
            </View>
          ) : (
            <FlatList
              ref={listRef}
              data={messages}
              keyExtractor={(m) => m.id}
              inverted
              maintainVisibleContentPosition={{ minIndexForVisible: 0, autoscrollToTopThreshold: 10 }}
              onLayout={onListLayout}
              style={{ opacity: listVisible ? 1 : 0 }}
              contentContainerStyle={styles.messageList}
              refreshControl={
                <RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor="#003B7E" />
              }
              ListEmptyComponent={
                <View style={[styles.emptyState, { transform: [{ scaleY: -1 }] }]}>
                  <Ionicons name="chatbubble-ellipses-outline" size={48} color="#CBD5E1" />
                  <Text style={styles.emptyText}>
                    Noch keine Nachrichten. Schreib die erste!
                  </Text>
                  <View style={styles.privacyNoteBoxCentered}>
                    <Ionicons name="shield-checkmark-outline" size={16} color="#2563EB" />
                    <Text style={styles.privacyNoteText}>
                      Nachrichten sind nur für euch beide sichtbar. Keine Weitergabe an Dritte (DSGVO-konform).
                    </Text>
                  </View>
                </View>
              }
              renderItem={({ item }) => (
                <MessageBubble
                  msg={item as Message}
                  isMe={item.sender.id === myMemberId}
                />
              )}
            />
          )}
        </View>

        {/* Input */}
        <View style={styles.inputContainer}>
          <TextInput
            style={styles.inputField}
            placeholder="Nachricht …"
            placeholderTextColor="#94A3B8"
            value={text}
            onChangeText={setText}
            multiline
            returnKeyType="default"
            blurOnSubmit={false}
          />
          <TouchableOpacity
            onPress={handleSend}
            disabled={!text.trim() || sendMutation.isPending}
            style={[styles.sendButton, text.trim() ? styles.sendButtonActive : styles.sendButtonInactive]}
          >
            {sendMutation.isPending ? (
              <ActivityIndicator size="small" color="#fff" />
            ) : (
              <Ionicons name="send" size={18} color={text.trim() ? '#fff' : '#94A3B8'} />
            )}
          </TouchableOpacity>
        </View>
      </KeyboardAvoidingView>
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: '#FFFFFF',
  },
  keyboardAvoid: {
    flex: 1,
    backgroundColor: '#F8FAFC',
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 16,
    paddingVertical: 12,
    backgroundColor: '#FFFFFF',
  },
  backButton: {
    padding: 4,
    marginRight: 8,
  },
  headerInfo: {
    flex: 1,
  },
  headerName: {
    fontSize: 18,
    fontWeight: '700',
    color: '#0F172A',
  },
  headerStatus: {
    fontSize: 12,
    color: '#64748B',
    marginTop: 2,
  },
  divider: {
    height: 1,
    backgroundColor: '#E2E8F0',
  },
  content: {
    flex: 1,
  },
  centerCont: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  messageList: {
    paddingTop: 16,
    paddingBottom: 8,
  },
  emptyState: {
    flex: 1,
    alignItems: 'flex-start',
    justifyContent: 'flex-start',
    paddingVertical: 16,
    paddingHorizontal: 16,
  },
  emptyText: {
    color: '#0F172A',
    marginTop: 12,
    textAlign: 'left',
    fontSize: 16,
  },
  privacyNoteBoxCentered: {
    flexDirection: 'row',
    alignItems: 'flex-start',
    padding: 0,
    marginTop: 16,
    gap: 8,
  },
  privacyNoteText: {
    fontSize: 14,
    color: '#0F172A',
    lineHeight: 20,
    flex: 1,
  },
  messageBubbleContainer: {
    flexDirection: 'row',
    marginBottom: 8,
    paddingHorizontal: 16,
  },
  messageBubbleRight: {
    justifyContent: 'flex-end',
  },
  messageBubbleLeft: {
    justifyContent: 'flex-start',
  },
  messageBubble: {
    maxWidth: '78%',
    paddingHorizontal: 16,
    paddingVertical: 10,
  },
  messageBubbleMe: {
    backgroundColor: '#2563EB',
    borderTopLeftRadius: 16,
    borderTopRightRadius: 16,
    borderBottomLeftRadius: 16,
    borderBottomRightRadius: 4,
  },
  messageBubbleOther: {
    backgroundColor: '#FFFFFF',
    borderTopLeftRadius: 16,
    borderTopRightRadius: 16,
    borderBottomRightRadius: 16,
    borderBottomLeftRadius: 4,
    borderWidth: 1,
    borderColor: '#E2E8F0',
  },
  messageText: {
    fontSize: 15,
    lineHeight: 20,
  },
  messageTextMe: {
    color: '#FFFFFF',
  },
  messageTextOther: {
    color: '#0F172A',
  },
  messageTime: {
    fontSize: 10,
    marginTop: 4,
  },
  messageTimeMe: {
    color: '#BFDBFE',
    textAlign: 'right',
  },
  messageTimeOther: {
    color: '#94A3B8',
    textAlign: 'left',
  },
  inputContainer: {
    flexDirection: 'row',
    alignItems: 'flex-end',
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderTopWidth: 1,
    borderTopColor: '#E2E8F0',
    backgroundColor: '#FFFFFF',
    gap: 8,
  },
  inputField: {
    flex: 1,
    backgroundColor: '#F1F5F9',
    borderRadius: 20,
    paddingHorizontal: 16,
    paddingTop: 12,
    paddingBottom: 12,
    fontSize: 15,
    color: '#0F172A',
    maxHeight: 120,
    minHeight: 44,
  },
  sendButton: {
    width: 44,
    height: 44,
    borderRadius: 22,
    alignItems: 'center',
    justifyContent: 'center',
  },
  sendButtonActive: {
    backgroundColor: '#2563EB',
  },
  sendButtonInactive: {
    backgroundColor: '#E2E8F0',
  },
})
