package com.house365.ws.util;

import com.alibaba.dubbo.common.json.JSON;
import com.alibaba.dubbo.common.json.ParseException;
import com.google.common.base.Strings;
import com.house365.beans.entity.DepartmentEntity;
import com.house365.beans.entity.UserEntity;
import com.house365.beans.system.Page;
import com.house365.beans.system.QueryParams;
import com.house365.web.util.SpringContextUtil;
import com.house365.ws.beans.request.DepartmentListRequest;
import com.house365.ws.beans.request.UserListRequest;
import com.house365.ws.beans.response.DepartmentListResponse;
import com.house365.ws.beans.response.UserListResponse;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.interfaces.server.IDepartment;
import com.house365.ws.interfaces.server.IUser;
import com.house365.ws.service.interfaces.IHgsCacheUtil;
import com.house365.ws.service.interfaces.IUserService;
import com.house365.ws.system.ReturnResult;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>Title: </p>
 * <p>Description:ss </p>
 * <p>Date: 2017/5/16</p>
 *
 * @author XN
 * @version 1.0
 */
@Service("hgsCacheUtil")
public class HgsCacheUtil implements IHgsCacheUtil {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private IDepartment department;

    @Autowired
    private IUserService user;

    /**
     * cache child department list
     *
     * @param parentId
     * @return
     */
    @Override
    public List<DepartmentEntity> getChildDeptments(Integer parentId) {
        List<DepartmentEntity> result = null;

        if (null == parentId) {
            return result;
        }
        RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
        String cacheKey = "HGS_childdepartment_" + parentId;
        if (redisUtils.hasKey(cacheKey) && redisUtils.getValByKeyNew(cacheKey) != null) {
            String cache = redisUtils.getValByKeyNew(cacheKey);

            if (!Strings.isNullOrEmpty(cache)) {
                result = com.alibaba.fastjson.JSON.parseArray(cache, DepartmentEntity.class);
            }

        }

        if (result == null) {
            Map<String, Object> depMap = new HashMap<>();
            depMap.put("EQ_parentId", parentId);

            DepartmentListRequest departmentListRequest = new DepartmentListRequest();
            Page departPage = new Page(Integer.MAX_VALUE);
            departmentListRequest.setPaging(departPage);
            departmentListRequest.setSearchParams(depMap);
            departmentListRequest.setOrderColumn("orderNum");
            departmentListRequest.setOrderMode(" asc");
            DepartmentListResponse departmentListResponse = department.getDepartmentList(departmentListRequest);
            result = departmentListResponse.getObjectList();
            redisUtils.setValueExpireNew(cacheKey, com.alibaba.fastjson.JSON.toJSONString(result), 10, TimeUnit.HOURS);
        }

        return result;
    }

    @Override
    public void delChildDepartCache(Integer deptId) {
        if (deptId != null) {
            RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
            String cacheKey = "HGS_childdepartment_" + deptId;
            redisUtils.deleteByKeyNew(cacheKey);
        }
    }

    @Override
    public void delChildTreeCache(Integer id) {
        if (id != null) {
            RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
            String cacheKey = "HGS_childnode_" + id;
            redisUtils.deleteByKeyNew(cacheKey);
        }
    }

    @Override
    public void delChildUserIds(Integer userId) {
        if (userId != null) {
            RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
            String key = "userOnPath_" + userId;
            redisUtils.deleteByKeyNew(key);
        }
    }

    @Override
    public UserListResponse getUserListByDept(DepartmentEntity dept, Map<String, Object> userParaMap, Page page) {
        List<UserEntity> result = null;

        if (null == dept) {
            return null;
        }

        UserListResponse response = new UserListResponse();

        RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
        StringBuilder q = new StringBuilder("");
        for (Map.Entry entry : userParaMap.entrySet()) {
            q.append(entry.getKey()).append("_").append(entry.getValue());
        }

        String cacheKey = "HGS_department_user_" + dept.getId() + "_q_" + q.toString() + "_p_" + page.getCurrentPage() + "_" + page.getPageSize();
        String pageCacheKey = cacheKey + "_page";
        if (redisUtils.hasKey(cacheKey) && redisUtils.getValByKeyNew(cacheKey) != null) {
            String cache = redisUtils.getValByKeyNew(cacheKey);

            result = com.alibaba.fastjson.JSON.parseArray(cache, UserEntity.class);

            response.setObjectList(result);

            String pageCache = redisUtils.getValByKeyNew(pageCacheKey);

            if (!Strings.isNullOrEmpty(pageCache)) {
                Page paging = com.alibaba.fastjson.JSON.parseObject(pageCache, Page.class);
                response.setPaging(paging);
            }

        }

        if (result == null) {
            userParaMap.put("EQ_urlPathLike", dept.getUrlPath());
            userParaMap.put("EQ_enabled", "1");

            try {
                QueryParams<UserEntity> queryParams = new QueryParams<UserEntity>(userParaMap);
                queryParams.setPaging(page);
                queryParams.setOrderColumn("id");
                queryParams.setOrderMode(" asc");
                List<UserEntity> users = user.queryByPage(queryParams);
                response.setPaging(page);
                response.setObjectList(users);
                response.setResultCode(ReturnResult.SUCCESS.getResultCode());
                response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());
            } catch (Exception ex) {
                logger.error(ex.getMessage(), ex);
                response.setResultCode(ReturnResult.FAIL.getResultCode());
                response.setResultMessage(ex.getMessage());
            }

            result = response.getObjectList();
            page = response.getPaging();
            redisUtils.setValueExpireNew(cacheKey, com.alibaba.fastjson.JSON.toJSONString(result), 1, TimeUnit.MINUTES);
            redisUtils.setValueExpireNew(pageCacheKey, com.alibaba.fastjson.JSON.toJSONString(page), 1, TimeUnit.MINUTES);

        }

        return response;
    }

    @Override
    public Map<String, Object> getSummary(String managerId) {
        Map<String, Object> result = null;

        if (null == managerId) {
            return result;
        }

        RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
        String cacheKey = "HGS_summary_mananger_" + managerId;

        if (redisUtils.hasKey(cacheKey) && redisUtils.getValByKeyNew(cacheKey) != null) {
            String cache = redisUtils.getValByKeyNew(cacheKey);

            if (!Strings.isNullOrEmpty(cache)) {
                result = com.alibaba.fastjson.JSON.parseObject(cache, Map.class);
            }
        }

        if (result == null) {
            result = user.getSummary(managerId);

            redisUtils.setValueExpireNew(cacheKey, com.alibaba.fastjson.JSON.toJSONString(result), 1, TimeUnit.HOURS);
        }

        return result;
    }

    @Override
    public void delUserSummary(Integer userId) {
        if (userId != null) {
            RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
            String key = "HGS_summary_mananger_" + userId;
            redisUtils.deleteByKeyNew(key);
        }
    }


}
