/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称: 大恒泰山系统
 * 创建日期:2022/8/22
 */
package org.springblade.modules.baseinfo.org.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import org.springblade.constant.BusinessConstant;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.baseinfo.org.dto.OrgInfoDTO;
import org.springblade.modules.baseinfo.org.entity.DeptAttEntity;
import org.springblade.modules.baseinfo.org.entity.DeptRegionEntity;
import org.springblade.modules.baseinfo.org.entity.OrgEntity;
import org.springblade.modules.baseinfo.org.entity.OrgTreeNodeEntity;
import org.springblade.modules.baseinfo.org.service.IDeptAttService;
import org.springblade.modules.baseinfo.org.service.IDeptRegionService;
import org.springblade.modules.baseinfo.org.service.IOrgService;
import org.springblade.modules.baseinfo.org.vo.OrgInfoVO;
import org.springblade.modules.baseinfo.org.wrapper.OrgInfoWrapper;
import org.springblade.modules.baseinfo.region.dto.RegionInfoDTO;
import org.springblade.modules.baseinfo.region.entity.RegionInfoEntity;
import org.springblade.modules.baseinfo.region.entity.RegionTreeNodeEntity;
import org.springblade.modules.system.entity.Dept;
import org.springblade.modules.system.entity.Role;
import org.springblade.modules.system.service.IDeptService;
import org.springblade.modules.system.service.IRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;


/***
 * Date:2022/8/22
 * Title: 组织机构管理
 * Description：系统管理员管理盟市，盟市管理员管理运维单位
 * @author swp
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@RestController
@RequestMapping("galaxy-business/baseinfo/org")
@AllArgsConstructor
@Api(value = "运维单位管理", tags = "运维单位管理")
public class BaseOrgController extends BladeController {
    private final IDeptService deptService;
    private final IDeptRegionService deptRegionService;
    private final IOrgService orgService;
    private final IDeptAttService deptAttService;
    private final IRoleService roleService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @GetMapping("/list")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "分页")
    public R<List<OrgInfoVO>> list() {
//        BladeUser user = AuthUtil.getUser();
//        if (BusinessConstant.ROLE_SYS_ADMIN.equals(user.getRoleName()) || BusinessConstant.ROLE_ORG_ADMIN.equals(user.getRoleName())) {
//            LambdaQueryWrapper<Dept> wrapper = Wrappers.<Dept>query().lambda();
//            wrapper.eq(Dept::getIsDeleted, 0);
//            wrapper.eq(Dept::getParentId, Func.toLong(user.getDeptId()));
//            List<Dept> pages = deptService.list(wrapper);
//            return R.data(OrgInfoWrapper.build().listVO(pages));
//        } else {
            return R.data(null);
       // }
    }

    /**
     * 多表联合查询自定义分页
     */
    @GetMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptName", value = "机构名称", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "parentId", value = "机构父ID", paramType = "query", dataType = "long"),
    })
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "分页")
    public R<IPage<OrgInfoVO>> page(@ApiIgnore OrgInfoDTO dto, Query query) {
        BladeUser user = AuthUtil.getUser();
        LambdaQueryWrapper<Role> rolewrapper = Wrappers.<Role>query().lambda();
        rolewrapper.eq(Role::getRoleAlias, BusinessConstant.ROLE_SYS_ADMIN);
        rolewrapper.last("limit 1");
        Role role = roleService.getOne(rolewrapper);
        if (Func.isNull(role)) {
            return R.fail("查询错误");
        }
        if (!user.getRoleId().equals(Func.toStr(role.getId()))) {
            if (Func.isNull(dto.getTenantId())) {
                dto.setTenantId(user.getTenantId());
            }
        }
        if (Func.isNull(dto.getParentId())) {
            dto.setParentId(Func.toLong(user.getDeptId()));
        }
        IPage<OrgInfoVO> pages = orgService.selectPage(Condition.getPage(query), dto);
        List<OrgInfoVO> list = pages.getRecords();
        for (OrgInfoVO vo:list){
            OrgInfoWrapper.build().entityVO(vo);
        }
        return R.data(pages);
    }

    /**
     * 详情
     */
