package be.jeffcheasey88.peeratcode.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class Group implements Comparable<Group> {
	private String name;
	private Integer linkToChapter;
//	private Integer linkToPuzzle;
	private List<Player> players;
	
	@Override
	public String toString(){
		return "Group[name="+name+", chapter="+linkToChapter+"]";
	}

	public Group(JSONObject json) {
		this.name = (String) json.get("name");
		if (json.containsKey("chapter"))
			this.linkToChapter = ((Number) json.get("chapter")).intValue();
//		if (json.containsKey("puzzle"))
//			this.linkToPuzzle = ((Number) json.get("puzzle")).intValue();
	}

	public Group(String name, Integer initChap, Integer initPuzz) {
		this.name = name;
		this.linkToChapter = initChap;
//		this.linkToPuzzle = initPuzz;
	}

	public void addPlayer(Player newPlayer) {
		if (newPlayer != null) {
			if (players == null)
				players = new ArrayList<Player>();

			int pPosition = players.indexOf(newPlayer);
			if (pPosition < 0) {
				players.add(newPlayer);
			} else {
				players.get(pPosition).addCompletion(new Completion(newPlayer.getTotalTries(), newPlayer.getTotalScore()));
			}
		}
	}

	public int getScore() {
		int score = 0;

		if (players != null) {
			for (Player p : players) {
				score = score + p.getTotalScore();
			}
		}
		return score;
	}

	public int getTries() {
		int tries = 0;

		if (players != null) {
			for (Player p : players) {
				tries = tries + p.getTotalTries();
			}
		}
		return tries;
	}

	public String getName() {
		return name;
	}

	public Integer getLinkToChapter() {
		return linkToChapter;
	}

//	public Integer getLinkToPuzzle() {
//		return linkToPuzzle;
//	}

	public JSONObject toJson() {
		return this.toJson(null);
	}

	public JSONObject toJson(Integer rank) {
		JSONObject groupJSON = new JSONObject();
		groupJSON.put("name", name);
		if (rank != null)
			groupJSON.put("rank", rank);
		else if (linkToChapter != null)
			groupJSON.put("chapter", linkToChapter);
//		else if (linkToPuzzle != null)
//			groupJSON.put("puzzle", linkToPuzzle);
		if (players != null) {
			JSONArray groupsPlayerJSON = new JSONArray();
			for (Player p : players) {
				JSONObject playerJSON = new JSONObject();
				playerJSON.put("pseudo", p.getPseudo());
				playerJSON.put("score", p.getTotalScore());
				playerJSON.put("completion", p.getTotalCompletion());
				playerJSON.put("tries", p.getTotalTries());
				groupsPlayerJSON.add(playerJSON);
			}
			groupJSON.put("players", groupsPlayerJSON);
		}
		return groupJSON;
	}

	@Override
	public int compareTo(Group arg0) {
		int comparo = arg0.getScore() - getScore();
		if (comparo == 0) {
			comparo = players.size() - arg0.players.size();
			if (comparo == 0) {
				comparo = getTries() - arg0.getTries();
				if (comparo == 0) {
					comparo = name.compareTo(arg0.name);
				}
			}
		}
		return comparo;
	}

	@Override
	public int hashCode() {
		return Objects.hash(name);
	}

	@Override
	public boolean equals(Object obj){
		if(obj == this) return true;
		if(obj == null) return false;
		if(!(obj instanceof Group)) return false;
		Group other = (Group) obj;
		return this.name.equals(other.name) && integerEquals(this.linkToChapter, other.linkToChapter); // && integerEquals(this.linkToPuzzle, other.linkToPuzzle);
	}

	private boolean integerEquals(Integer a, Integer b){
		if(a == null) return b == null;
		return a.equals(b);
	}
}
