package com.testor.module.sys.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.dict.data.model.domain.SysDictData;
import com.testor.biz.sys.dict.data.service.SysDictDataService;
import com.testor.biz.sys.org.OrgEnumCode;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.model.dto.DeptAndPost;
import com.testor.biz.sys.org.model.dto.SysOrgCreateAndUpdateRequest;
import com.testor.biz.sys.org.model.dto.SysOrgParam;
import com.testor.biz.sys.org.service.OrgExcelImport;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.biz.sys.post.model.domain.TSysPost;
import com.testor.biz.sys.post.model.dto.TSysPostParam;
import com.testor.biz.sys.post.service.TSysPostService;
import com.testor.biz.sys.role.model.domain.SysRole;
import com.testor.biz.sys.role.service.SysRoleService;
import com.testor.biz.sys.user.UserEnumCode;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.biz.sys.user.service.SysUserService;
import com.testor.biz.sys.userRole.model.domain.SysUserRole;
import com.testor.biz.sys.userRole.service.SysUserRoleService;
import com.testor.common.constant.NewOrgEnumCode;
import com.testor.common.util.BeanConverUtil;
import com.testor.module.accident.model.resp.ReportUnitResp;
import com.testor.module.contractor.ledger.model.domain.TContractorInfo;
import com.testor.module.contractor.ledger.model.domain.TContractorLedger;
import com.testor.module.contractor.ledger.service.TContractorInfoService;
import com.testor.module.contractor.ledger.service.TContractorLedgerService;
import com.testor.module.sys.model.domian.NewSysOrg;
import com.testor.module.sys.model.dto.NewDeptAndPost;
import com.testor.module.sys.model.dto.NewSysOrgCreateAndUpdateRequest;
import com.testor.module.sys.model.vo.SysOrgAndDeptVo;
import com.testor.module.sys.model.vo.SysOrgVo;
import com.testor.module.sys.service.NewSysDictDataService;
import com.testor.module.sys.service.NewSysOrgService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.models.exceptions.ApiException;
import com.tongtech.tfw.backend.common.models.response.ResponseInfo;
import com.tongtech.tfw.backend.common.models.supers.SuperController;
import com.tongtech.tfw.backend.common.models.supers.SuperModel;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import liquibase.pro.packaged.S;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author rsq
 * @program zlmy_boot
 * @return
 **/
@RestController
@Api(
        value = "SysOrg",
        tags = {"SysOrg 外部组织机构"}
)
@RequestMapping({"/new/org"})
public class NewSysOrgController extends SuperController {

    private static final Logger log = LoggerFactory.getLogger(com.testor.biz.sys.org.controller.SysOrgController.class);
    @Autowired
    private NewSysOrgService sysOrgService;
    @Autowired
    private OrgExcelImport orgExcelImport;
    @Autowired
    private TSysPostService tSysPostService;
    @Autowired
    private SysDictDataService sysDictDataService;
    @Autowired
    private NewSysDictDataService newSysDictDataService;
    @Autowired
    private TContractorLedgerService tContractorLedgerService;
    @Autowired
    private TContractorInfoService tContractorInfoService;

