package org.kar.karideo.api;

import java.util.List;

import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.QueryAnd;
import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.options.Condition;
import org.kar.archidata.filter.GenericContext;
import org.kar.karideo.model.UserMediaAdvancement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PATCH;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;

@Path("/advancement")
@Produces(MediaType.APPLICATION_JSON)
public class UserMediaAdvancementResource {
	static final Logger LOGGER = LoggerFactory.getLogger(UserMediaAdvancementResource.class);

	@GET
	@Path("{id}")
	@RolesAllowed("USER")
	@Operation(description = "Get a specific user advancement with his ID", tags = "GLOBAL")
	public UserMediaAdvancement get(@Context final SecurityContext sc, @PathParam("id") final Long id) throws Exception {
		final GenericContext gc = (GenericContext) sc.getUserPrincipal();
		return DataAccess.getWhere(UserMediaAdvancement.class, new Condition(new QueryAnd(new QueryCondition("mediaId", "=", id), new QueryCondition("userId", "=", gc.userByToken.id))));
	}

	@GET
	@RolesAllowed("USER")
	@Operation(description = "Get all user advancement", tags = "GLOBAL")
	public List<UserMediaAdvancement> gets(@Context final SecurityContext sc) throws Exception {
		final GenericContext gc = (GenericContext) sc.getUserPrincipal();
		return DataAccess.getsWhere(UserMediaAdvancement.class, new Condition(new QueryCondition("userId", "=", gc.userByToken.id)));
	}

	/* ============================================================================= Modification SECTION: ============================================================================= */

	public record MediaInformations(int time, float percent, int count) {
	}

	// @POST
	// @Path("{id}")
	// @RolesAllowed("USER")
	// @Consumes(MediaType.APPLICATION_JSON)
	public UserMediaAdvancement post(@Context final SecurityContext sc, @PathParam("id") final Long id, final MediaInformations data) throws Exception {
		final GenericContext gc = (GenericContext) sc.getUserPrincipal();
		final UserMediaAdvancement elem = new UserMediaAdvancement();
		elem.userId = gc.userByToken.id;
		elem.mediaId = id;
		elem.time = data.time;
		elem.percent = data.percent;
		elem.count = data.count;
		return DataAccess.insert(elem);
	}

	public record MediaInformationsDelta(int time, float percent, boolean addCount) {
	}

	@PATCH
	@Path("{id}")
	@RolesAllowed("USER")
	@Consumes(MediaType.APPLICATION_JSON)
	@Operation(description = "Modify a user advancement", tags = "GLOBAL")
	public UserMediaAdvancement patch(@Context final SecurityContext sc, @PathParam("id") final Long id, final MediaInformationsDelta data) throws Exception {
		final UserMediaAdvancement elem = get(sc, id);
		if (elem == null) {
			// insert element
			if (data.addCount) {
				return post(sc, id, new MediaInformations(data.time(), data.percent(), 1));
			} else {
				return post(sc, id, new MediaInformations(data.time(), data.percent(), 0));
			}
		}
		elem.time = data.time;
		elem.percent = data.percent;
		if (data.addCount) {
			elem.count++;
		}
		LOGGER.info("{},{},{}", elem.time, elem.percent, elem.count);
		final long nbAfected = DataAccess.update(elem, elem.id, List.of("time", "percent", "count"));
		return DataAccess.get(UserMediaAdvancement.class, elem.id);
	}

	@DELETE
	@Path("{id}")
	@RolesAllowed("USER")
	@Operation(description = "Remove a specific user advancement", tags = "GLOBAL")
	public void remove(@Context final SecurityContext sc, @PathParam("id") final Long id) throws Exception {
		final UserMediaAdvancement elem = get(sc, id);
		DataAccess.delete(UserMediaAdvancement.class, elem.id);
	}

}
