package com.yifu.cloud.plus.v1.business.controller.system;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yifu.cloud.plus.v1.business.entity.system.TBusDept;
import com.yifu.cloud.plus.v1.business.service.system.TBusDeptService;
import com.yifu.cloud.plus.v1.business.vo.system.BusDeptVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.UpdateEmployeeExtendRedundancyDTO;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.log.annotation.SysLog;
import com.yifu.cloud.plus.v1.yifu.common.security.annotation.Inner;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * B端部门表
 *
 * @author hgw
 * @date 2021-08-10 10:38:44
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/tbusdept")
@Tag(name = "B端部门表")
public class TBusDeptController {

     private final TBusDeptService tBusDeptService;

	 private final ArchivesDaprUtil archivesDaprUtil;

     /**
      * 简单分页查询
      *
      * @param page     分页对象
      * @param tBusDept B端部门表
      * @return
      */
	 @Operation(summary = "简单分页查询", description = "简单分页查询")
	 @GetMapping("/page")
     public R<IPage<TBusDept>> getTBusDeptPage(Page<TBusDept> page, TBusDept tBusDept) {
          return new R<>(tBusDeptService.getTBusDeptPage(page, tBusDept));
     }

     /**
      * 检查名称是否重复，false：不重复，可以使用的名称
      * @param name 名称
      * @return
      */
     private boolean getDeptByName(Integer id, String name) {
          List<TBusDept> list = tBusDeptService.getDeptByName(id, name);
          return (list != null && !list.isEmpty());
     }

     /**
      * 查询父级的平级list
      * @return
      */
	 @Operation(summary = "查询父级的平级list", description = "查询父级的平级list")
	 @GetMapping("/getParentList")
     public R<List<TBusDept>> getParentList(Integer pid) {
          if (Common.isNotNull(pid)) {
               TBusDept parent = tBusDeptService.getById(pid);
               if (parent != null && Common.isNotNull(parent.getLevel())) {
                    TBusDept parentDept = new TBusDept();
                    parentDept.setLevel(parent.getLevel());
                    return new R<>(tBusDeptService.getTBusDeptList(parentDept));
               }
          }
          return new R<>();
     }

     /**
      * 查询所有的list
      * @param tBusDept B端部门表
      * @return
      */
	 @Operation(summary = "查询所有的list", description = "查询所有的list")
	 @GetMapping("/getTBusDeptList")
     public R<List<TBusDept>> getTBusDeptList(TBusDept tBusDept) {
          return new R<>(tBusDeptService.getTBusDeptList(tBusDept));
     }

	 /**
	  * @param tBusDept
	  * @Description: B端人员调用的部门
	  * @Author: hgw
	  * @Date: 2023/1/4 11:38
	  * @return: com.yifu.cloud.plus.v1.business.vo.system.BusDeptVo
	  **/
	 @PostMapping("/inner/getTBusDeptList")
	 @Inner
     public BusDeptVo innerGetTBusDeptList(TBusDept tBusDept) {
		 BusDeptVo vo = new BusDeptVo();
		 vo.setBusDeptList(tBusDeptService.getTBusDeptList(tBusDept));
		 return vo;
     }

     /**
      * 查询所有的list 包含删除
      * @param tBusDept B端部门表
      * @return
      */
	 @Operation(summary = "查询所有的list", description = "查询所有的list")
	 @GetMapping("/getTBusDeptListAsso")
     public R<List<TBusDept>> getTBusDeptListAsso(TBusDept tBusDept) {
          return new R<>(tBusDeptService.getTBusDeptListAsso(tBusDept));
     }

     /**
      * 查询部门树
      * @param rootDept B端部门表，id是想要查询的顶级节点
      * @return
      */
	 @Operation(summary = "查询tree", description = "查询tree")
	 @GetMapping("/getTBusDeptTree")
     public R<TBusDept> getTBusDeptTree(TBusDept rootDept) {
          if (rootDept == null || rootDept.getId() == null) {
               rootDept = tBusDeptService.getById(1);
          } else {
               rootDept = tBusDeptService.getById(rootDept.getId());
          }
          List<TBusDept> deptList = tBusDeptService.getTBusDeptSubList(rootDept.getId(), rootDept.getTreeLogo());
          this.getSubList(rootDept, deptList);
          return new R<>(rootDept);
     }

     /**
      * @param rootDept 上级部门
      * @param deptList 所有部门信息
      * @Description:
      * @Author: hgw
      * @Date: 2021/8/10 15:49
      * @return: com.yifu.cloud.v1.hrobusiness.api.entity.system.TBusDept
      **/
     private void getSubList(TBusDept rootDept, List<TBusDept> deptList) {
          List<TBusDept> deptListCopy = new ArrayList<>(deptList);
          List<TBusDept> subList;
          for (TBusDept dept : deptList) {
               if (dept.getPid().equals(rootDept.getId())) {
                    subList = rootDept.getChildren();
                    if (subList == null) {
                         subList = new ArrayList<>();
                    }
                    deptListCopy.remove(dept);
                    // 递归塞子集
                    if (!deptListCopy.isEmpty()) {
                         getSubList(dept, deptListCopy);
                    }
                    subList.add(dept);
                    rootDept.setChildren(subList);
               }
          }
     }

