package dev.peerat.backend.routes.admins;

import static dev.peerat.framework.RequestType.DELETE;
import static dev.peerat.framework.RequestType.POST;
import static dev.peerat.framework.RequestType.PUT;

import java.util.List;
import java.util.regex.Matcher;

import dev.peerat.backend.model.Puzzle;
import dev.peerat.backend.repository.DatabaseAdminRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;

public class PuzzleController {

	private DatabaseAdminRepository repo;
	
	public PuzzleController(DatabaseRepository repo){
		this.repo = repo.getAdminRepository();
	}
	
	@Route(path = "^/admin/puzzle/$", type = POST, needLogin = true)
	public void add(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
		JsonMap json = reader.readJson();
		Puzzle puzzle = new Puzzle(-1, json.get("name"), json.get("content"), json.<String>get("soluce").getBytes(), null, json.<Long>get("scoreMax").intValue(), null, -1, null);
		if(repo.adminAddPuzzle(puzzle, json.<Long>get("chapter").intValue())){
			context.response(200);
		}else{
			context.response(501);
		}
	}
	
	@Route(path = "^/admin/puzzle/(\\d+)$", type = DELETE, needLogin = true)
	public void delete(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
		if(this.repo.adminDeletePuzzle(Integer.parseInt(matcher.group(1)))){
			context.response(200);
		}else{
			context.response(501);
		}
	}
	
	
	@Route(path = "^/admin/puzzle/(\\d+)$", type = PUT, needLogin = true)
	public void edit(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
		JsonMap json = reader.readJson();
		Puzzle puzzle = new Puzzle(-1, json.get("name"), json.get("content"), json.<String>get("soluce").getBytes(), null, json.<Long>get("scoreMax").intValue(), null, -1, null);
		if(repo.adminUpdatePuzzle(Integer.parseInt(matcher.group(1)), puzzle, json.<Long>get("chapter").intValue())){
			context.response(200);
		}else{
			context.response(501);
		}
	}
	
	@Route(path = "^/admin/puzzle/(\\d+)$", needLogin = true)
	public void get(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
		Puzzle puzzle = this.repo.getAdminPuzzle(Integer.parseInt(matcher.group(1)));
		JsonMap json = new JsonMap();
		json.set("name", puzzle.getName());
		json.set("content", puzzle.getContent());
		json.set("soluce", new String(puzzle.getSoluce()));
		json.set("score_max", puzzle.getScoreMax());
		
		context.response(200);
		writer.write(json.toString()+"\n");
	}
	
	@Route(path = "^/admin/puzzles/$", needLogin = true)
	public void getAll(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
		List<Puzzle> puzzles = repo.getAdminPuzzles();
		JsonArray array = new JsonArray();
		for (Puzzle puzzle : puzzles){
			JsonMap puzzleJSON = new JsonMap();
			puzzleJSON.set("id", puzzle.getId());
			puzzleJSON.set("name", puzzle.getName());
			puzzleJSON.set("scoreMax", puzzle.getScoreMax());
			if(puzzle.getTags() != null) puzzleJSON.set("tags", puzzle.getJsonTags());
			puzzleJSON.set("show", puzzle.hasStarted());
			array.add(puzzleJSON);
		}
		context.response(200);
		writer.write(array.toString());
	}
}