    @ApiOperation(
            value = "【根据机构名称或Id获取其直接子部门】",
            notes = "根据机构名称或Id获取其直接子部门"
    )
    @GetMapping({"/sub_list"})
    public BaseResponse<BaseResponseList<NewDeptAndPost>> childrenEntity(SysOrgParam param) {
        BaseResponse<BaseResponseList<NewDeptAndPost>> baseResponse = new BaseResponse();
        Long page = StringHelper.isEmpty(param.getPage()) ? BizConstants.PAGE : Long.valueOf(param.getPage());
        Long limit = StringHelper.isEmpty(param.getLimit()) ? BizConstants.LIMIT : Long.valueOf(param.getLimit());
        Page<NewSysOrg> resultPage = new Page(page, limit);
        QueryWrapper<NewSysOrg> queryWrapper = this.orgIdsEntity(param);
        Page<NewSysOrg> resultList = (Page) this.sysOrgService.page(resultPage, queryWrapper);
        BaseResponseList<NewDeptAndPost> baseResponseList = new BaseResponseList();
        List<NewSysOrg> records = resultList.getRecords();
        List<NewDeptAndPost> collect = (List) records.stream().map((bean) -> {
            return (NewDeptAndPost) bean.beanToBean(NewDeptAndPost.class);
        }).collect(Collectors.toList());
        List<NewDeptAndPost> deptAndPosts = new ArrayList();

        for (NewDeptAndPost deptAndPost : collect) {
            String nature = deptAndPost.getNature();
            //如果企业性质不为空去查字典
            if (StringUtils.isNotBlank(nature)) {
                //获取层级字典
                SysDictData sysDictData = newSysDictDataService.getDictTypeDetail(null, "NATURE", deptAndPost.getNature());
                if (sysDictData != null) {
                    deptAndPost.setNatureName(sysDictData.getDictValue());
                }
            }
            //为空展示默认值
            else {
                BigDecimal treeLevel = deptAndPost.getTreeLevel();
                String natureName = "";
                if (treeLevel.compareTo(BigDecimal.ONE) == 0) {
                    natureName = "总部";
                } else if (treeLevel.compareTo(BigDecimal.valueOf(2)) == 0) {
                    natureName = "大区/平台";
                } else if (treeLevel.compareTo(BigDecimal.valueOf(3)) == 0) {
                    natureName = "经营部";
                } else if (treeLevel.compareTo(BigDecimal.valueOf(4)) >= 0 && treeLevel.compareTo(BigDecimal.valueOf(9)) <= 0) {
                    natureName = "基层企业";
                }
                deptAndPost.setNatureName(natureName);
            }
            deptAndPosts.add(deptAndPost);
        }

        baseResponseList.setData(deptAndPosts);
        baseResponseList.setTotal(this.sysOrgService.count(queryWrapper) + "");
        baseResponse.setData(baseResponseList);
        return baseResponse;
    }

    public QueryWrapper<NewSysOrg> orgIdsEntity(SysOrgParam param) {
        QueryWrapper<NewSysOrg> queryWrapper = new QueryWrapper();
        if (!StringHelper.isEmpty(param.getOrgId())) {
            ((QueryWrapper) queryWrapper.and((i) -> {
                QueryWrapper var10000 = (QueryWrapper) ((QueryWrapper) ((QueryWrapper) i.eq("org_id", param.getOrgId())).or()).like("parent_id", param.getOrgId());
            })).eq("is_dept", "0");
        }

        if (!StringHelper.isEmpty(param.getStatus())) {
            queryWrapper.eq("status", param.getStatus());
        } else {
            queryWrapper.ne("status", "1");
        }

        if (StringHelper.isEmpty(param.getOrgName()) && StringHelper.isEmpty(param.getLeader()) && StringHelper.isEmpty(param.getOrgCode()) && StringHelper.isEmpty(param.getPhoneNo())) {
            if (!StringHelper.isEmpty(param.getKeyword())) {
                queryWrapper.and((i) -> {
                    QueryWrapper var10000 = (QueryWrapper) ((QueryWrapper) ((QueryWrapper) i.like("org_name", param.getKeyword())).or()).like("leader", param.getKeyword());
                });
            }
        } else {
            if (!StringHelper.isEmpty(param.getOrgName())) {
                queryWrapper.like("org_name", param.getOrgName());
            }

            if (!StringHelper.isEmpty(param.getLeader())) {
                queryWrapper.like("leader", param.getLeader());
            }

            if (!StringHelper.isEmpty(param.getOrgCode())) {
                queryWrapper.like("org_code", param.getOrgCode());
            }

            if (!StringHelper.isEmpty(param.getPhoneNo())) {
                queryWrapper.like("phone_no", param.getPhoneNo());
            }
        }

        if (!StringHelper.isEmpty(param.getOrderBy())) {
            if (!StringHelper.isEmpty(param.getOrderType()) && "asc".equals(param.getOrderType())) {
                queryWrapper.orderByAsc(param.getOrderBy());
            } else {
                queryWrapper.orderByDesc(param.getOrderBy());
            }
        } else {
            queryWrapper.orderByAsc(new String[]{"parent_ids", "tree_sort"});
        }
        if (param.getTreeLevel() != null) {
            queryWrapper.eq(SysOrg.TREE_LEVEL, param.getTreeLevel());
        }
        return queryWrapper;
    }

