import React, { useState, useRef, useCallback, useMemo, useEffect } from "react";
import {
  View,
  Text,
  FlatList,
  TextInput,
  TouchableOpacity,
  StyleSheet,
  SafeAreaView,
  KeyboardAvoidingView,
  Platform,
  ActivityIndicator,
  Image,
} from "react-native";
import { useLocalSearchParams, router } from "expo-router";
import { useFocusEffect } from "@react-navigation/native";
import { ArrowLeft, Send, MessageCircle } from "lucide-react-native";
import { PRIMARY } from "@/constants/colors";
import {
  buildTimelineItems,
  type MessageGroup,
  type TimelineItem,
} from "@/features/chat/channelTimeline";
import { getMessageAuthorDisplay } from "@/features/chat/messageAuthor";
import { useThemeColor } from "@/hooks/useThemeColor";
import { useColorScheme } from "@/hooks/useColorScheme";
import { useChat } from "@/hooks/chat";
import { useTablosList } from "@/hooks/tablos";
import { useTabloMembers, TabloMember } from "@/hooks/members";
import { useQueryClient } from "@tanstack/react-query";
import { ChatMessage } from "@/types/chat.types";
import { useAuthStore } from "@/stores/auth";

const MESSAGE_GROUP_INTERVAL = 2 * 60 * 1000; // 2 minutes in ms

function groupMessages(messages: ChatMessage[], currentUserId: string): MessageGroup[] {
  const groups: MessageGroup[] = [];

  for (const msg of messages) {
    const lastGroup = groups[groups.length - 1];
    const timeDiff = lastGroup
      ? new Date(msg.createdAt).getTime() -
        new Date(lastGroup.messages[lastGroup.messages.length - 1].createdAt).getTime()
      : Infinity;

    if (lastGroup && lastGroup.userId === msg.userId && timeDiff < MESSAGE_GROUP_INTERVAL) {
      lastGroup.messages.push(msg);
    } else {
      groups.push({
        key: msg.id,
        userId: msg.userId,
        messages: [msg],
        isOwn: msg.userId === currentUserId,
      });
    }
  }

  return groups;
}

