/**
 * Description: 部门WS接口
 * Copyright:   Copyright (c)2016
 * Company:     江苏三六五网络股份有限公司
 *
 * @author: 江苏三六五网络股份有限公司
 * @version: 1.0
 * Create at:   2016-09-14 下午 17:27:15
 * <p>
 * Modification History:
 * Date         Author      Version     Description
 * ------------------------------------------------------------------
 * 2016-09-14   江苏三六五网络股份有限公司   1.0         Initial
 */
package com.house365.ws.interfaces.impl;

import com.house365.beans.entity.DepartmentEntity;
import com.house365.beans.system.Page;
import com.house365.beans.system.QueryParams;
import com.house365.rest.context.Parameter;
import com.house365.rest.exception.ServiceRunException;
import com.house365.ws.beans.request.DepartmentListRequest;
import com.house365.ws.beans.request.DepartmentRequest;
import com.house365.ws.beans.response.DepartmentListResponse;
import com.house365.ws.beans.response.DepartmentResponse;
import com.house365.ws.dao.mapper.DepartMapper;
import com.house365.ws.interfaces.server.IDepartment;
import com.house365.ws.service.interfaces.IDepartmentService;
import com.house365.ws.service.interfaces.IHgsCacheUtil;
import com.house365.ws.service.interfaces.IWechatService;
import com.house365.ws.system.ReturnResult;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 部门WS接口<br>
 *
 * @author 江苏三六五网络股份有限公司
 * @version 1.0, 2016-09-14
 * @see
 * @since 1.0
 */
@Service("department")
public class DepartmentImpl implements IDepartment {
    /**
     * 日志记录器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(DepartmentImpl.class);
    /**
     * 部门服务对象
     */
    @Autowired
    IDepartmentService<DepartmentEntity> departmentService;
    @Autowired
    IWechatService wechatService;
    @Autowired
    private IHgsCacheUtil hgsCacheUtil;
    @Autowired
    private DepartMapper departMapper;

    @Override
    public List<DepartmentEntity> findChildrenListByPath(
            List<DepartmentEntity> parents
    ) {
        return departmentService.findChildrenListByPath(parents);
    }

    @Override
    public List<DepartmentEntity> findRootAndChild() {
        return findChildByParentId(0);
    }

    @Override
    public List<DepartmentEntity> findChildByParentId(int parentId) {
        Page page = new Page(Integer.MAX_VALUE);
        Map<String, Object> map = new HashMap<>();
        map.put("EQ_parentId", parentId);
        QueryParams<DepartmentEntity> queryParams = new QueryParams<>(map);
        queryParams.setPaging(page);
        List<DepartmentEntity> all = departmentService.queryAll(queryParams);
        return all;
    }

