package com.ruoyi.web.controller.drill;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.DeletedEnum;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.drill.domain.DrillOrganizationalStructure;
import com.ruoyi.drill.domain.DrillOrganizationalStructurePersonnel;
import com.ruoyi.drill.dto.DrillOrganizationalStructureDto;
import com.ruoyi.drill.dto.DrillOrganizationalStructureTreeDto;
import com.ruoyi.drill.service.IDrillOrganizationalStructurePersonnelService;
import com.ruoyi.drill.service.IDrillOrganizationalStructureService;
import com.ruoyi.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * DrillOrganizationalStructureController
 *
 * @Auther: mtx
 * @Date: 2023/09/07 17:18
 */
@Api(tags = "演习组织架构")
@RestController
@RequestMapping("/drill/organizational")
public class DrillOrganizationalStructureController extends BaseController {

    @Resource
    private IDrillOrganizationalStructureService drillOrganizationalStructureService;
    @Resource
    private IDrillOrganizationalStructurePersonnelService drillOrganizationalStructurePersonnelService;
    @Resource
    private ISysUserService userService;

    /**
     * 编辑应急岗位
     */
    //TODO 20230920PreAuthorize("@("@ss.hasPermi('drill:organizational:add')")
    @Log(title = "新增应急岗位", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation("新增应急岗位")
    public AjaxResult add(@Validated @RequestBody DrillOrganizationalStructureDto drillOrganizationalStructure) {
        return drillOrganizationalStructureService.saveAndUpdate(drillOrganizationalStructure);
    }

    //TODO 20230920PreAuthorize("@("@ss.hasPermi('drill:organizational:edit')")
    @Log(title = "编辑应急岗位", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation("编辑应急岗位")
    public AjaxResult edit(@Validated @RequestBody DrillOrganizationalStructureDto drillOrganizationalStructure) {
        return drillOrganizationalStructureService.saveAndUpdate(drillOrganizationalStructure);
    }

    /**
     * 删除应急岗位
     */
    //TODO 20230920PreAuthorize("@("@ss.hasPermi('drill:organizational:remove')")
    @Log(title = "删除应急岗位", businessType = BusinessType.DELETE)
    @DeleteMapping("/remove")
    @ApiOperation("删除应急岗位")
    public AjaxResult remove(String id) {
        return drillOrganizationalStructureService.removeOrganizationalStructure(id);
    }

    /**
     * 树形结构
     *
     * @return
     */
    //TODO 20230920PreAuthorize("@("@ss.hasPermi('drill:organizational:list')")
    @GetMapping("/getTree")
    @ApiOperation("树形结构")
    public AjaxResult getTree(@RequestParam String contingentId) {
        LambdaQueryWrapper<DrillOrganizationalStructure> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(DrillOrganizationalStructure::getContingentId, contingentId);
        wrapper.eq(DrillOrganizationalStructure::getIsDel, DeletedEnum.VALID.getValue());
        wrapper.orderByAsc(DrillOrganizationalStructure::getParentId);
        wrapper.orderByAsc(DrillOrganizationalStructure::getOrderNum);
        List<DrillOrganizationalStructure> list = drillOrganizationalStructureService.list(wrapper);

        List<DrillOrganizationalStructureTreeDto> result = new ArrayList<>();
        for (DrillOrganizationalStructure organizationalStructure : list) {
            DrillOrganizationalStructureTreeDto dto = new DrillOrganizationalStructureTreeDto();
            BeanUtils.copyProperties(organizationalStructure, dto);
            String id = dto.getId();
            List<DrillOrganizationalStructurePersonnel> personnels = drillOrganizationalStructurePersonnelService.list(
                    Wrappers.<DrillOrganizationalStructurePersonnel>lambdaQuery()
                            .eq(DrillOrganizationalStructurePersonnel::getDrillOrganizationalStructureId, id));

            if (CollectionUtils.isNotEmpty(personnels)) {
                List<Long> ids = personnels.stream()
                        .map(DrillOrganizationalStructurePersonnel::getUserId)
                        .collect(Collectors.toList());
                List<String> li = new ArrayList<>();
                for (Long aLong : ids) {
                    String name = getSysUserNameById(aLong);
                    li.add(name);
                }
                String join = StringUtils.join(li, ",");
                dto.setPersons(join);
                dto.setPersonList(ids);
            }
            result.add(dto);
        }
        List<DrillOrganizationalStructureTreeDto> node = getTree("0", result);
        return success(node);
    }

    private String getSysUserNameById(Long id) {
        SysUser sysUser = getSysUserById(id);
        return Objects.nonNull(sysUser) ? sysUser.getNickName() : "";
    }

    private SysUser getSysUserById(Long id) {
        return userService.selectUserById(id);
    }

    /**
     * stream 方法转换树形结构方法的优化
     *
     * @param parentId 父级id
     * @param treeList 想要树形结构的list
     * @return 树形结构
     */
    public static List<DrillOrganizationalStructureTreeDto> getTree(String parentId, List<DrillOrganizationalStructureTreeDto> treeList) {
        return treeList.stream()
                // 筛选父节点
                .filter(t -> t.getParentId().equals(parentId))
                // 递归设置子节点
                .peek(item -> item.setChildren(getTree(item.getId(), treeList)))
                .collect(Collectors.toList());
    }

}
