package eu.dnetlib.openaire.usermanagement.utils;

import com.google.gson.JsonElement;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Service
public class RoleManagement {

    private static final Logger logger = Logger.getLogger(RoleManagement.class);

    @Value("${role-management.url}")
    private String url;
    public HttpUtils httpUtils;
    public AuthorizationService authorizationService;

    @Autowired
    public RoleManagement(HttpUtils httpUtils, AuthorizationService authorizationService) {
        this.httpUtils = httpUtils;
        this.authorizationService = authorizationService;
    }

    private String mapType(String type, boolean communityMap) {
        if (type.equals("organization")) {
            type = "institution";
        } else if (type.equals("ri") && communityMap) {
            type = "community";
        }
        return type;
    }

    public JsonElement assignMemberRole(String type, String id, HttpServletRequest request) throws HttpClientErrorException {
        Map<String, String> params = new HashMap<>();
        params.put("force", "true");
        return this.httpUtils.post(url + "/member/" + mapType(type, false) + "/" + id, getSessionCookie(request), null, params);
    }

    public JsonElement assignManagerRole(String type, String id, HttpServletRequest request) throws HttpClientErrorException {
        Map<String, String> params = new HashMap<>();
        params.put("force", "true");
        return this.httpUtils.post(url + "/admin/" + mapType(type, true) + "/" + id, getSessionCookie(request), null, params);
    }

    public JsonElement removeMemberRole(String type, String id, HttpServletRequest request) throws HttpClientErrorException {
        Map<String, String> params = new HashMap<>();
        params.put("force", "true");
        return this.httpUtils.delete(url + "/member/" + mapType(type, false) + "/" + id, getSessionCookie(request), params);
    }

    public JsonElement removeMemberRole(String type, String id, String email) throws HttpClientErrorException {
        Map<String, String> params = new HashMap<>();
        params.put("email", email);
        return this.httpUtils.delete(url + "/member/" + mapType(type, false) + "/" + id, null, params);
    }

    public JsonElement removeManagerRole(String type, String id, HttpServletRequest request) throws HttpClientErrorException {
        return this.httpUtils.delete(url + "/admin/" + mapType(type, true) + "/" + id, getSessionCookie(request), null);
    }

    public JsonElement removeManagerRole(String type, String id, String email) throws HttpClientErrorException {
        Map<String, String> params = new HashMap<>();
        params.put("email", email);
        return this.httpUtils.delete(url + "/admin/" + mapType(type, true) + "/" + id, null, params);
    }

    public JsonElement getAllMembers(String type, String id) throws HttpClientErrorException {
        return this.httpUtils.get(url + "/member/" + mapType(type, false) + "/" + id, null, null);
    }

    public int getAllMembersCount(String type, String id) throws HttpClientErrorException {
        return this.httpUtils.get(url + "/member/" + mapType(type, false) + "/" + id + "/count", null, null).getAsInt();
    }

    public JsonElement getAllManagers(String type, String id) throws HttpClientErrorException {
        Map<String, String> params = new HashMap<>();
        if(!authorizationService.isPortalAdmin() && !authorizationService.isCurator(type) && !authorizationService.isManager(type, id)) {
            params.put("name", "false");
            params.put("email", "false");
        }
        return this.httpUtils.get(url + "/admin/" + mapType(type, true) + "/" + id, null, params);
    }

    public JsonElement getAllCurators(String type) throws HttpClientErrorException {
        return this.httpUtils.get(url + "/curator/" + mapType(type, false), null, null);
    }

    public boolean isMember(String type, String id, String email) throws HttpClientErrorException {
        for (JsonElement element : this.httpUtils.get(url + "/member/" + mapType(type, false) + "/" + id, null, null).getAsJsonArray()) {
            if (element.getAsJsonObject().get("email").getAsString().equalsIgnoreCase(email)) {
                return true;
            }
        }
        return false;
    }

    public boolean isManager(String type, String id, String email) throws HttpClientErrorException {
        for (JsonElement element : this.httpUtils.get(url + "/admin/" + mapType(type, true) + "/" + id, null, null).getAsJsonArray()) {
            if (element.getAsJsonObject().get("email").getAsString().equalsIgnoreCase(email)) {
                return true;
            }
        }
        return false;
    }

    public JsonElement createMemberRole(String type, String id) {
        Map<String, String> params = new HashMap<>();
        params.put("description", mapType(type, false) + " " + id);
        return this.httpUtils.post(url + "/member/" + mapType(type, false) + "/" + id + "/create", null, null, params);
    }

    public JsonElement createCuratorRole(String type) {
        Map<String, String> params = new HashMap<>();
        params.put("description", mapType(type, false) + " Curator");
        return this.httpUtils.post(url + "/curator/" + mapType(type, false) + "/create", null, null, params);
    }

    public JsonElement createRole(String name, String description) {
        Map<String, String> params = new HashMap<>();
        params.put("name", name);
        params.put("description", description);
        return this.httpUtils.post(url + "/super/create", null, null, params);
    }

    private String getSessionCookie(HttpServletRequest request) {
        return httpUtils.getCookie(request, "openAIRESession");
    }
}