     /**
      * 通过id查询单条记录
      *
      * @param id
      * @return R
      */
	 @Operation(summary = "id查询", description = "id查询")
	 @GetMapping("/{id}")
     public R<TBusDept> getById(@PathVariable("id") Integer id) {
          return new R<>(tBusDeptService.getById(id));
     }

     /**
      * 新增记录
      *
      * @param tBusDept
      * @return R
      */
	 @Operation(summary = "新增(yifu-mvp-business:tbusdept_add)", description = "新增(yifu-mvp-business:tbusdept_add)")
	 @PostMapping
//     @PreAuthorize("@pms.hasPermission('yifu-mvp-business:tbusdept_add')")
     public R<Boolean> save(@RequestBody TBusDept tBusDept) {
          String error;
          if (Common.isNotNull(tBusDept.getName())) {
               boolean flag = this.getDeptByName(null, tBusDept.getName());
               if (flag) {
                    return R.failed("部门名称不可重复");
               }
          } else {
               return R.failed("部门名称不可为空");
          }
          if (tBusDept.getPid() != null) {
               TBusDept parentDept = tBusDeptService.getById(tBusDept.getPid());
               if (parentDept != null && parentDept.getId() != null) {
                    YifuUser user = SecurityUtils.getUser();
                    if (user != null && user.getId() != null) {
                         tBusDept.setCreateTime(LocalDateTime.now());
                         tBusDept.setCreateUserId(user.getId());
                         tBusDept.setCreateUserName(user.getNickname());
                         tBusDept.setLevel(parentDept.getLevel() + CommonConstants.ONE_INT);
                         tBusDeptService.save(tBusDept);
                         tBusDept.setTreeLogo(parentDept.getTreeLogo() + CommonConstants.CENTER_SPLIT_LINE_STRING+tBusDept.getId());
                         boolean flag = tBusDeptService.updateById(tBusDept);
                         return new R<>(flag);
                    } else {
                         error = "未获取到登录人信息！";
                    }
               } else {
                    error = "根据pid，未获取到上级信息！";
               }
          } else {
               error = "pid不可为空！";
          }
          return R.failed(error);
     }

     /**
      * 修改记录
      *
      * @param tBusDept
      * @return R
      */
	 @Operation(summary = "修改(yifu-mvp-business:tbusdept_edit)", description = "修改(yifu-mvp-business:tbusdept_edit)")
	 @SysLog("修改B端部门表")
     @PutMapping
//     @PreAuthorize("@pms.hasPermission('yifu-mvp-business:tbusdept_edit')")
     public R<Boolean> update(@RequestBody TBusDept tBusDept) {
          if (Common.isNotNull(tBusDept.getName()) && Common.isNotNull(tBusDept.getId())) {
               boolean flag = this.getDeptByName(tBusDept.getId(), tBusDept.getName());
               if (flag) {
                    return R.failed("部门名称不可重复");
               }
               TBusDept deptOld = tBusDeptService.getById(tBusDept.getId());
               if (deptOld != null && Common.isNotNull(tBusDept.getPid())
                       && !deptOld.getPid().equals(tBusDept.getPid())) {
                    TBusDept parentDept = tBusDeptService.getById(tBusDept.getPid());
                    if (parentDept != null && parentDept.getId() != null) {
                         String oldLogo = deptOld.getTreeLogo() + CommonConstants.CENTER_SPLIT_LINE_STRING;
                         String newLogo = parentDept.getTreeLogo() + CommonConstants.CENTER_SPLIT_LINE_STRING + tBusDept.getId();
                         tBusDept.setTreeLogo(newLogo);
                         newLogo += CommonConstants.CENTER_SPLIT_LINE_STRING;
                         tBusDeptService.updateAllTreeLogo(oldLogo, newLogo);
                    } else {
                         return R.failed("根据pid，未获取到上级信息！");
                    }
               }
          } else {
               return R.failed("部门id、名称不可为空");
          }
          boolean isSuccess = tBusDeptService.updateById(tBusDept);

		  //更新人员表冗余字段
          if (isSuccess) {
               UpdateEmployeeExtendRedundancyDTO dto = new UpdateEmployeeExtendRedundancyDTO();
               dto.setDepartId(tBusDept.getId());
               dto.setDepartName(tBusDept.getName());
               dto.setTreeLogo(tBusDept.getTreeLogo());
               dto.setDepartIdVal(tBusDept.getId());
               archivesDaprUtil.updateEmployeeExtendRedundancy(CollUtil.newArrayList(dto));
          }
          return new R<>(isSuccess);
     }

