package com.rjlresaka.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.rjlresaka.dao.ConversationDAO;
import com.rjlresaka.dao.FriendDAO;
import com.rjlresaka.dao.MessageDAO;
import com.rjlresaka.model.ConversationItem;
import com.rjlresaka.model.FriendRequest;
import com.rjlresaka.model.Message;
import com.rjlresaka.model.User;

@WebServlet("/app/dashboard")
public class DashboardServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private final ConversationDAO conversationDAO = new ConversationDAO();
    private final FriendDAO friendDAO = new FriendDAO();
    private final MessageDAO messageDAO = new MessageDAO();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("authUser") == null) {
            response.sendRedirect(request.getContextPath() + "/login");
            return;
        }

        User authUser = (User) session.getAttribute("authUser");
        try {
            Integer forcedConversationId = null;
            int requestedUserId = parseInt(request.getParameter("user"));
            if (requestedUserId > 0 && requestedUserId != authUser.getId()) {
                forcedConversationId = Integer.valueOf(conversationDAO.findOrCreateConversationId(authUser.getId(), requestedUserId, getServletContext()));
            }

            List<ConversationItem> conversations = conversationDAO.findConversationsForUser(authUser.getId(), getServletContext());
            List<User> friends = friendDAO.findFriends(authUser.getId(), getServletContext());
            List<User> people = friendDAO.findPeople(authUser.getId(), getServletContext());
            List<FriendRequest> pendingRequests = friendDAO.findPendingRequestsReceived(authUser.getId(), getServletContext());

            ConversationItem activeConversation = resolveActiveConversation(request, conversations, forcedConversationId);
            List<Message> messages = new ArrayList<Message>();
            if (activeConversation != null) {
                activeConversation.setActive(true);
                conversationDAO.markConversationAsSeen(activeConversation.getId(), authUser.getId(), getServletContext());
                messages = messageDAO.findMessagesByConversation(activeConversation.getId(), authUser.getId(), getServletContext());
            }

            request.setAttribute("conversations", conversations);
            request.setAttribute("activeConversation", activeConversation);
            request.setAttribute("messages", messages);
            request.setAttribute("friends", friends);
            request.setAttribute("people", people);
            request.setAttribute("pendingRequests", pendingRequests);
            request.setAttribute("friendCount", Integer.valueOf(friends.size()));
            request.setAttribute("requestCount", Integer.valueOf(pendingRequests.size()));
            request.setAttribute("groupCandidateCount", Integer.valueOf(friends.size()));
            consumeFlash(session, request);
            request.getRequestDispatcher("/WEB-INF/views/dashboard.jsp").forward(request, response);
        } catch (Exception exception) {
            request.setAttribute("error", "Impossible de charger le tableau de bord pour le moment.");
            request.setAttribute("debugMessage", exception.getMessage());
            request.getRequestDispatcher("/WEB-INF/views/dashboard.jsp").forward(request, response);
        }
    }

    private ConversationItem resolveActiveConversation(HttpServletRequest request, List<ConversationItem> conversations, Integer forcedConversationId) {
        String conversationParam = request.getParameter("conversation");
        Integer conversationId = null;
        try {
            if (conversationParam != null && !conversationParam.trim().isEmpty()) {
                conversationId = Integer.valueOf(conversationParam);
            }
        } catch (NumberFormatException exception) {
            conversationId = null;
        }

        if (conversations.isEmpty()) {
            return null;
        }
        if (conversationId == null && forcedConversationId != null) {
            conversationId = forcedConversationId;
        }
        if (conversationId == null) {
            return conversations.get(0);
        }
        for (ConversationItem item : conversations) {
            if (item.getId() == conversationId.intValue()) {
                return item;
            }
        }
        return conversations.get(0);
    }

    private int parseInt(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException exception) {
            return 0;
        }
    }

    private void consumeFlash(HttpSession session, HttpServletRequest request) {
        Object success = session.getAttribute("flashSuccess");
        Object error = session.getAttribute("flashError");
        if (success != null) {
            request.setAttribute("success", success.toString());
            session.removeAttribute("flashSuccess");
        }
        if (error != null) {
            request.setAttribute("error", error.toString());
            session.removeAttribute("flashError");
        }
    }
}