    @ApiOperation(
            value = "根据机构ID查询机构",
            notes = "根据机构ID查询机构"
    )
    @GetMapping({"/get"})
    public BaseResponse<Map<String, Object>> getById(String orgId) {
        BaseResponse<Map<String, Object>> baseResponse = new BaseResponse();
        if (StringHelper.isEmpty(orgId)) {
            throw new ApiException(OrgEnumCode.REQUIRED_ITEMS_MISSING.transform());
        } else {
            NewSysOrg sysOrg = (NewSysOrg)this.sysOrgService.getById(orgId);
            if (ObjectHelper.isEmpty(sysOrg)) {
                throw new ApiException(OrgEnumCode.ORG_ID_NOT_EXISTENT.transform());
            } else {
                Map<String, Object> data = BeanHelper.beanToMap(sysOrg);
                if (!StringHelper.isEmpty(sysOrg.getParentId()) && !"0".equals(sysOrg.getParentId())) {
                    NewSysOrg parentOrg = (NewSysOrg)this.sysOrgService.getById(sysOrg.getParentId());
                    data.put("parentOrgName", parentOrg.getOrgName());
                } else {
                    data.put("parentOrgName", "");
                }

                baseResponse.setData(data);
                return baseResponse;
            }
        }
    }

    @ApiOperation(
            value = "【返回当前机构下的部门信息】",
            notes = "获取机构部门信息"
    )
    @GetMapping({"/returnDeptAndParties"})
    public BaseResponse<List<SysOrgAndDeptVo>> returnDeptsss(String orgId) {
        BaseResponse<List<SysOrgAndDeptVo>> baseResponse = new BaseResponse();
        if (StringHelper.isBlank(orgId)) {
            orgId = ContextUtils.getLoginUser().getOrgId();
        }
        List<SysOrgAndDeptVo> sysOrgAndDeptVos = new ArrayList<>();
        NewSysOrg newSysOrg = sysOrgService.getById(orgId);
        newSysOrg.setOrgType("0");
        SysOrgAndDeptVo sysOrgAndDeptVo = BeanConverUtil.conver(newSysOrg, SysOrgAndDeptVo.class);
        List<SysOrg> depts = this.sysOrgService.list((Wrapper)((QueryWrapper)((QueryWrapper)(new QueryWrapper()).eq("parent_id", orgId)).eq("is_dept", "1")).ne("status", "1"));
        if(depts != null){
            List<NewSysOrg> deptList = BeanConverUtil.converList(depts, NewSysOrg.class).stream().map(sysOrg -> {
                sysOrg.setOrgType("0");
                return sysOrg;
            }).collect(Collectors.toList());
            sysOrgAndDeptVo.setDeptList(deptList);
        }
        sysOrgAndDeptVos.add(sysOrgAndDeptVo);

        SysOrgAndDeptVo relatedParties = new SysOrgAndDeptVo();
        relatedParties.setOrgType("1");
        relatedParties.setOrgName("相关方作业");
        // 获取当前组织的所有承包商台账信息
        List<Object> infoIds = tContractorLedgerService.listObjs(new QueryWrapper<TContractorLedger>().select(TContractorLedger.INFO_ID).eq(TContractorLedger.ORG_ID, orgId).groupBy(TContractorLedger.INFO_ID));
        List<NewSysOrg> contractors = new ArrayList<>();
        for (Object infoId : infoIds) {
            TContractorInfo tContractorInfo = tContractorInfoService.getById(infoId.toString());
            NewSysOrg sysOrg = new NewSysOrg();
            sysOrg.setOrgName(tContractorInfo.getName());
            sysOrg.setOrgType("1");
            sysOrg.setOrgId(tContractorInfo.getId());
            contractors.add(sysOrg);
        }
        relatedParties.setDeptList(contractors);
        sysOrgAndDeptVos.add(relatedParties);
        baseResponse.setData(sysOrgAndDeptVos);
        return baseResponse;
    }

