package dev.peerat.backend.routes.groups;

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

import java.time.LocalDateTime;
import java.util.regex.Matcher;

import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
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.Locker;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;

public class GroupCreate implements Response {

	private Locker<Group> locker;
	private DatabaseRepository repo;
	private int groupDelay;

	public GroupCreate(DatabaseRepository repo, Locker<Group> locker, int groupDelay){
		this.repo = repo;
		this.locker = locker;
		this.groupDelay = groupDelay;
	}

	@RouteDoc(path = "/groupCreate", responseCode = 200, responseDescription = "Le groupe a été créé")
	@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur est déjà dans le groupe / ne peux pas le rejoindre")
	@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de crée un groupe après le délai maximum de création de l'event")
	
	@Route(path = "^\\/groupCreate$", type = POST, needLogin = true)
	public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
		Group newGroup = new Group(reader.readJson());
		PeerAtUser user = context.getUser();
		
		if (this.repo.getPlayerGroup(user.getId(), newGroup.getLinkToChapter()) == null) {
			try {
				if(this.repo.getGroupId(newGroup) == null) throw new NullPointerException();
				context.response(403);
				return;
			}catch(NullPointerException e){
				if(newGroup.getLinkToChapter() != null){
					Chapter chapter = this.repo.getChapter(newGroup.getLinkToChapter());
					if(chapter.getStartDate() != null){
						LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
						if(LocalDateTime.now().isAfter(start)){
							context.response(423);
							return;
						}
					}
				}
				if (this.repo.insertGroup(newGroup, user)) {
					context.response(200);
					
					locker.setValue(newGroup);
				} else {
					context.response(403);
				}
			}
		}else {
			context.response(403);
		}
	}
}