//    @GetMapping("/detail")
//    @ApiOperationSupport(order = 2)
//    @ApiOperation(value = "详情", notes = "传入 Dept")
//    public R<Dept> detail(Dept dept) {
//        Dept vo = deptService.getById(dept.getId());
//
//        return R.data(OrgInfoWrapper.build().entityVO(vo));
//    }

    @GetMapping("/region")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "取行政区信息", notes = "传入 Dept")
    public R<Dept> getRegion(Dept dept) {
        Dept vo = deptService.getById(dept.getId());
        return R.data(vo);
    }

    /**
     * 新增
     */
    @PostMapping("/save")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "新增", notes = "传入 Dept")
    @Transactional
    public R save(@RequestBody OrgInfoDTO orgInfoDTO) {
        Dept dept = new Dept();
        dept.setDeptName(orgInfoDTO.getDeptName());
        dept.setFullName(orgInfoDTO.getDeptName());
        if (Func.isNull(orgInfoDTO.getParentId())) {
            dept.setParentId(BusinessConstant.ORG_ROOT_ID);
        } else {
            dept.setParentId(orgInfoDTO.getParentId());
        }
        Dept parentDept = deptService.getById(dept.getParentId());
        dept.setAncestors(parentDept.getAncestors() + "," + parentDept.getId());
        dept.setRemark(orgInfoDTO.getRemark());
        dept.setDeptCategory(2);
        deptService.save(dept);
        DeptAttEntity deptAttEntity = new DeptAttEntity();
        deptAttEntity.setDeptId(dept.getId());
        deptAttEntity.setRegType(1);
        return R.status(deptAttService.save(deptAttEntity));
    }

    /**
     * 修改
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "修改", notes = "传入 Dept")
    public R update(@RequestBody Dept dept) {
        return R.status(deptService.updateById(dept));
    }

    /**
     * 新增或修改
     */
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "新增或修改", notes = "传入 Dept")
    public R submit(@RequestBody Dept dept) {
        return R.status(deptService.saveOrUpdate(dept));
    }

    /**
     * 删除
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "逻辑删除", notes = "传入ID数组")
    public R remove(@ApiParam(value = "主键集合") @RequestParam String ids) {
        if (null == ids) {
            return R.status(false);
        }
        List<Long> list = Func.toLongList(ids);
        for (Long id : list) {
            deptService.removeById(id);
        }
        return R.status(true);
    }

    @GetMapping("/lazy-tree")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "行政区划代码", paramType = "query", dataType = "long"),
    })
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "树")
    public R<List<OrgTreeNodeEntity>> lazyTree(@ApiIgnore OrgInfoDTO dto) {
        BladeUser user = AuthUtil.getUser();
        if (Func.isNull(dto.getTenantId())) {
            dto.setTenantId(user.getTenantId());
        }
        LambdaQueryWrapper<Role> rolewrapper = Wrappers.<Role>query().lambda();
        rolewrapper.eq(Role::getRoleAlias, BusinessConstant.ROLE_SYS_ADMIN);
        rolewrapper.last("limit 1");
        Role role = roleService.getOne(rolewrapper);
        if (Func.isNull(role)) {
            return R.fail("查询错误");
        }
        List<OrgTreeNodeEntity> nodeEntities = new LinkedList<>();
        LambdaQueryWrapper<Dept> wrapper = Wrappers.<Dept>query().lambda();
        wrapper.eq(Dept::getIsDeleted, 0);
        if (!user.getRoleId().equals(Func.toStr(role.getId()))) {
            wrapper.eq(Dept::getTenantId, dto.getTenantId());
        }
        if (Func.notNull(dto.getParentId())) {
            wrapper.eq(Dept::getParentId, Func.toLong(dto.getParentId()));
        } else {
            wrapper.eq(Dept::getParentId, BusinessConstant.ORG_ROOT_ID);
        }
        List<Dept> list = this.deptService.list(wrapper);
        for (Dept entity : list) {
            OrgTreeNodeEntity nodeEntity = new OrgTreeNodeEntity();
            nodeEntity.setId(Func.toStr(entity.getId()));
            nodeEntity.setValue(Func.toStr(entity.getId()));
            nodeEntity.setTitle(entity.getDeptName());
            nodeEntity.setText(entity.getDeptName());
            nodeEntity.setKey(Func.toStr(entity.getId()));
            nodeEntity.setParentId(Func.toStr(entity.getParentId()));
            LambdaQueryWrapper<Dept> childrenWrapper = Wrappers.<Dept>query().lambda();
            childrenWrapper.eq(Dept::getParentId, entity.getId());
            long count = this.deptService.count(childrenWrapper);
            if (count > 0) {
                nodeEntity.setHasChildren(true);
            } else {
                nodeEntity.setHasChildren(false);
            }
            nodeEntities.add(nodeEntity);
        }
        return R.data(nodeEntities);
    }

    @GetMapping("/tree")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "树")
    public R<List<OrgTreeNodeEntity>> orgTree() {
        //ValueOperations<String, String> opsHash = redisTemplate.opsForValue();
        List<OrgTreeNodeEntity> nodeEntities = new LinkedList<>();
        BladeUser user = AuthUtil.getUser();
        LambdaQueryWrapper<Dept> wrapper = Wrappers.<Dept>query().lambda();
        wrapper.eq(Dept::getId, Func.toLong(user.getDeptId()));
        List<Dept> list = this.deptService.list(wrapper);
        for (Dept entity : list) {
            OrgTreeNodeEntity nodeEntity = new OrgTreeNodeEntity();
            nodeEntity.setId(Func.toStr(entity.getId()));
            nodeEntity.setValue(Func.toStr(entity.getId()));
            nodeEntity.setTitle(entity.getDeptName());
            nodeEntity.setText(entity.getDeptName());
            nodeEntity.setKey(Func.toStr(entity.getId()));
            nodeEntity.setParentId(Func.toStr(entity.getParentId()));
            getChildren(nodeEntity, entity);
            if (nodeEntity.getChildren() != null && nodeEntity.getChildren().size() > 0) {
                nodeEntity.setHasChildren(true);
            } else {
                nodeEntity.setHasChildren(false);
            }
            nodeEntities.add(nodeEntity);
        }
        return R.data(nodeEntities);
    }


    @GetMapping("/tree/{orgId}")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "树")
    public R<List<OrgTreeNodeEntity>> orgTree(@PathVariable(name = "orgId") String orgId) {
        List<OrgTreeNodeEntity> nodeEntities = new LinkedList<>();
        LambdaQueryWrapper<Dept> deptRegionEntityLambdaQueryWrapper = Wrappers.<Dept>query().lambda();
        deptRegionEntityLambdaQueryWrapper.eq(Dept::getIsDeleted, 0);
        deptRegionEntityLambdaQueryWrapper.eq(Dept::getId, Func.toLong(orgId));
        List<Dept> list = deptService.list(deptRegionEntityLambdaQueryWrapper);
        for (Dept entity : list) {
            OrgTreeNodeEntity nodeEntity = new OrgTreeNodeEntity();
            nodeEntity.setId(Func.toStr(entity.getId()));
            nodeEntity.setValue(Func.toStr(entity.getId()));
            nodeEntity.setTitle(entity.getDeptName());
            nodeEntity.setText(entity.getDeptName());
            nodeEntity.setKey(Func.toStr(entity.getId()));
            nodeEntity.setParentId(Func.toStr(entity.getParentId()));
            getChildren(nodeEntity, entity);
            if (nodeEntity.getChildren() != null && nodeEntity.getChildren().size() > 0) {
                nodeEntity.setHasChildren(true);
            } else {
                nodeEntity.setHasChildren(false);
            }
            nodeEntities.add(nodeEntity);
        }
        return R.data(nodeEntities);
    }

    private void getChildren(OrgTreeNodeEntity nodeEntity, Dept orgEntity) {
        LambdaQueryWrapper<Dept> queryWrapper = Wrappers.<Dept>query().lambda();
        queryWrapper.eq(Dept::getParentId, Func.toLong(orgEntity.getId()));
        List<Dept> list = deptService.list(queryWrapper);
        if (null != list && list.size() > 0) {
            List<OrgTreeNodeEntity> nodeEntities = new LinkedList<>();
            for (Dept entity : list) {
                OrgTreeNodeEntity node = new OrgTreeNodeEntity();
                node.setId(Func.toStr(entity.getId()));
                node.setValue(Func.toStr(entity.getId()));
                node.setTitle(entity.getDeptName());
                node.setText(entity.getDeptName());
                node.setKey(Func.toStr(entity.getId()));
                node.setParentId(Func.toStr(entity.getParentId()));
                getChildren(node, entity);
                if (node.getChildren() != null && node.getChildren().size() > 0) {
                    node.setHasChildren(true);
                } else {
                    node.setHasChildren(false);
                }
                nodeEntities.add(node);
            }
            nodeEntity.setChildren(nodeEntities);
        }
    }
}