export default function ChannelScreen() {
  const { cid } = useLocalSearchParams<{ cid: string }>();
  const channelId = cid;
  const session = useAuthStore((state) => state.session);
  const currentUser = useAuthStore((state) => state.user);
  const currentUserId = session?.user?.id ?? "";
  const queryClient = useQueryClient();

  const colorScheme = useColorScheme();
  const isDark = colorScheme === "dark";
  const bgColor = useThemeColor({ light: "#f8fafc", dark: "#111827" }, "background");
  const textColor = useThemeColor({ light: "#1f2937", dark: "#f9fafb" }, "text");
  const subtextColor = useThemeColor({ light: "#6b7280", dark: "#9ca3af" }, "text");
  const inputBg = useThemeColor({ light: "#f1f5f9", dark: "#374151" }, "background");
  const headerBg = useThemeColor({ light: "#ffffff", dark: "#1f2937" }, "background");
  const borderColor = isDark ? "#374151" : "#e5e7eb";
  const ownBubbleBg = PRIMARY;
  const otherBubbleBg = isDark ? "#374151" : "#e5e7eb";

  const {
    messages,
    sendMessage,
    sendTyping,
    isConnected,
    typingUsers,
    onlineUsers,
    loadMoreMessages,
    hasMoreMessages,
    markAsRead,
  } = useChat(channelId);

  const { data: tablos } = useTablosList();
  const { data: members } = useTabloMembers(channelId);
  const tablo = tablos?.find((t) => t.id === channelId);

  const [inputText, setInputText] = useState("");
  const [failedAvatarUserIds, setFailedAvatarUserIds] = useState<Record<string, boolean>>({});
  const flatListRef = useRef<FlatList>(null);

  useEffect(() => {
    setFailedAvatarUserIds({});
  }, [channelId]);

  // Build user lookup map
  const userMap = useMemo(() => {
    const map: Record<string, TabloMember> = {};
    members?.forEach((m: TabloMember) => { map[m.id] = m; });
    return map;
  }, [members]);

  // Mark as read when screen gains focus
  useFocusEffect(
    useCallback(() => {
      markAsRead();
      queryClient.invalidateQueries({ queryKey: ["chat-unread"] });
    }, [markAsRead, queryClient])
  );

  const separatorColor = isDark ? "#4b5563" : "#d1d5db";

  // Build timeline items in chronological order, then reverse for inverted FlatList.
  const timelineItems = useMemo(() => {
    const messageGroups = groupMessages(messages, currentUserId);
    return buildTimelineItems(messageGroups, new Date()).reverse();
  }, [messages, currentUserId]);

  const handleSend = () => {
    const text = inputText.trim();
    if (!text) return;
    sendMessage(text);
    setInputText("");
  };

  const handleTextChange = (text: string) => {
    setInputText(text);
    sendTyping();
  };

  // Typing indicator text
  const typingText = useMemo(() => {
    if (typingUsers.length === 0) return null;
    const names = typingUsers.map((id) => userMap[id]?.name ?? "Quelqu'un");
    if (names.length === 1) return `${names[0]} est en train d'écrire...`;
    return `${names.join(" et ")} sont en train d'écrire...`;
  }, [typingUsers, userMap]);

  const renderMessageGroup = (item: MessageGroup) => {
    const author = getMessageAuthorDisplay({
      userId: item.userId,
      members: userMap,
      currentUser,
      failedAvatarUserIds,
    });
    const timestamp = new Date(item.messages[0].createdAt).toLocaleTimeString("fr-FR", {
      hour: "2-digit",
      minute: "2-digit",
    });
    const avatar = author.avatarUrl ? (
      <Image
        source={{ uri: author.avatarUrl }}
        style={styles.avatarImage}
        onError={() => {
          setFailedAvatarUserIds((prev) =>
            prev[item.userId] ? prev : { ...prev, [item.userId]: true }
          );
        }}
      />
    ) : (
      <View style={styles.avatar}>
        <Text style={styles.avatarText}>{author.initial}</Text>
      </View>
    );

    return (
      <View style={[styles.groupContainer, item.isOwn && styles.groupContainerOwn]}>
        <View style={[styles.senderRow, item.isOwn && styles.senderRowOwn]}>
          {item.isOwn ? (
            <>
              <Text style={[styles.timestamp, { color: subtextColor }]}>{timestamp}</Text>
              <Text style={[styles.senderName, { color: subtextColor }]}>{author.name}</Text>
              {avatar}
            </>
          ) : (
            <>
              {avatar}
              <Text style={[styles.senderName, { color: subtextColor }]}>{author.name}</Text>
              <Text style={[styles.timestamp, { color: subtextColor }]}>{timestamp}</Text>
            </>
          )}
        </View>

        {item.messages.map((msg) => (
          <View
            key={msg.id}
            style={[
              styles.bubble,
              item.isOwn
                ? [styles.bubbleOwn, { backgroundColor: ownBubbleBg }]
                : [styles.bubbleOther, { backgroundColor: otherBubbleBg }],
              msg.optimistic && styles.bubbleOptimistic,
            ]}
          >
            <Text style={[styles.messageText, { color: item.isOwn ? "#ffffff" : textColor }]}>
              {msg.text}
            </Text>
          </View>
        ))}
      </View>
    );
  };

  const renderTimelineItem = ({ item }: { item: TimelineItem }) => {
    if (item.type === "day-separator") {
      return (
        <View style={styles.daySeparator}>
          <View style={[styles.daySeparatorLine, { backgroundColor: separatorColor }]} />
          <Text style={[styles.daySeparatorLabel, { color: subtextColor }]}>{item.label}</Text>
          <View style={[styles.daySeparatorLine, { backgroundColor: separatorColor }]} />
        </View>
      );
    }

    return renderMessageGroup(item.group);
  };

  return (
    <SafeAreaView style={[styles.container, { backgroundColor: bgColor }]}>
      {/* Header */}
      <View style={[styles.header, { backgroundColor: headerBg, borderBottomColor: borderColor }]}>
        <TouchableOpacity onPress={() => router.back()} style={styles.backButton}>
          <ArrowLeft size={22} color={textColor} />
        </TouchableOpacity>
        <View style={styles.headerContent}>
          <Text style={[styles.headerTitle, { color: textColor }]} numberOfLines={1}>
            {tablo?.name ?? "Discussion"}
          </Text>
          {onlineUsers.length > 0 && (
            <Text style={[styles.headerSubtitle, { color: subtextColor }]}>
              {onlineUsers.length} en ligne
            </Text>
          )}
        </View>
      </View>

      {/* Connection banner */}
      {!isConnected && (
        <View style={styles.connectionBanner}>
          <Text style={styles.connectionText}>Reconnexion...</Text>
        </View>
      )}

      <KeyboardAvoidingView
        style={styles.content}
        behavior={Platform.OS === "ios" ? "padding" : undefined}
      >
        {/* Message list */}
        {messages.length === 0 ? (
          <View style={styles.emptyState}>
            <MessageCircle size={48} color={subtextColor} strokeWidth={1.5} />
            <Text style={[styles.emptyTitle, { color: textColor }]}>
              Commencez la conversation
            </Text>
            <Text style={{ color: subtextColor, textAlign: "center" }}>
              Soyez le premier à envoyer un message !
            </Text>
          </View>
        ) : (
          <FlatList
            ref={flatListRef}
            data={timelineItems}
            keyExtractor={(item) => item.key}
            renderItem={renderTimelineItem}
            inverted
            onEndReached={loadMoreMessages}
            onEndReachedThreshold={0.3}
            ListFooterComponent={
              hasMoreMessages ? (
                <ActivityIndicator style={styles.loadingMore} color={PRIMARY} />
              ) : null
            }
            contentContainerStyle={styles.messageListContent}
          />
        )}

        {/* Typing indicator */}
        {typingText && (
          <View style={[styles.typingBar, { borderTopColor: borderColor }]}>
            <Text style={[styles.typingText, { color: subtextColor }]}>{typingText}</Text>
          </View>
        )}

        {/* Input */}
        <View style={[styles.inputContainer, { borderTopColor: borderColor }]}>
          <TextInput
            style={[styles.input, { backgroundColor: inputBg, color: textColor }]}
            value={inputText}
            onChangeText={handleTextChange}
            placeholder="Message..."
            placeholderTextColor="#9ca3af"
            multiline
            maxLength={4000}
          />
          <TouchableOpacity
            style={[styles.sendButton, !inputText.trim() && styles.sendButtonDisabled]}
            onPress={handleSend}
            disabled={!inputText.trim()}
          >
            <Send size={20} color={inputText.trim() ? PRIMARY : "#9ca3af"} />
          </TouchableOpacity>
        </View>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    flexDirection: "row",
    alignItems: "center",
    paddingHorizontal: 12,
    paddingVertical: 12,
    borderBottomWidth: StyleSheet.hairlineWidth,
    gap: 10,
  },
  backButton: {
    padding: 4,
  },
  headerContent: {
    flex: 1,
  },
  headerTitle: {
    fontSize: 17,
    fontWeight: "700",
  },
  headerSubtitle: {
    fontSize: 12,
    marginTop: 1,
  },
  connectionBanner: {
    backgroundColor: "#f59e0b",
    paddingVertical: 4,
    alignItems: "center",
  },
  connectionText: {
    color: "#ffffff",
    fontSize: 12,
    fontWeight: "600",
  },
  content: {
    flex: 1,
  },
  messageListContent: {
    paddingHorizontal: 12,
    paddingVertical: 8,
  },
  emptyState: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    gap: 12,
    paddingHorizontal: 40,
  },
  emptyTitle: {
    fontSize: 20,
    fontWeight: "700",
  },
  loadingMore: {
    paddingVertical: 16,
  },
  daySeparator: {
    flexDirection: "row",
    alignItems: "center",
    alignSelf: "stretch",
    gap: 12,
    marginVertical: 12,
  },
  daySeparatorLine: {
    flex: 1,
    height: StyleSheet.hairlineWidth,
  },
  daySeparatorLabel: {
    fontSize: 12,
    fontWeight: "600",
    textTransform: "uppercase",
    letterSpacing: 0.4,
  },
  groupContainer: {
    marginBottom: 12,
    maxWidth: "80%",
    alignSelf: "flex-start",
  },
  groupContainerOwn: {
    alignSelf: "flex-end",
  },
  senderRow: {
    flexDirection: "row",
    alignItems: "center",
    gap: 6,
    marginBottom: 4,
  },
  senderRowOwn: {
    justifyContent: "flex-end",
  },
  avatar: {
    width: 24,
    height: 24,
    borderRadius: 12,
    backgroundColor: PRIMARY,
    alignItems: "center",
    justifyContent: "center",
  },
  avatarImage: {
    width: 24,
    height: 24,
    borderRadius: 12,
  },
  avatarText: {
    color: "#ffffff",
    fontSize: 11,
    fontWeight: "700",
  },
  senderName: {
    fontSize: 12,
    fontWeight: "600",
  },
  timestamp: {
    fontSize: 11,
  },
  bubble: {
    paddingHorizontal: 12,
    paddingVertical: 8,
    borderRadius: 16,
    marginBottom: 2,
  },
  bubbleOwn: {
    borderBottomRightRadius: 4,
  },
  bubbleOther: {
    borderBottomLeftRadius: 4,
  },
  bubbleOptimistic: {
    opacity: 0.7,
  },
  messageText: {
    fontSize: 15,
    lineHeight: 20,
  },
  typingBar: {
    paddingHorizontal: 16,
    paddingVertical: 6,
    borderTopWidth: StyleSheet.hairlineWidth,
  },
  typingText: {
    fontSize: 12,
    fontStyle: "italic",
  },
  inputContainer: {
    flexDirection: "row",
    alignItems: "flex-end",
    paddingHorizontal: 12,
    paddingVertical: 8,
    borderTopWidth: StyleSheet.hairlineWidth,
    gap: 8,
  },
  input: {
    flex: 1,
    borderRadius: 20,
    paddingHorizontal: 16,
    paddingVertical: 10,
    fontSize: 15,
    maxHeight: 100,
  },
  sendButton: {
    padding: 10,
  },
  sendButtonDisabled: {
    opacity: 0.5,
  },
});
