import { useMemo, useState, useCallback } from "react";
import { View, ScrollView, TextInput, Pressable, Text } from "react-native";
import { Avatar, Button, Menu } from "react-native-paper";
import { Ionicons } from "@expo/vector-icons";
import { formatDistanceToNow, formatDistanceToNowStrict } from "date-fns";

import {
  useGetTodoCommentsQuery,
  useAddCommentMutation,
  useUpdateCommentMutation,
  useDeleteCommentMutation,
} from "@/store/api/commentsApi";
import { useAuthContext } from "@/auth/AuthContext";
import { useGetUsersQuery } from "@/store/api/usersApi";
import { AppSnackbar } from "@/components/ui/AppSnackbar";

interface TodoCommentsProps {
  todoId: string;
}

// Helper: compact relative time like "2h ago"
const timeAgo = (dateInput: string | Date | null | undefined) => {
  if (!dateInput) return "";
  const date = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
  try {
    const raw = formatDistanceToNowStrict(date, { addSuffix: false });
    // raw examples: "2 hours", "1 minute", "less than a minute"
    const m = raw.match(
      /(\d+)\s+(second|seconds|minute|minutes|hour|hours|day|days|week|weeks|month|months|year|years)/
    );
    if (m) {
      const n = m[1];
      const unit = m[2];
      const abbr = unit.startsWith("second")
        ? "s"
        : unit.startsWith("minute")
        ? "m"
        : unit.startsWith("hour")
        ? "h"
        : unit.startsWith("day")
        ? "d"
        : unit.startsWith("week")
        ? "w"
        : unit.startsWith("month")
        ? "mo"
        : "y";
      return `${n}${abbr} ago`;
    }
    // fallback to full format
    return formatDistanceToNow(date, { addSuffix: true });
  } catch {
    return "";
  }
};

const LONG_COMMENT_THRESHOLD = 220;

interface TodoCommentsProps {
  todoId: string;
}

