package com.sunyard.ssp.modules.user.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.common.constant.ValidatorConstant;
import com.sunyard.ssp.modules.user.entity.ScDepartment;
import com.sunyard.ssp.modules.user.entity.ScDepartmentHeader;
import com.sunyard.ssp.modules.user.entity.ScRoleDepartment;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.service.IScDepartmentHeaderService;
import com.sunyard.ssp.modules.user.service.IScDepartmentService;
import com.sunyard.ssp.modules.user.service.IScRoleDepartmentService;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.modules.user.utils.validator.DepartmentValidator;
import com.sunyard.ssp.redis.RedisObjectOperation;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.DataBinder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author tsz
 * @since 2020-03-12
 */
@RestController
@Slf4j
@RequestMapping("/department")
@Transactional
public class ScDepartmentController {

    @Autowired
    DepartmentValidator departmentValidator;

    @Autowired
    private IScDepartmentService departmentService;

    @Autowired
    private IScUserService userService;

    @Autowired
    private IScRoleDepartmentService roleDepartmentService;

    @Autowired
    private IScDepartmentHeaderService departmentHeaderService;

    /*@Autowired
    private StringRedisTemplate redisTemplate;*/

    @Autowired
    private RedisObjectOperation redisObjectOperation;

    @Autowired
    private SecurityUtil securityUtil;

    @InitBinder(value = ValidatorConstant.DEPARTMENT_BASE_NAME)
    public void initBainder(DataBinder binder){
        binder.replaceValidators(departmentValidator);
    }