    @ApiOperation(
            value = "【新增机构信息及部门信息】",
            notes = "新增机构信息及部门信息， 如果新增部门 isDept传 1 新增机构传 0"
    )
    @PostMapping({"/add"})
    public BaseResponse<SysOrg> addEntity(@RequestBody @Valid NewSysOrgCreateAndUpdateRequest addRequest) throws Exception {
        BaseResponse<SysOrg> baseResponse = new BaseResponse();
        if (ObjectHelper.isEmpty(addRequest)) {
            throw new ApiException(OrgEnumCode.ORG_PARAM_IS_NULL.transform());
        } else {
            List<SysOrg> sysOrgList = this.sysOrgService.list((Wrapper)((QueryWrapper)(new QueryWrapper()).eq("org_code", addRequest.getOrgCode())).ne("status", "1"));
            if (!ObjectHelper.isEmpty(sysOrgList)) {
                throw new ApiException(OrgEnumCode.ORG_CODE_ALREADY_EXISTS.transform());
            } else {
                String parentId = addRequest.getParentId();
                if (!StringHelper.isEmpty(parentId) && !"0".equals(parentId)) {
                    NewSysOrg parentOrg = (NewSysOrg)this.sysOrgService.getById(parentId);
                    addRequest.setParentIds(parentOrg.getParentIds() + "," + parentOrg.getOrgId());
                } else {
                    addRequest.setParentId("0");
                    addRequest.setParentIds("0");
                }

                List<SysOrg> sysOrgs = this.sysOrgService.list((Wrapper)((QueryWrapper)((QueryWrapper)(new QueryWrapper()).eq("org_name", addRequest.getOrgName())).eq("parent_id", addRequest.getParentId())).ne("status", "1"));
                if (!ObjectHelper.isEmpty(sysOrgs)) {
                    throw new ApiException(OrgEnumCode.ORG_NAME_ALREADY_EXISTS.transform());
                } else {
                    NewSysOrg data = (NewSysOrg)BeanHelper.beanToBean(addRequest, NewSysOrg.class);
                    String bit = IdHelper.getId32bit();
                    data.setOrgId(bit);
                    boolean flag = this.sysOrgService.save(data);
                    if (flag) {
                        if ("0".equals(addRequest.getIsDept())) {
                            NewSysOrg sysOrg = new NewSysOrg();
                            String parent = addRequest.getParentId();
                            if (!StringHelper.isEmpty(parent) && !"0".equals(parent)) {
                                NewSysOrg parentOrg = (NewSysOrg)this.sysOrgService.getById(parent);
                                sysOrg.setParentId(bit);
                                sysOrg.setParentIds(parentOrg.getParentIds() + "," + parentOrg.getOrgId() + "," + bit);
                            } else {
                                sysOrg.setParentId("0");
                                sysOrg.setParentIds("0");
                            }

                            String dept = IdHelper.getId32bit();
                            sysOrg.setOrgId(dept);
                            sysOrg.setOrgName("安全环保部");
                            sysOrg.setIsDept("1");
                            this.sysOrgService.save(sysOrg);
                            TSysPostParam tSysPostParam = new TSysPostParam();
                            tSysPostParam.setDeptId(dept);
                            List<TSysPost> posts = new ArrayList();
                            TSysPost tSysPost = new TSysPost();
                            tSysPost.setPostName("安全生产岗");
                            posts.add(tSysPost);
                            tSysPostParam.setTSysPosts(posts);
                            this.tSysPostService.addEntity(tSysPostParam);
                        }

                        baseResponse.setData(data);
                    }

                    return baseResponse;
                }
            }
        }
    }


