import type { SupportConversation } from "~/types";

const toConversationMap = (items: SupportConversation[]) =>
  Object.fromEntries(items.map((item) => [item.id, item])) as Record<string, SupportConversation>;

export function useSupportUnread() {
  const { user, token } = useAuth();
  const { connect, onConversationUpdated, onMessageCreated } = useSupportRealtime();

  const conversations = useState<Record<string, SupportConversation>>("support-unread-conversations", () => ({}));
  const unreadCount = useState<number>("support-unread-count", () => 0);
  const initialized = useState<boolean>("support-unread-initialized", () => false);
  const loading = useState<boolean>("support-unread-loading", () => false);
  const offConversationUpdated = useState<(() => void) | null>("support-unread-off-conversation", () => null);
  const offMessageCreated = useState<(() => void) | null>("support-unread-off-message", () => null);

  const recomputeUnreadCount = () => {
    const items = Object.values(conversations.value);

    unreadCount.value = user.value?.role === "admin"
      ? items.filter((item) => item.unreadForAdmin).length
      : items.some((item) => item.unreadForUser) ? 1 : 0;
  };

  const replaceConversations = (items: SupportConversation[]) => {
    conversations.value = toConversationMap(items);
    recomputeUnreadCount();
  };

  const upsertConversation = (item: SupportConversation) => {
    conversations.value = {
      ...conversations.value,
      [item.id]: item
    };
    recomputeUnreadCount();
  };

  const clearState = () => {
    conversations.value = {};
    unreadCount.value = 0;
    initialized.value = false;
    offConversationUpdated.value?.();
    offConversationUpdated.value = null;
    offMessageCreated.value?.();
    offMessageCreated.value = null;
  };

  const refreshUnread = async () => {
    if (!user.value || !token.value || loading.value) {
      return;
    }

    loading.value = true;

    try {
      if (user.value.role === "admin") {
        const response = await useChatApi<SupportConversation[]>("/admin/support/conversations");
        replaceConversations(response);
      } else {
        const response = await useChatApi<SupportConversation>("/support/conversation");
        replaceConversations([response]);
      }
    } catch {
      // Ignore unread refresh failures in shell navigation.
    } finally {
      loading.value = false;
    }
  };

  const ensureRealtime = () => {
    if (!process.client || !token.value || offConversationUpdated.value || offMessageCreated.value) {
      return;
    }

    connect();
    offConversationUpdated.value = onConversationUpdated(({ conversation }) => {
      if (conversation) {
        upsertConversation(conversation);
      }
    });
    offMessageCreated.value = onMessageCreated(({ conversation }) => {
      if (conversation) {
        upsertConversation(conversation);
      }
    });
  };

  const initializeUnread = async () => {
    if (initialized.value || !user.value || !token.value) {
      return;
    }

    await refreshUnread();
    ensureRealtime();
    initialized.value = true;
  };

  return {
    unreadCount,
    initializeUnread,
    refreshUnread,
    replaceConversations,
    upsertConversation,
    clearState
  };
}