    @RequestMapping(value = "/getByParentId/{parentId}",method = RequestMethod.GET)
    @ApiOperation(value = "通过id获取")
    public Result<List<ScDepartment>> getByParentId(@PathVariable Long parentId,
                                                  @ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "false") Boolean openDataFilter){

        List<ScDepartment> list = new ArrayList<>();
        ScUser u = securityUtil.getCurrUser();

        list = departmentService.findByParentIdOrderBySortOrder(parentId, openDataFilter);
        list = setInfo(list);
        return new ResultUtil<List<ScDepartment>>().setData(list);
    }

    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @ApiOperation(value = "添加")
    public Result<Object> add(@ModelAttribute(ValidatorConstant.DEPARTMENT_BASE_NAME) @Validated ScDepartment department){

        departmentService.save(department);
        // 如果不是添加的一级 判断设置上级为父节点标识
        if(department.getParentId()!=null && !CommonConstant.PARENT_ID.equals(department.getParentId())){
            ScDepartment parent = departmentService.getById(department.getParentId());
            if(parent.getIsParent()==null||!parent.isParent()){
                parent.setIsParent(true);
                departmentService.updateById(parent);
            }
        }
        // 更新缓存
        Set<String> keys = redisObjectOperation.keys("department::*");
        redisObjectOperation.delete(keys);
        return new ResultUtil<Object>().setData(department,"添加成功");
    }

    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    @ApiOperation(value = "编辑")
    public Result<Object> edit(@ModelAttribute(ValidatorConstant.DEPARTMENT_BASE_NAME) @Validated ScDepartment department,
                               @RequestParam(required = false) Long[] mainHeader,
                               @RequestParam(required = false) Long[] viceHeader){

        ScDepartment originDepartment = departmentService.getById(department.getId());
        if(!originDepartment.getParentId().equals(department.getParentId())){
            return new ResultUtil<Object>().setErrorMsg("禁止编辑上级部门");
        }

        departmentService.updateById(department);
        // 先删除原数据
        departmentHeaderService.remove(new QueryWrapper<ScDepartmentHeader>().lambda()
                .eq(ScDepartmentHeader::getDepartmentId, department.getId()));
        for(Long id:mainHeader){
            ScDepartmentHeader dh = new ScDepartmentHeader();
            dh.setUserId(id);
            dh.setDepartmentId(department.getId());
            dh.setType(CommonConstant.HEADER_TYPE_MAIN);
            departmentHeaderService.save(dh);
        }
        for(Long id:viceHeader){
            ScDepartmentHeader dh = new ScDepartmentHeader();
            dh.setUserId(id);
            dh.setDepartmentId(department.getId());
            dh.setType(CommonConstant.HEADER_TYPE_VICE);
            departmentHeaderService.save(dh);
        }
        // 手动删除所有部门缓存
        Set<String> keys = redisObjectOperation.keys("department:" + "*");
        redisObjectOperation.delete(keys);
        // 删除所有用户缓存
        Set<String> keysUser = redisObjectOperation.keys("user:" + "*");
        redisObjectOperation.delete(keysUser);
        return new ResultUtil<Object>().setData(department,"编辑成功");
    }

    @RequestMapping(value = "/delByIds/{ids}",method = RequestMethod.DELETE)
    @ApiOperation(value = "批量通过id删除")
    public Result<Object> delByIds(@PathVariable String[] ids){

        for(String id:ids){
            List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getOrganizationId, id));
            if(list!=null&&list.size()>0){
                return new ResultUtil<Object>().setErrorMsg("删除失败，包含正被用户使用关联的部门");
            }
            ScDepartment department = departmentService.getById(id);
            List<ScDepartment> departments = departmentService.findByParentIdOrderBySortOrder(department.getId(), false);
            if(departments!=null&&departments.size()>0){
                return new ResultUtil<Object>().setErrorMsg("删除失败，待删除部门下还有子部门");
            }
        }
        for(String id:ids){
            departmentService.removeById(id);
            // 删除关联数据权限
            roleDepartmentService.remove(new QueryWrapper<ScRoleDepartment>().lambda()
                    .eq(ScRoleDepartment::getDepartmentId, id));
            // 删除关联部门负责人
            departmentHeaderService.remove(new QueryWrapper<ScDepartmentHeader>().lambda()
                    .eq(ScDepartmentHeader::getDepartmentId, id));
        }
        // 手动删除所有部门缓存
        Set<String> keys = redisObjectOperation.keys("department:" + "*");
        redisObjectOperation.delete(keys);
        // 删除数据权限缓存
        Set<String> keysUserRoleData = redisObjectOperation.keys("userRole::depIds:" + "*");
        redisObjectOperation.delete(keysUserRoleData);
        return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
    }

    @RequestMapping(value = "/search",method = RequestMethod.GET)
    @ApiOperation(value = "部门名模糊搜索")
    public Result<List<ScDepartment>> searchByTitle(@RequestParam String title,
                                                  @ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "false") Boolean openDataFilter){

        List<ScDepartment> list = departmentService.findByTitleLikeOrderBySortOrder("%"+title+"%", openDataFilter);
        list = setInfo(list);
        return new ResultUtil<List<ScDepartment>>().setData(list);
    }

    public List<ScDepartment> setInfo(List<ScDepartment> list){

        // lambda表达式
        list.forEach(item -> {
            if(!CommonConstant.PARENT_ID.equals(item.getParentId())){
                ScDepartment parent = departmentService.getById(item.getParentId());
                if(parent != null){
                    item.setParentTitle(parent.getTitle());
                }else{
                    item.setParentTitle("");
                }
            }else{
                item.setParentTitle("一级部门");
            }
            // 设置负责人
            List<ScDepartmentHeader> mainHeaderList = departmentHeaderService.list(new QueryWrapper<ScDepartmentHeader>().lambda()
                    .eq(ScDepartmentHeader::getDepartmentId, item.getId())
                    .eq(ScDepartmentHeader::getType, CommonConstant.HEADER_TYPE_MAIN));
            List<ScDepartmentHeader> viceHeaderList = departmentHeaderService.list(new QueryWrapper<ScDepartmentHeader>().lambda()
                    .eq(ScDepartmentHeader::getDepartmentId, item.getId())
                    .eq(ScDepartmentHeader::getType, CommonConstant.HEADER_TYPE_VICE));

            if(CollectionUtils.isNotEmpty(mainHeaderList)){
                item.setMainHeader(mainHeaderList.stream().map(scDepartmentHeader -> scDepartmentHeader.getUserId()).collect(Collectors.toList()));
            }

            if(CollectionUtils.isNotEmpty(viceHeaderList)){
                item.setViceHeader(viceHeaderList.stream().map(scDepartmentHeader -> scDepartmentHeader.getUserId()).collect(Collectors.toList()));
            }

        });
        return list;
    }
    @RequestMapping(value = "/getAllJSON",method = RequestMethod.GET)
    @ApiOperation(value = "获取全部部门的json格式数据")
    public Result<JSONArray> getAllJSON(@ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "true") Boolean openDataFilter){
        JSONArray res = getByPid(CommonConstant.DEPARTMENT_ROOT_ID,openDataFilter);

        return new ResultUtil().setData(res);

    }

    @RequestMapping(value = "/getAllList", method = RequestMethod.GET)
    public Result<List<ScDepartment>> getAllList(){
        return new ResultUtil().setData(departmentService.list());
    }

    private JSONArray getByPid(Long pId, Boolean openDataFilter){
        JSONArray res = new JSONArray();
        List<ScDepartment> list = departmentService.findByParentIdOrderBySortOrder(pId, openDataFilter);
        if (CollectionUtils.isEmpty(list)){
            return null;
        }

        for (int i = 0; i < list.size(); i++) {
            JSONObject departmentJSON = new JSONObject();
            departmentJSON.put("title",list.get(i).getTitle());
            departmentJSON.put("id",list.get(i).getId());
            departmentJSON.put("childern",getByPid(list.get(i).getId(),openDataFilter));
            res.add(departmentJSON);
        }

        return res;
    }
}