    @Override
    public DepartmentEntity appendChild(Integer parent, DepartmentEntity child) throws Exception {
        DepartmentEntity parentDept = departmentService.getById(parent);

        hgsCacheUtil.delChildDepartCache(parent);

        QueryParams<DepartmentEntity> queryParams = new QueryParams<>();
        queryParams.setPaging(new Page(Integer.MAX_VALUE));
        Map<String, Object> map = new HashMap<>(10);
        map.put("EQ_parentId", parent);
        queryParams.setSearchParams(map);
        List<DepartmentEntity> brothers = departmentService.queryByPage(queryParams);
        int orderNum = 1;
        if (brothers.size() > 0) {
            for (DepartmentEntity departmentEntity : brothers) {
                if (departmentEntity.getOrderNum() > orderNum) {
                    orderNum = departmentEntity.getOrderNum();
                }
            }
        }
        child.setOrderNum(orderNum);
        child.setParentId(parent);
        child.setHierarchy(parentDept.getHierarchy() + 1);
        Integer id = departmentService.save(child);

        final DepartmentEntity departmentPost = child;
        departmentPost.setName(departmentPost.getName() + id);
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    wechatService.callWechatDepartmentAPI(departmentPost, "/enterprise/department/create");
                } catch (Exception e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
        });
        child.setUrlPath(parentDept.getUrlPath() + "/" + id);
        departmentService.update(child);
        return child;
    }

    /**
     * 部门列表查询
     *
     * @param request 部门列表查询请求
     * @return 部门列表查询响应
     */
    @Override
    public DepartmentListResponse getDepartmentList(DepartmentListRequest request) {
        DepartmentListResponse response = new DepartmentListResponse();
        try {
            QueryParams<DepartmentEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setPaging(request.getPaging());
            queryParams.setOrderColumn(request.getOrderColumn());
            queryParams.setOrderMode(request.getOrderMode());
            List<DepartmentEntity> departments = departmentService.queryByPage(queryParams);
            response.setPaging(queryParams.getPaging());
            response.setObjectList(departments);
            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());
        }
        return response;
    }

    /**
     * 保存部门
     *
     * @param request 部门请求
     * @return 保存部门响应
     */
    @Override
    public DepartmentResponse addDepartment(DepartmentRequest request) {
        DepartmentResponse response = new DepartmentResponse();
        try {
            DepartmentEntity department = request.getEntity();
            hgsCacheUtil.delChildDepartCache(department.getParentId());

            Integer id = departmentService.save(department);
            response.setEntity(department);
            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());
        }
        return response;
    }

    /**
     * 删除部门通过唯一标识
     *
     * @param id 唯一标识
     * @return 删除部门响应
     */
    @Override
    public DepartmentResponse deleteDepartmentById(Integer id) {
        DepartmentResponse response = new DepartmentResponse();
        try {
            DepartmentEntity dep = getDepartmentById(id).getEntity();
            hgsCacheUtil.delChildDepartCache(dep.getParentId());

            final Integer postId = id;
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        wechatService.deleteWechatDepartment(postId);
                    } catch (Exception e) {
                        LOGGER.error(e.getMessage(), e);
                    }
                }
            });
            departmentService.delete(id);
            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());
        }
        return response;
    }

    /**
     * 修改部门
     *
     * @param request 修改部门请求
     * @return 修改部门响应
     */
    @Override
    public DepartmentResponse updateDepartment(DepartmentRequest request) {
        DepartmentResponse response = new DepartmentResponse();
        try {
            DepartmentEntity department = request.getEntity();
            hgsCacheUtil.delChildDepartCache(department.getParentId());

            final DepartmentEntity departmentPost = department;
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        wechatService.callWechatDepartmentAPI(departmentPost, "/enterprise/department/update");
                    } catch (Exception e) {
                        LOGGER.error(e.getMessage(), e);
                    }
                }
            });
            departmentService.update(request.getEntity());
            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());
        }
        return response;
    }

    /**
     * 通过ID获取部门
     *
     * @param id 唯一标识
     * @return 通过ID获取部门响应
     */
    @Override
    public DepartmentResponse getDepartmentById(Integer id) {
        DepartmentResponse response = new DepartmentResponse();
        try {
            DepartmentEntity entity = departmentService.getById(id);
            response.setEntity(entity);
            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());
        }
        return response;
    }

    @Override
    public DepartmentListResponse getDepartments(DepartmentListRequest request) {
        DepartmentListResponse response = new DepartmentListResponse();
        try {
            QueryParams<DepartmentEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setOrderColumn("id");
            queryParams.setOrderMode("asc");
            List<DepartmentEntity> departments = departmentService.queryAll(queryParams);
            if (departments.size() > 0) {
                for (DepartmentEntity department : departments) {
                    try {
                        wechatService.callWechatDepartmentAPI(department, "/enterprise/department/create");
                    } catch (Exception e) {
                        LOGGER.error(e.getMessage(), e);
                    }
                }
            }
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    @Override
    public DepartmentEntity getRoot() {
        DepartmentEntity root = departmentService.getById(1);
        if (root == null) {
            root = initRoot();
            departmentService.save(root);
        }
        return root;
    }

    private DepartmentEntity initRoot() {
        DepartmentEntity root = new DepartmentEntity();
        root.setId(1);
        root.setName("集团总部");
        root.setRoot(true);
        root.setUrlPath("/1");
        root.setHierarchy(0);
        Date date = new Date();
        root.setCreateTime(date);
        root.setUpdateTime(date);
        return root;
    }

    @Override
    public DepartmentEntity queryById(int id) {
        return departMapper.queryById(id);
    }

    @Override
    public List<DepartmentEntity> queryByCondition(Map<String, Object> map) {
        List<DepartmentEntity> list = departMapper.queryByConditions(map);
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        }
        return Collections.emptyList();
    }

    /**
     * 以下均为自动生成
     */

    @Override
    public Object exectue(Parameter parameter) throws ServiceRunException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isControlService() {
        return false;
    }

    @Override
    public boolean isLogService() {
        return false;
    }

    @Override
    public boolean isMonitorService() {
        return false;
    }

    @Override
    public Object rollback() {
        return null;
    }

    @Override
    public void commit() {
    }
}
