const { ConversationMembers, Conversations, Messages, Users } = require('../models');
const { Op } = require('sequelize');
const { formatTimestamp } = require('../util');

const buildConversationFilter = (status) => {
  const filter = {};
  if (status) {
    filter.status = status;
  }
  return filter;
};

const buildMessageFilter = (isSeen) => {
  const filter = {};
  if (isSeen !== undefined) {
    filter.is_seen = isSeen === 'true';
  }
  return filter;
};

const formatMembers = (members, userId) => {
  const memberLists = members
    .filter((m) => m.user_id !== userId)
    .map((m) => ({
      name: m.user_members
        ? `${m.user_members.firstname || ''} ${m.user_members.lastname || ''}`.trim()
        : 'Unknown User',
      image: m.user_members?.image
        ? `${process.env.BASE_URL}/public/user-uploads/${m.user_members.image}`
        : null,
    }));

  if (memberLists.length < 1) {
    return [
      {
        name: 'Unknown User',
        image: null,
      },
    ];
  }

  return memberLists;
};

const formatConversation = (member, userId) => {
  const lastMessage = member.conversations.messages[0];

  const members = formatMembers(member.conversations.members, userId);
  return {
    id: member.conversations.id,
    name: member?.conversations?.name ?? members?.[0]?.name,
    convoType: member.conversations.convo_type,
    status: member.conversations.status,
    lastMessage: lastMessage
      ? {
          content: lastMessage.content,
          createdAt: formatTimestamp(lastMessage.createdAt),
          isSeen: lastMessage.is_seen,
          sender: lastMessage.sender
            ? {
                isFromLoggedInUser: lastMessage.sender_id === userId,
                name: `${lastMessage.sender.firstname || ''} ${lastMessage.sender.lastname || ''}`.trim(),
                image: lastMessage.sender.image
                  ? `${process.env.BASE_URL}/public/user-uploads/${lastMessage.sender.image}`
                  : null,
              }
            : null,
        }
      : null,
    members,
  };
};

const getAllConvoByUser = (userId, { status, isSeen }) => {
  const conversationFilter = buildConversationFilter(status);
  const messageFilter = buildMessageFilter(isSeen);

  return ConversationMembers.findAll({
    where: { user_id: userId },
    include: [
      {
        model: Conversations,
        as: 'conversations',
        where: conversationFilter,
        include: [
          {
            model: ConversationMembers,
            as: 'members',
            include: [
              {
                model: Users,
                as: 'user_members',
                attributes: ['firstname', 'lastname', 'image'],
              },
            ],
          },
          {
            model: Messages,
            as: 'messages',
            where: messageFilter,
            attributes: ['id', 'content', 'sender_id', 'createdAt', 'is_seen'],
            limit: 1,
            order: [['createdAt', 'DESC']],
            include: [
              {
                model: Users,
                as: 'sender',
                attributes: ['firstname', 'lastname', 'image'],
              },
            ],
          },
        ],
      },
    ],
  }).then((memberRecords) => {
    return memberRecords
      .filter((member) => member.conversations.messages.length > 0)
      .map((member) => formatConversation(member, userId));
  });
};

module.exports = {
  getAllConvoByUser,
};
