package org.exoplatform.cs.rest;

import io.swagger.annotations.*;
import org.exoplatform.cs.dto.SpaceDTO;
import org.exoplatform.cs.service.CSSpaceService;
import org.exoplatform.cs.service.EnvironmentService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.resource.ResourceContainer;
import org.exoplatform.social.core.identity.model.Profile;
import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider;
import org.exoplatform.social.core.manager.IdentityManager;
import org.exoplatform.social.core.space.model.Space;
import org.exoplatform.social.core.space.spi.SpaceService;
import org.json.JSONArray;
import org.json.JSONObject;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;

@Path("/customerspace/info")
@Api(value = "/customerspace/info")
public class CustomerInfoRest implements ResourceContainer {

    private CSSpaceService csSpaceService;
    private IdentityManager identityManager;
    private SpaceService spaceService;
    private EnvironmentService environmentService;
    private static final Log LOG =
            ExoLogger.getLogger(CustomerInfoRest.class);

    public CustomerInfoRest(CSSpaceService csSpaceService, EnvironmentService environmentService, IdentityManager identityManager, SpaceService spaceService) {
        this.csSpaceService = csSpaceService;
        this.environmentService = environmentService;
        this.identityManager = identityManager;
        this.spaceService = spaceService;
    }

    @GET
    @RolesAllowed("support-team")
    @Produces(MediaType.APPLICATION_JSON)
    @Path("getAllSpaces")
    @ApiOperation(value = "Get All Customer Spaces", httpMethod = "GET", response = Response.class, notes = "Get all cs spaces")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Request fulfilled"),
            @ApiResponse(code = 400, message = "Invalid query input"),
            @ApiResponse(code = 403, message = "Unauthorized operation"),
            @ApiResponse(code = 500, message = "Internal server error")})
    public Response getAllSpaces() {
        List<SpaceDTO> allspaces = csSpaceService.getAllSpaces();
        JSONArray spaces = new JSONArray();
        try {
            for (SpaceDTO spaceDTO : allspaces) {
                JSONObject spaceJson = new JSONObject();
                spaceJson.put("name", spaceDTO.getName());
                spaceJson.put("subscriptionStartDate", spaceDTO.getSubscriptionStartDate());
                spaceJson.put("subscriptionEndDate", spaceDTO.getSubscriptionEndDate());
                spaceJson.put("subscriptionActive", spaceDTO.isSubscriptionActive());
                spaceJson.put("language", spaceDTO.getLanguage());
                spaceJson.put("hosted", spaceDTO.isHosted());
                spaces.put(spaceJson);
            }
        } catch (Exception e) {
            LOG.error("Error while getting all spaces ", e);
            return Response.status(500).build();
        }
        return Response.ok(spaces.toString()).build();
    }

    @GET
    @RolesAllowed("support-team")
    @Produces(MediaType.APPLICATION_JSON)
    @Path("getAllSpacesWithMembers")
    @ApiOperation(value = "Get All Customer Spaces with members", httpMethod = "GET", response = Response.class, notes = "Get all cs spaces with members")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Request fulfilled"),
            @ApiResponse(code = 400, message = "Invalid query input"),
            @ApiResponse(code = 403, message = "Unauthorized operation"),
            @ApiResponse(code = 500, message = "Internal server error")})
    public Response getAllSpacesWithMembers() {
        List<SpaceDTO> allspaces = csSpaceService.getAllSpaces();
        JSONArray spaces = new JSONArray();
        try {
            for (SpaceDTO spaceDTO : allspaces) {
                JSONObject spaceJson = new JSONObject();
                JSONArray spaceMembersJSON = new JSONArray();
                String[] spaceMembers = getMembersOfSpaceDTO(spaceDTO);
                for (String member : spaceMembers) {
                        Profile userProfile = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME,member,false).getProfile();
                        JSONObject userJson = new JSONObject();
                        userJson.put("username",userProfile.getProperty(Profile.USERNAME));
                        userJson.put("firstname",userProfile.getProperty(Profile.FIRST_NAME));
                        userJson.put("lastname",userProfile.getProperty(Profile.LAST_NAME));
                        userJson.put("email",userProfile.getEmail());
                        userJson.put("createdtime",userProfile.getCreatedTime());
                        userJson.put("gender",userProfile.getProperty(Profile.GENDER));
                        userJson.put("deleted",userProfile.getProperty(Profile.DELETED));
                        spaceMembersJSON.put(userJson);
                }
                spaceJson.put("name", spaceDTO.getName());
                spaceJson.put("members", spaceMembersJSON);
                spaceJson.put("subscriptionStartDate", spaceDTO.getSubscriptionStartDate());
                spaceJson.put("subscriptionEndDate", spaceDTO.getSubscriptionEndDate());
                spaceJson.put("subscriptionActive", spaceDTO.isSubscriptionActive());
                spaceJson.put("language", spaceDTO.getLanguage());
                spaceJson.put("hosted", spaceDTO.isHosted());
                spaces.put(spaceJson);
            }
        } catch (Exception e) {
            LOG.error("Error while getting all spaces with members", e);
            return Response.status(500).build();
        }
        return Response.ok(spaces.toString()).build();
    }

    @GET
    @RolesAllowed("support-team")
    @Produces(MediaType.APPLICATION_JSON)
    @Path("getAllSpacesWithEnvironment")
    @ApiOperation(value = "Get All Customer Spaces with environment", httpMethod = "GET", response = Response.class, notes = "Get all cs spaces with environment")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Request fulfilled"),
            @ApiResponse(code = 400, message = "Invalid query input"),
            @ApiResponse(code = 403, message = "Unauthorized operation"),
            @ApiResponse(code = 500, message = "Internal server error")})
    public Response getAllSpacesWithEnvironment() {
        List<SpaceDTO> allspaces = csSpaceService.getAllSpaces();
        JSONArray spaces = new JSONArray();
        try {
            for (SpaceDTO spaceDTO : allspaces) {
                JSONObject spaceJson = new JSONObject();
                JSONArray envlist = new JSONArray(environmentService.getSpaceEnvironments(spaceDTO.getGroupId()));
                spaceJson.put("name", spaceDTO.getName());
                spaceJson.put("environments", envlist);
                spaceJson.put("subscriptionStartDate", spaceDTO.getSubscriptionStartDate());
                spaceJson.put("subscriptionEndDate", spaceDTO.getSubscriptionEndDate());
                spaceJson.put("subscriptionActive", spaceDTO.isSubscriptionActive());
                spaceJson.put("language", spaceDTO.getLanguage());
                spaceJson.put("hosted", spaceDTO.isHosted());
                spaces.put(spaceJson);
            }
        } catch (Exception e) {
            LOG.error("Error while getting all spaces with environments", e);
            return Response.status(500).build();
        }
        return Response.ok(spaces.toString()).build();
    }

    private String[] getMembersOfSpaceDTO(SpaceDTO spaceDTO) throws Exception {
        Space space = spaceService.getSpaceByGroupId(spaceDTO.getGroupId());
        return space.getMembers();
    }
}