package de.stephanlindauer.criticalmaps.model;

import com.squareup.okhttp.internal.Util;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;

import de.stephanlindauer.criticalmaps.interfaces.IChatMessage;
import de.stephanlindauer.criticalmaps.vo.chat.OutgoingChatMessage;
import de.stephanlindauer.criticalmaps.vo.chat.ReceivedChatMessage;

public class ChatModel {

    private ArrayList<ReceivedChatMessage> chatMessages = new ArrayList<>();
    private ArrayList<OutgoingChatMessage> outgoingMassages = new ArrayList<>();

    //singleton
    private static ChatModel instance;

    public static ChatModel getInstance() {
        if (ChatModel.instance == null) {
            ChatModel.instance = new ChatModel();
        }
        return ChatModel.instance;
    }

    public void setNewJson(JSONObject jsonObject) throws JSONException, UnsupportedEncodingException {
        if (chatMessages == null) {
            chatMessages = new ArrayList<>(jsonObject.length());
        } else {
            chatMessages.clear();
        }

        Iterator<String> keys = jsonObject.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            JSONObject value = jsonObject.getJSONObject(key);
            String message = URLDecoder.decode(value.getString("message"), Util.UTF_8.name());
            Date timestamp = new Date(Long.parseLong(value.getString("timestamp")) * 1000);
            String identifier = key;

            //for i going backwards to delete without side-effects
            for (int i = outgoingMassages.size() - 1; i > -1; i--) {
                OutgoingChatMessage outgoingMessageToMaybeDelete = outgoingMassages.get(i);
                if (outgoingMessageToMaybeDelete.getIdentifier().equals(identifier)) {
                    outgoingMassages.remove(i);
                }
            }

            chatMessages.add(new ReceivedChatMessage(message, timestamp));
        }

        Collections.sort(chatMessages, new Comparator<ReceivedChatMessage>() {
            @Override
            public int compare(ReceivedChatMessage oneChatMessages, ReceivedChatMessage otherChatMessage) {
                return oneChatMessages.getTimestamp().compareTo(otherChatMessage.getTimestamp());
            }
        });
    }

    public void setNewOutgoingMessage(OutgoingChatMessage newOutgoingMessage) {
        outgoingMassages.add(newOutgoingMessage);
    }

    public JSONArray getOutgoingMessagesAsJson() {
        JSONArray jsonArray = new JSONArray();

        for (int i = 0, size = outgoingMassages.size(); i < size; i++) {
            OutgoingChatMessage outgoingChatMessage = outgoingMassages.get(i);
            try {
                JSONObject messageObject = new JSONObject();
                messageObject.put("text", outgoingChatMessage.getUrlEncodedMessage());
                messageObject.put("timestamp", outgoingChatMessage.getTimestamp().getTime());
                messageObject.put("identifier", outgoingChatMessage.getIdentifier());
                jsonArray.put(messageObject);
            } catch (JSONException e) {
            }
        }
        return jsonArray;
    }

    public ArrayList<IChatMessage> getSavedAndOutgoingMessages() {
        int mergedListsSize = chatMessages.size() + outgoingMassages.size();
        ArrayList<IChatMessage> mergeArrayList = new ArrayList<>(mergedListsSize);
        mergeArrayList.addAll(chatMessages);
        mergeArrayList.addAll(outgoingMassages);
        return mergeArrayList;
    }

    public boolean hasOutgoingMessages() {
        return outgoingMassages.size() > 0;
    }
}

@@ -3324,17 +3324,23 @@
 ception 
-e
+ignored
 ) %7B%0A    
@@ -3809,16 +3809,17 @@
  return 
+!
 outgoing
@@ -3831,18 +3831,17 @@
 ges.
-size() %3E 0
+isEmpty()
 ;%0A  

Use isEmpty and mark ignored Exception as ignored