    @ApiOperation(
            value = "修改机构信息",
            notes = "修改机构信息 Edit Org Info"
    )
    @Transactional(
            rollbackFor = {Exception.class}
    )
    @PutMapping({"/update"})
    public BaseResponse<NewSysOrg> updateEntity(@RequestBody @Valid NewSysOrgCreateAndUpdateRequest updateRequest) {
        BaseResponse<NewSysOrg> baseResponse = new BaseResponse();
        if (ObjectHelper.isEmpty(updateRequest)) {
            throw new ApiException(OrgEnumCode.ORG_PARAM_IS_NULL.transform());
        } else if (StringHelper.isEmpty(updateRequest.getOrgId())) {
            throw new ApiException(OrgEnumCode.ORG_ID_NOT_EXISTENT.transform());
        } else {
            NewSysOrg oldSysOrg = this.sysOrgService.getById(updateRequest.getOrgId());
            if (ObjectHelper.isEmpty(oldSysOrg)) {
                throw new ApiException(OrgEnumCode.ORG_ID_NOT_EXISTENT.transform());
            } else {
                NewSysOrg modifyOrg = BeanHelper.beanToBean(updateRequest, NewSysOrg.class);
                if (!StringHelper.isEmpty(updateRequest.getOrgCode()) && !oldSysOrg.getOrgCode().equals(updateRequest.getOrgCode())) {
                    List<NewSysOrg> sysOrgList = this.sysOrgService.list((Wrapper)((QueryWrapper)((QueryWrapper)(new QueryWrapper()).eq("org_code", updateRequest.getOrgCode())).ne("org_id", updateRequest.getOrgId())).ne("status", "1"));
                    if (!ObjectHelper.isEmpty(sysOrgList)) {
                        throw new ApiException(OrgEnumCode.ORG_CODE_ALREADY_EXISTS.transform());
                    }
                }

                boolean isStatusChanged = false;
                if (!modifyOrg.getStatus().equals(oldSysOrg.getStatus())) {
                    isStatusChanged = true;
                }

                boolean isParentOrgChanged = false;
                String newParentId = modifyOrg.getParentId();
                if (StringHelper.isEmpty(newParentId)) {
                    newParentId = "0";
                }

                String oldParentIds = oldSysOrg.getParentIds();
                String newParentIds = "0";
                //如果旧父id不等于新父id
                if (!oldSysOrg.getParentId().equals(newParentId)) {
                    isParentOrgChanged = true;
                    //如果新的父id等于0 即（总部性质）
                    if ("0".equals(newParentId)) {
                        modifyOrg.setParentId("0");
                        modifyOrg.setParentIds("0");
                    }
                    //如果不是顶级，根据新的父id获取newParentIds
                    else {
                        //查出新的上级机构
                        NewSysOrg tmp = this.sysOrgService.getById(newParentId);
                        if (ObjectHelper.isEmpty(tmp)) {
                            throw new ApiException(OrgEnumCode.ORG_ID_NOT_EXISTENT.transform());
                        }

                        newParentIds = tmp.getParentIds() + "," + tmp.getOrgId();
                        String[] split = newParentIds.split(",");
                        int level = split.length;
                        //如果层级大于九层
                        if (level > 9) {
                            throw new ApiException(NewOrgEnumCode.ORG_LEVEL_NOT_GT_NINE.transform());
                        }

                        modifyOrg.setTreeLevel(BigDecimal.valueOf(level));
                        modifyOrg.setParentIds(newParentIds);


                    }
                }
                //如果状态已经更改或父级已更改，修改所有子机构
                if (isStatusChanged || isParentOrgChanged) {
                    List<NewSysOrg> childrenOrgList = this.sysOrgService.getChildrenById(modifyOrg.getOrgId());
                    if (!ObjectHelper.isEmpty(childrenOrgList)) {
                        if (isParentOrgChanged) {
                            String finalNewParentIds = newParentIds;
                            childrenOrgList = (List)childrenOrgList.stream().map((org) -> {
                                return org.setParentIds(org.getParentIds().replaceAll(oldParentIds, finalNewParentIds));
                            }).collect(Collectors.toList());
                        }

                        childrenOrgList = (List)childrenOrgList.stream().peek((org) -> {
                            org.setStatus(updateRequest.getStatus());
                        }).collect(Collectors.toList());
                        this.sysOrgService.updateBatchById(childrenOrgList);
                    }
                }

                boolean flag = this.sysOrgService.updateById(modifyOrg);
                if (flag) {
                    baseResponse.setData(modifyOrg);
                }

                return baseResponse;
            }
        }
    }

    @ApiOperation(
            value = "【根据父级id获取子集数据】",
            notes = "根据父级id获取子集数据"
    )
    @GetMapping({"/getOrgByParentId"})
    public BaseResponse<List<NewSysOrg>> getOrgListByParentId(@RequestParam String parentId) {
        BaseResponse<List<NewSysOrg>> baseResponse = new BaseResponse();
        baseResponse.setData(this.sysOrgService.getOrgListByParentId(parentId));
        return baseResponse;
    }

    @ApiOperation(
            value = "获取机构信息列表 SELF+SUB",
            notes = "根据机构ID获取其子机构"
    )
    @GetMapping({"/children"})
    public BaseResponse<List<NewSysOrg>> childrenEntity(String orgId) {
        BaseResponse<List<NewSysOrg>> baseResponse = new BaseResponse();
        baseResponse.setData(this.sysOrgService.getChildrenById(orgId));
        return baseResponse;
    }

    @ApiOperation(
            value = "【根据当前登录用户获取机构信息】",
            notes = ""
    )
    @GetMapping({"/getCurrentOrg"})
    public BaseResponse<NewSysOrg> getCurrentOrg() {
        BaseResponse<NewSysOrg> sysOrgBaseResponse = new BaseResponse();
        String orgId = ContextUtils.getLoginUser().getOrgId();
        NewSysOrg one = this.sysOrgService.getOne((Wrapper)((QueryWrapper)(new QueryWrapper()).eq("org_id", orgId)).ne("status", "1"));
        sysOrgBaseResponse.setData(one);
        return sysOrgBaseResponse;
    }

    @ApiModelProperty(value = "根据机构id获取机构路径")
    @GetMapping(value = "/lookOrg")
    public BaseResponse<SysOrgVo> lookOrg(String orgId) throws Exception {
        BaseResponse<SysOrgVo> baseResponse = new BaseResponse<>();
        baseResponse.setData(sysOrgService.lookOrg(orgId));
        return baseResponse;
    }

}
