package org.gcube.keycloak.avatar;

import java.nio.file.Files;
import java.util.List;

import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.multipart.FileUpload;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.http.HttpRequest;
import org.keycloak.models.KeycloakSession;
import org.keycloak.services.cors.Cors;
import org.keycloak.services.resources.RealmsResource;

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.NotAuthorizedException;
import jakarta.ws.rs.OPTIONS;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.core.UriInfo;

public class AvatarResource extends AbstractAvatarResource {

    //    public static final String STATE_CHECKER_ATTRIBUTE = "state_checker";
    //    public static final String STATE_CHECKER_PARAMETER = "stateChecker";

    public AvatarResource(KeycloakSession session) {
        super(session);
    }

    @Path("/admin")
    public AvatarAdminResource admin() {
        AvatarAdminResource service = new AvatarAdminResource(session);
        ResteasyProviderFactory.getInstance().injectProperties(service);
        service.init();
        return service;
    }

    @OPTIONS
    public Response handleCorsPreflight(@Context final HttpRequest request) {
        logger.info("Received CORS preflight request for ext/user; request is " + request);
        return Cors.add(request, Response.ok())
                .preflight()
                .allowAllOrigins()
                .allowedMethods("GET", "POST", "DELETE")
                .exposedHeaders("Location")
                .auth()
                .build();
    }

    @GET
    @Produces({ "image/png", "image/jpeg", "image/gif" })
    public Response downloadCurrentUserAvatarImage(@Context final HttpRequest request) {
        if (auth == null) {
            logger.debug("Unhautorized call to get avatar");
            throw new NotAuthorizedException("Bearer");
        }
        logger.debugf("Getting avatar for user %s in realm %s", auth.getUser(), auth.getSession().getRealm());
        return Cors
                .add(request,
                        Response.fromResponse(fetchAndCreateResponse(auth.getSession().getRealm(), auth.getUser())))
                .allowAllOrigins()
                .allowedMethods("GET", "POST", "DELETE")
                .exposedHeaders("Location")
                .auth()
                .build();
    }

    @POST
    @NoCache
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadCurrentUserAvatarImage(@RestForm(AVATAR_IMAGE_PARAMETER) FileUpload image, @Context UriInfo uriInfo) {
        if (auth == null) {
            throw new NotAuthorizedException("Bearer");
        }

        //        if (!isValidStateChecker(input)) {
        //            throw new ForbiddenException("State");
        //        }

        logger.debugf("Uploading new avatar for user %s in realm %s", auth.getUser(), auth.getSession().getRealm());
        Response response = null;
        try {
            saveUserImage(auth.getSession().getRealm(), auth.getUser(), Files.newInputStream(image.uploadedFile()));

            if (uriInfo.getQueryParameters().containsKey("account")) {
                UriBuilder uriBuilder = RealmsResource.accountUrl(session.getContext().getUri().getBaseUriBuilder());
                for (String parameterName : uriInfo.getQueryParameters().keySet()) {
                    List<String> parameterValues = uriInfo.getQueryParameters().get(parameterName);
                    for (String parameterValue : parameterValues) {
                        uriBuilder.queryParam(parameterName, parameterValue);
                    }
                }
                response = Response.seeOther(uriBuilder.build(auth.getSession().getRealm().getName())).build();
            } else {
                response = Response.noContent().build();
            }
        } catch (Exception ex) {
            response = Response.serverError().build();
        }
        return response;
    }

    //    private boolean isValidStateChecker(MultipartFormDataInput input) {
    //        try {
    //            String actualStateChecker = input.getFormDataPart(STATE_CHECKER_PARAMETER, String.class, null);
    //            String requiredStateChecker = (String) session.getAttribute(STATE_CHECKER_ATTRIBUTE);
    //
    //            return Objects.equals(requiredStateChecker, actualStateChecker);
    //        } catch (Exception ex) {
    //            return false;
    //        }
    //    }

}