     /**
      * 通过id删除一条记录
      *
      * @param id
      * @return R
      */
	 @Operation(summary = "假删除(yifu-mvp-business:tbusdept_del)", description = "假删除(yifu-mvp-business:tbusdept_del)")
	 @SysLog("假删除B端部门表")
     @DeleteMapping("/{id}")
//     @PreAuthorize("@pms.hasPermission('yifu-mvp-business:tbusdept_del')")
     public R<Boolean> removeById(@PathVariable Integer id) {
          TBusDept tBusDept = new TBusDept();
          tBusDept.setPid(id);
          List<TBusDept> list = tBusDeptService.getTBusDeptList(tBusDept);
          if (list != null && !list.isEmpty()) {
               return R.failed("部门下有部门，请先删除！");
          }
          tBusDept = new TBusDept();
          tBusDept.setId(id);
          tBusDept.setDeleteFlag(1);

          boolean isSuccess = tBusDeptService.updateById(tBusDept);
          // 更新人员表冗余字段,设置为空值
          if (isSuccess) {
               UpdateEmployeeExtendRedundancyDTO dto = new UpdateEmployeeExtendRedundancyDTO();
               dto.setDepartId(tBusDept.getId());
               dto.setDepartName(null);
               dto.setTreeLogo(null);
               dto.setDepartIdVal(null);
               archivesDaprUtil.updateEmployeeExtendRedundancy(CollUtil.newArrayList(dto));
          }
          return new R<>(isSuccess);
     }

     /**
      * 导入
      * @return R
      */
	 @Operation(summary = "导入", description = "导入")
	 @PostMapping("/importDept")
     public R<List<ErrorMessage>> importDept(@RequestBody List<TBusDept> deptList) {
          if (deptList == null || deptList.isEmpty()) {
               return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
          }

          String error;
          YifuUser user = SecurityUtils.getUser();
		 if (user == null || Common.isEmpty(user.getId())) {
               return R.failed("未获取到登录人信息！");
          }
          String userId = String.valueOf(user.getId());
          String userName = user.getNickname();
          LocalDateTime nows = LocalDateTime.now();
          List<ErrorMessage> errorList = new ArrayList<>();
          int i=1;
          for (TBusDept dept : deptList) {
               i++;
               if (Common.isNotNull(dept.getName())) {
                    boolean flag = this.getDeptByName(null, dept.getName());
                    if (!flag) {
                         this.doSaveInfo(userId, userName, nows, errorList, i, dept);
                    } else {
                         error = "已存在此部门：" + dept.getName();
                         errorList.add(new ErrorMessage(i, error));
                    }
               } else {
                    error = "部门名称不可为空！";
                    errorList.add(new ErrorMessage(i, error));
               }
          }
          return R.ok(errorList);
     }

     /**
      * @param userId
      * @param userName
      * @param nows
      * @param errorList
      * @param i
      * @param dept
      * @Description: 保存信息
      * @Author: hgw
      * @Date: 2021/8/11 16:39
      * @return: void
      **/
     private void doSaveInfo(String userId, String userName, LocalDateTime nows, List<ErrorMessage> errorList, int i
             , TBusDept dept) {
          String error;
          if (dept.getName().length() <= 50) {
               if (dept.getParentName() != null) {
                    List<TBusDept> parentDeptList = tBusDeptService.getDeptByName(null, dept.getParentName());
                    if (parentDeptList != null && !parentDeptList.isEmpty()) {
                         TBusDept parentDept = parentDeptList.get(CommonConstants.ZERO_INT);
                         dept.setPid(parentDept.getId());

                         dept.setCreateTime(nows);
                         dept.setCreateUserId(userId);
                         dept.setCreateUserName(userName);
                         dept.setLevel(parentDept.getLevel() + CommonConstants.ONE_INT);
                         tBusDeptService.save(dept);
                         dept.setTreeLogo(parentDept.getTreeLogo() + CommonConstants.CENTER_SPLIT_LINE_STRING + dept.getId());
                         tBusDeptService.updateById(dept);
                    } else {
                         error = "部门：" + dept.getName() +"，未找到上级部门：" + dept.getParentName();
                         errorList.add(new ErrorMessage(i, error));
                    }
               } else {
                    error = "部门：" + dept.getName() +"，上级部门不可为空！";
                    errorList.add(new ErrorMessage(i, error));
               }
          } else {
               error = "部门名称长度不允许超过50：" + dept.getName();
               errorList.add(new ErrorMessage(i, error));
          }
     }


     /**
      * 根据部门父id或等级查询部门列表
      * @param pid 部门pid
      * @param level 部门等级
      * @return: com.yifu.cloud.v1.common.core.util.R<java.util.List<com.yifu.cloud.v1.hrobusiness.api.entity.system.TBusDept>>
      * @author: wangweiguo
      * @date: 2021/9/7
      * @since hrob2.1
     */
	 @Operation(summary = "根据部门父id或等级查询部门列表", description = "根据部门父id或等级查询部门列表")
		 @GetMapping("/getBusDepartByLevelOrPid")
     public R<List<TBusDept>> getBusDepartByLevelOrPid(
             @Parameter(description = "部门父id选填，如果需要获取指定部门下面所有的部门须填写") @RequestParam(name = "pid", required = false) Integer pid,
             @Parameter(description = "部门等级 1：一级部门 2：二级部门，以此类推") @RequestParam(name = "level") Integer level) {
          return this.tBusDeptService.getBusDepartByLevelOrPid(pid, level);
     }

}
