package ai.elimu.rest.v2.crowdsource;

import ai.elimu.dao.ContributorDao;
import ai.elimu.dao.WordContributionEventDao;
import ai.elimu.dao.WordPeerReviewEventDao;
import ai.elimu.model.contributor.Contributor;
import ai.elimu.model.contributor.WordContributionEvent;
import ai.elimu.model.contributor.WordPeerReviewEvent;
import ai.elimu.model.v2.gson.crowdsource.WordContributionEventGson;
import ai.elimu.rest.v2.JpaToGsonConverter;
import ai.elimu.web.content.word.WordPeerReviewsController;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource
 * <p>
 * <p>
 * This controller has similar functionality as the {@link WordPeerReviewsController}.
 */
@RestController
@RequestMapping(value = "/rest/v2/crowdsource/word-peer-reviews", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class WordPeerReviewsRestController {

    private Logger logger = LogManager.getLogger();

    @Autowired
    private WordContributionEventDao wordContributionEventDao;

    @Autowired
    private ContributorDao contributorDao;

    @Autowired
    private WordPeerReviewEventDao wordPeerReviewEventDao;

    /**
     * Get {@link WordContributionEvent}s pending a {@link WordPeerReviewEvent} for the current {@link Contributor}.
     * <p>
     * Note: Currently The list of Emojis are not delivered in this method compared to the handleGetRequest method in
     * {@link WordPeerReviewsController}
     */
    @RequestMapping(method = RequestMethod.GET)
    public String handleGetRequest(HttpServletRequest request,
                                   HttpServletResponse response) {
        logger.info("handleGetRequest");


        // Validate the Contributor.
        JSONObject jsonObject = new JSONObject();

        String providerIdGoogle = request.getHeader("providerIdGoogle");
        logger.info("providerIdGoogle: " + providerIdGoogle);
        if (StringUtils.isBlank(providerIdGoogle)) {
            jsonObject.put("result", "error");
            jsonObject.put("errorMessage", "Missing providerIdGoogle");
            response.setStatus(HttpStatus.BAD_REQUEST.value());

            String jsonResponse = jsonObject.toString();
            logger.info("jsonResponse: " + jsonResponse);
            return jsonResponse;
        }

        // Lookup the Contributor by ID
        Contributor contributor = contributorDao.readByProviderIdGoogle(providerIdGoogle);
        logger.info("contributor: " + contributor);
        if (contributor == null) {
            jsonObject.put("result", "error");
            jsonObject.put("errorMessage", "The Contributor was not found.");
            response.setStatus(HttpStatus.UNPROCESSABLE_ENTITY.value());

            String jsonResponse = jsonObject.toString();
            logger.info("jsonResponse: " + jsonResponse);
            return jsonResponse;
        }

        List<WordContributionEvent> mostRecentWordContributionEvents = wordContributionEventDao.readMostRecentPerWord();
        logger.info("mostRecentWordContributionEvents.size(): " + mostRecentWordContributionEvents.size());

        // For each WordContributionEvent, check if the Contributor has already performed a peer-review.
        // If not, add it to the list of pending peer reviews.
        List<WordContributionEvent> wordContributionEventsPendingPeerReview = new ArrayList<>();
        for (WordContributionEvent mostRecentWordContributionEvent : mostRecentWordContributionEvents) {
            // Ignore WordContributionEvents made by the current Contributor
            if (mostRecentWordContributionEvent.getContributor().getId().equals(contributor.getId())) {
                continue;
            }

            // Check if the current Contributor has already peer-reviewed this Word contribution
            List<WordPeerReviewEvent> wordPeerReviewEvents = wordPeerReviewEventDao.readAll(mostRecentWordContributionEvent, contributor);
            if (wordPeerReviewEvents.isEmpty()) {
                wordContributionEventsPendingPeerReview.add(mostRecentWordContributionEvent);
            }
        }
        logger.info("wordContributionEventsPendingPeerReview.size(): " + wordContributionEventsPendingPeerReview.size());

        JSONArray wordContributionEventsJsonArray = new JSONArray();
        for (WordContributionEvent wordContributionEvent : wordContributionEventsPendingPeerReview) {
            WordContributionEventGson wordContributionEventGson = JpaToGsonConverter.getWordContributionEventGson(wordContributionEvent);
            String json = new Gson().toJson(wordContributionEventGson);
            wordContributionEventsJsonArray.put(new JSONObject(json));
        }

        String jsonResponse = wordContributionEventsJsonArray.toString();
        logger.info("jsonResponse: " + jsonResponse);
        return jsonResponse;
    }
}

@@ -3535,32 +3535,148 @@
 nse;%0A        %7D%0A%0A
+        // Get the most recent WordContributionEvent for each Word, including those made by the current Contributor%0A
         List%3CWor
@@ -4069,35 +4069,17 @@
     
-List%3CWordContributionEvent%3E
+JSONArray
  wor
@@ -4118,26 +4118,33 @@
 view
+JsonArray
  = new 
+JSON
 Array
-List%3C%3E
 ();%0A
@@ -4647,24 +4647,45 @@
 iewEventDao.
+%0A                    
 readAll(most
@@ -4785,33 +4785,33 @@
                 
-w
+W
 ordContributionE
@@ -4818,31 +4818,13 @@
 vent
-sPendingPeerReview.add(
+Gson 
 most
@@ -4842,37 +4842,59 @@
 ontributionEvent
-);%0A  
+Gson = JpaToGsonConverter.%0A
           %7D%0A    
@@ -4891,28 +4891,22 @@
     
-%7D%0A
       
-  %7D%0A
         
 logg
@@ -4905,22 +4905,12 @@
     
-logger.info(%22w
+getW
 ordC
@@ -4929,194 +4929,107 @@
 vent
-sPendingPeerReview.size(): %22 + wordContributionEventsPendingPeerReview.size());%0A%0A        JSONArray wordContributionEventsJsonArray = new JSONArray();%0A        for (WordContributionEvent w
+Gson(mostRecentWordContributionEvent);%0A%0A                String json = new Gson().toJson(mostRecentW
 ordC
@@ -5044,18 +5044,38 @@
 ionEvent
+Gson);%0A              
  
-:
  wordCon
@@ -5106,19 +5106,66 @@
 erReview
-) %7B
+JsonArray.put(new JSONObject(json));%0A            %7D
 %0A       
@@ -5169,290 +5169,167 @@
     
+%7D%0A
     
-WordContributionEventGson wordContributionEventGson = JpaToGsonConverter.getWordContributionEventGson(wordContributionEvent);%0A            String json = new Gson().toJson(wordContributionEventGson);%0A            wordContributionEventsJsonArray.put(new JSONObject(json));%0A        %7D
+    logger.info(%22wordContributionEventsPendingPeerReviewJsonArray.size(): %22 +%0A                wordContributionEventsPendingPeerReviewJsonArray.length());
 %0A%0A  
@@ -5378,16 +5378,33 @@
 onEvents
+PendingPeerReview
 JsonArra

remove unnecessary intermediate array list