export const TodoComments = ({ todoId }: TodoCommentsProps) => {
  const { user } = useAuthContext();
  const {
    data: comments,
    isLoading,
    isError,
    refetch,
  } = useGetTodoCommentsQuery(todoId);
  const [addComment, { isLoading: isAdding }] = useAddCommentMutation();
  const [updateComment, { isLoading: isUpdating }] = useUpdateCommentMutation();
  const [deleteComment, { isLoading: isDeleting }] = useDeleteCommentMutation();
  const [content, setContent] = useState("");
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editContent, setEditContent] = useState("");
  const [snackbarMessage, setSnackbarMessage] = useState("");
  const [snackbarVisible, setSnackbarVisible] = useState(false);
  const [expanded, setExpanded] = useState<Record<string, boolean>>({});
  const [menuId, setMenuId] = useState<string | null>(null);

  const showSnackbar = (message: string) => {
    setSnackbarMessage(message);
    setSnackbarVisible(true);
  };

  const canPost = useMemo(() => !!user, [user]);

  const handleSubmit = async () => {
    const trimmed = content.trim();
    if (!trimmed) return;
    try {
      await addComment({ todoId, content: trimmed }).unwrap();
      setContent("");
    } catch {
      showSnackbar("Error creating comment");
    }
  };

  const startEdit = (id: string, current: string) => {
    setEditingId(id);
    setEditContent(current);
  };

  const cancelEdit = () => {
    setEditingId(null);
    setEditContent("");
  };

  const saveEdit = async () => {
    const trimmed = editContent.trim();
    if (!editingId || !trimmed) return;
    try {
      await updateComment({
        todoId,
        commentId: editingId,
        content: trimmed,
      }).unwrap();
      setEditingId(null);
      setEditContent("");
    } catch {
      showSnackbar("Error updating comment");
    }
  };

  const onDelete = async (id: string) => {
    try {
      // simple confirm for web; on native it won't show but action still works if called
      if (typeof window !== "undefined") {
        const ok = window.confirm?.("Delete this comment?") ?? true;
        if (!ok) return;
      }
      await deleteComment({ todoId, commentId: id }).unwrap();
    } catch {
      showSnackbar("Error deleting comment");
    }
  };

  // Mention support
  const extractMentionQuery = useCallback((text: string) => {
    // find last segment starting with @ that has no whitespace afterwards yet
    const match = text.match(/@([\w.-]{1,30})$/);
    return match ? match[1] : "";
  }, []);

  const mentionQuery = extractMentionQuery(editingId ? editContent : content);
  const { data: mentionUsers } = useGetUsersQuery(
    mentionQuery
      ? { search: mentionQuery, page: 1, limit: 5, roleType: "admin" }
      : undefined,
    { skip: !mentionQuery }
  );

  const insertMention = (fullName: string) => {
    const setter = editingId ? setEditContent : setContent;
    const text = editingId ? editContent : content;
    // replace trailing @query with @Full Name and a space
    const replaced = text.replace(/@([\w.-]{1,30})$/, `@${fullName} `);
    setter(replaced);
  };

  const renderContentWithMentions = (text: string) => {
    const parts = text.split(/(@[\w.-]+)/g);
    return parts.map((p, i) =>
      p.startsWith("@") ? (
        <Text key={i} className="text-primaryPurpleDark font-medium">
          {p}
        </Text>
      ) : (
        <Text key={i}>{p}</Text>
      )
    );
  };

  const getCommentAuthorName = (commentUser: {
    id: string;
    firstName?: string;
    lastName?: string;
  }) => {
    if (!commentUser) return "Unknown User";
    if (commentUser.id === user?.id) return "You";
    return `${(commentUser.firstName || "").trim()} ${(
      commentUser.lastName || ""
    ).trim()}`.trim();
  };

  return (
    <>
      <View className="flex-1">
        <Text className="text-lg mb-2">Comments</Text>
        {isLoading ? (
          <Text>Loading comments...</Text>
        ) : isError ? (
          <View>
            <Text className="text-red-500 mb-2">Failed to load comments</Text>
            <Button mode="text" onPress={refetch}>
              Retry
            </Button>
          </View>
        ) : comments && comments.length > 0 ? (
          <ScrollView
            className="max-h-96"
            contentContainerStyle={{ paddingBottom: 8, paddingTop: 4 }}
            showsVerticalScrollIndicator
            nestedScrollEnabled
            keyboardShouldPersistTaps="handled"
            keyboardDismissMode="on-drag"
            scrollEnabled
            persistentScrollbar
            style={{ maxHeight: 384, minHeight: 0, flexGrow: 0 }}
          >
            {comments.map((c, idx) => {
              const isExpanded = !!expanded[c.id];
              const isLong = (c.content?.length || 0) > LONG_COMMENT_THRESHOLD;
              const prevUserId = idx > 0 ? comments[idx - 1]?.user?.id : null;
              const isNewUserBlock = idx > 0 && prevUserId !== c.user?.id;

              return (
                <View key={c.id} className="mb-2">
                  {isNewUserBlock ? (
                    <View
                      style={{
                        height: 1,
                        backgroundColor: "#D9D9D9",
                        marginVertical: 8,
                      }}
                    />
                  ) : null}
                  <View className="py-1">
                    <View className="flex-row">
                      {c.user?.imageUrl ? (
                        <Avatar.Image
                          source={{ uri: c.user.imageUrl }}
                          size={32}
                          style={{ marginRight: 10, marginTop: 0 }}
                        />
                      ) : (
                        <Avatar.Text
                          label={
                            (c.user?.firstName?.[0] || "?") +
                            (c.user?.lastName?.[0] || "").toUpperCase()
                          }
                          size={32}
                          style={{ marginRight: 10, marginTop: 0 }}
                        />
                      )}
                      <View className="flex-1">
                        <View
                          className="flex-row justify-between items-center"
                          style={{ minHeight: 18, marginBottom: 6 }}
                        >
                          <View className="flex-1 pr-2" style={{ minWidth: 0 }}>
                            <Text
                              className="text-[13px] font-medium text-gray-900"
                              numberOfLines={1}
                              style={{ lineHeight: 18 }}
                            >
                              {getCommentAuthorName(c.user)}
                            </Text>
                          </View>
                          <View className="flex-row items-center">
                            <Text className="text-[11px] text-gray-500">
                              {timeAgo(c.createdAt)}
                            </Text>
                            <View className="ml-2" style={{ flexShrink: 0 }}>
                              {user?.id === c.user?.id && editingId !== c.id ? (
                                <Menu
                                  visible={menuId === c.id}
                                  onDismiss={() => setMenuId(null)}
                                  anchor={
                                    <Pressable
                                      onPress={() => setMenuId(c.id)}
                                      style={{
                                        height: 18,
                                        width: 18,
                                        alignItems: "center",
                                        justifyContent: "center",
                                      }}
                                    >
                                      <Ionicons
                                        name="ellipsis-vertical"
                                        size={16}
                                        color="#555"
                                      />
                                    </Pressable>
                                  }
                                >
                                  <Menu.Item
                                    leadingIcon="pencil-outline"
                                    onPress={() => {
                                      setMenuId(null);
                                      startEdit(c.id, c.content);
                                    }}
                                    title="Edit"
                                  />
                                  <Menu.Item
                                    leadingIcon="delete-outline"
                                    onPress={() => {
                                      setMenuId(null);
                                      onDelete(c.id);
                                    }}
                                    disabled={isDeleting}
                                    title="Delete"
                                  />
                                </Menu>
                              ) : null}
                            </View>
                          </View>
                        </View>

                        {editingId === c.id ? (
                          <View style={{ marginTop: 0 }}>
                            <TextInput
                              className="border border-gray-300 rounded-md p-2 bg-white"
                              placeholder="Edit your comment..."
                              placeholderTextColor="#d9d9d9"
                              value={editContent}
                              onChangeText={setEditContent}
                              multiline
                            />
                            {mentionQuery && mentionUsers?.items?.length ? (
                              <View className="bg-white border border-gray-200 rounded-md mt-1 shadow-sm">
                                {mentionUsers.items.map((u) => (
                                  <Pressable
                                    key={u.id}
                                    onPress={() =>
                                      insertMention(
                                        `${u.firstName} ${u.lastName}`
                                      )
                                    }
                                  >
                                    <Text className="p-2">
                                      @{u.firstName} {u.lastName}
                                    </Text>
                                  </Pressable>
                                ))}
                              </View>
                            ) : null}
                            <View className="flex-row justify-end mt-2">
                              <Button
                                compact
                                mode="contained"
                                onPress={saveEdit}
                                disabled={!editContent.trim() || isUpdating}
                              >
                                Save
                              </Button>
                              <Button
                                compact
                                mode="text"
                                onPress={cancelEdit}
                                disabled={isUpdating}
                              >
                                Cancel
                              </Button>
                            </View>
                          </View>
                        ) : (
                          <View style={{ marginTop: 0 }}>
                            <Text
                              className="text-[13px] text-gray-800"
                              numberOfLines={isExpanded ? undefined : 4}
                            >
                              {renderContentWithMentions(c.content)}
                            </Text>
                            {isLong ? (
                              <Pressable
                                onPress={() =>
                                  setExpanded((prev) => ({
                                    ...prev,
                                    [c.id]: !isExpanded,
                                  }))
                                }
                              >
                                <Text className="mt-1 text-[12px] font-medium text-primaryPurpleDark">
                                  {isExpanded ? "Show less" : "Show more"}
                                </Text>
                              </Pressable>
                            ) : null}
                          </View>
                        )}
                      </View>
                    </View>
                  </View>
                </View>
              );
            })}
          </ScrollView>
        ) : (
          <Text className="text-gray-500 mb-2">No comments yet</Text>
        )}

        {canPost ? (
          <View className="mt-3">
            <TextInput
              className="border border-gray-300 rounded-md p-2 bg-white"
              placeholder="Write a comment..."
              placeholderTextColor="#d9d9d9"
              value={content}
              onChangeText={setContent}
              multiline
            />
            {mentionQuery && mentionUsers?.items?.length ? (
              <View className="bg-white border border-gray-200 rounded-md mt-1 shadow-sm">
                {mentionUsers.items.map((u) => (
                  <Pressable
                    key={u.id}
                    onPress={() =>
                      insertMention(`${u.firstName} ${u.lastName}`)
                    }
                  >
                    <Text className="p-2">
                      @{u.firstName} {u.lastName}
                    </Text>
                  </Pressable>
                ))}
              </View>
            ) : null}
            <View className="flex-row justify-end mt-2">
              <Button
                mode="contained"
                onPress={handleSubmit}
                disabled={!content.trim() || isAdding}
              >
                Post
              </Button>
            </View>
          </View>
        ) : null}
      </View>

      <AppSnackbar
        visible={snackbarVisible}
        onDismiss={() => setSnackbarVisible(false)}
        action={{ label: "Close", onPress: () => setSnackbarVisible(false) }}
      >
        {snackbarMessage}
      </AppSnackbar>
    </>
  );
};
