package com.bocloud.ims.service.internal;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.common.enums.BoCloudMethod;
import com.bocloud.common.enums.BoCloudService;
import com.bocloud.common.model.*;
import com.bocloud.common.model.RequestContext.Catalog;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.common.Project;
import com.bocloud.ims.entity.common.UserProject;
import com.bocloud.service.core.CurrentService;
import com.bocloud.service.core.Service;
import com.bocloud.service.http.core.ServiceFactory;
import com.bocloud.service.http.model.RemoteService;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * SOC项目内部访问
 *
 * @author wangyu
 * @version 1.0
 * @since 2018年3月5日
 */
@Component
public class SmsProjectService implements InitializingBean {

    @Autowired
    private ServiceFactory serviceFactory;
    @Autowired
    private CurrentService currentService;
    private static Service service = Service.create(BoCloudService.SMS);
    private Map<String, Object> headers = new HashMap<>(4);

    public BocloudResult<Project> detail(Long id) {
        RemoteService remote = serviceFactory.build(service, "/v1/projects/" + id, BoCloudMethod.GET, headers, null);
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return new BocloudResult<>(false, result.getMessage());
        }
        String data = JSONObject.toJSONString(result.getData());
        return new BocloudResult<>(true, JSONObject.parseObject(data, Project.class), "success");
    }

    public BocloudResult<Project> basic(Long id) {
        RemoteService remote = serviceFactory.build(service, "/v1/projects/" + id, BoCloudMethod.GET, headers,
                null);
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return new BocloudResult<>(false, result.getMessage());
        }
        String data = JSONObject.toJSONString(result.getData());
        return new BocloudResult<>(true, JSONObject.parseObject(data, Project.class), "success");
    }

    public List<Project> listProjectsByIds(List<Long> ids) {
        ArrayList<Param> params = null;
        if (null != ids && !ids.isEmpty()) {
            String idString = JSONArray.toJSONString(ids);
            params = Lists.newArrayList(new Param(MapTools.simpleMap("id", idString.substring(1, idString.length() - 1)), Sign.IN));
        }
        Map<String, Object> paramMap = MapTools.simpleMap("simple", false);
        paramMap.put("page", 1);
        paramMap.put("rows", Integer.MAX_VALUE);
        paramMap.put(Common.PARAMS, JSONArray.toJSONString(params));
        RemoteService remoteService = serviceFactory.build(service, "/v1/projects", BoCloudMethod.GET, headers, paramMap);
        BocloudResult result = remoteService.invoke();
        if (result.isFailed()) {
            return new ArrayList<>();
        }
        String data = JSONObject.toJSONString(result.getData());
        return JSONObject.parseObject(data).getJSONArray("rows").toJavaList(Project.class);
    }

    public List<Project> projectsByCondition(Long target, Catalog catalog) {
        JSONObject object = new JSONObject();
        object.put(Common.CONDITION, "projectsByCondition");
        object.put("target", target);
        object.put("catalog", catalog.name());
        RemoteService remote = serviceFactory.build(service, "/v1/projects/condition", BoCloudMethod.GET, headers,
                MapTools.simpleMap(Common.CONDITION, object.toJSONString()));
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return Lists.newArrayList();
        }
        String data = JSONObject.toJSONString(result.getData());
        if (StringUtils.isEmpty(data)) {
            return Lists.newArrayList();
        }
        return JSONArray.parseArray(data, Project.class);
    }

    /**
     * 查询用户管理的项目
     *
     * @param userId
     * @return
     */
    public List<Project> listUserManagerProjects(Long userId) {
        JSONObject object = new JSONObject();
        object.put(Common.CONDITION, "listUserManagerProjects");
        object.put("userId", userId);
        RemoteService remote = serviceFactory.build(service, "/v1/projects/condition", BoCloudMethod.GET, headers,
                MapTools.simpleMap(Common.CONDITION, object.toJSONString()));
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return Lists.newArrayList();
        }
        String data = JSONObject.toJSONString(result.getData());
        if (StringUtils.isEmpty(data)) {
            return Lists.newArrayList();
        }
        return JSONArray.parseArray(data, Project.class);
    }

    /**
     * 查询用户有可见权限的项目
     *
     * @param userId
     * @return
     */
    public List<Project> listUserVisibleProjects(Long userId) {
        JSONObject object = new JSONObject();
        object.put(Common.CONDITION, "listUserVisibleProjects");
        object.put("userId", userId);
        RemoteService remote = serviceFactory.build(service, "/v1/projects/condition", BoCloudMethod.GET, headers,
                MapTools.simpleMap(Common.CONDITION, object.toJSONString()));
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return Lists.newArrayList();
        }
        String data = JSONObject.toJSONString(result.getData());
        if (StringUtils.isEmpty(data)) {
            return Lists.newArrayList();
        }
        return JSONArray.parseArray(data, Project.class);
    }


    /**
     * 查询租户下用户所在的全局项目（管理端项目）
     *
     * @param tenantId
     * @return
     */
    public List<UserProject> listTenantUserGlobalProjects(Long tenantId) {
        JSONObject object = new JSONObject();
        object.put(Common.CONDITION, "listTenantUserGlobalProjects");
        object.put("tenantId", tenantId);
        RemoteService remote = serviceFactory.build(service, "/v1/projects/condition", BoCloudMethod.GET, headers,
                MapTools.simpleMap(Common.CONDITION, object.toJSONString()));
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return Lists.newArrayList();
        }
        String data = JSONObject.toJSONString(result.getData());
        if (StringUtils.isEmpty(data)) {
            return Lists.newArrayList();
        }
        return JSONArray.parseArray(data, UserProject.class);
    }

    /**
     * 查询租户下项目
     *
     * @param tenantId
     * @return
     */
    public List<Project> listTenantProjects(Long tenantId) {
        RemoteService remote = serviceFactory.build(service, "/v1/tenants/" + tenantId + "/projects", BoCloudMethod.GET, headers, null);
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return Lists.newArrayList();
        }
        String data = JSONObject.toJSONString(result.getData());
        if (StringUtils.isEmpty(data)) {
            return Lists.newArrayList();
        }
        return JSONArray.parseArray(data, Project.class);
    }


    public BocloudResult<List<Project>> listByTenant(Long tenantId) {
        RemoteService remote = serviceFactory.build(service, "/v1/tenants/" + tenantId + "/projects",
                BoCloudMethod.POST, headers, null);
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return new BocloudResult<>(false, result.getMessage());
        }
        String data = JSONObject.toJSONString(result.getData());
        return new BocloudResult<>(true, JSONArray.parseArray(data, Project.class), "success");
    }

    public List<SimpleBean> list(Long businessId) {
        List<Param> params = Lists.newArrayList();
        params.add(new Param(MapTools.simpleMap("businessId", businessId), Sign.EQ));
        Map<String, Object> paramMap = MapTools.simpleMap("simple", true);
        paramMap.put(Common.PARAMS, JSONArray.toJSONString(params));
        paramMap.put("page", 1);
        paramMap.put("rows", Integer.MAX_VALUE);
        paramMap.put(Common.PARAMS, JSONArray.toJSONString(params));
        RemoteService remote = serviceFactory.build(service, "/v1/projects", BoCloudMethod.POST, headers, paramMap);
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return Lists.newArrayList();
        }
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), JSONObject.class);
        return JSONArray.parseArray(jsonObject.getString("rows"), SimpleBean.class);
    }

    public List<Project> listAll() {
        List<Param> params = Lists.newArrayList();
        Map<String, Object> paramMap = MapTools.simpleMap("simple", false);
        paramMap.put(Common.PARAMS, JSONArray.toJSONString(params));
        paramMap.put("page", 1);
        paramMap.put("rows", Integer.MAX_VALUE);
        paramMap.put(Common.PARAMS, JSONArray.toJSONString(params));
        RemoteService remote = serviceFactory.build(service, "/v1/projects", BoCloudMethod.GET, headers, paramMap);
        BocloudResult result = remote.invoke();
        if (result.isFailed()) {
            return Lists.newArrayList();
        }
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), JSONObject.class);
        return JSONArray.parseArray(jsonObject.getString("rows"), Project.class);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
        this.headers.put("source", currentService.getService().getName());
    }
}
