package com.testor.ddd.safetyControl.application.service.riskPointManage.impl;

import cn.hutool.core.util.StrUtil;
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.service.SysOrgService;
import com.testor.ddd.safetyControl.application.service.riskOwnerManage.RiskOwnerManageService;
import com.testor.ddd.safetyControl.application.service.riskPointManage.RiskPointManageService;
import com.testor.ddd.safetyControl.application.service.riskPointSource.RiskPointSourceManageService;
import com.testor.ddd.safetyControl.domain.riskPoint.entity.TSafeRiskPointRepo;
import com.testor.ddd.safetyControl.domain.riskPoint.service.RiskPointService;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskOwner.TSafeRiskOwnerDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskOwner.TSafeRiskOwnerDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskPoint.TSafeRiskPointDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskPoint.TSafeRiskPointDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskPointSource.TSafeRiskPointSourceDTO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskOwner.TSafeRiskOwnerVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskPoint.TSafeRiskPointVO;
import com.testor.module.sys.model.vo.SysOrgVo;
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.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class RiskPointManageServiceImpl implements RiskPointManageService {

    @Resource
    private SysOrgService orgService;

    @Resource
    private RiskPointService riskPointService;

    @Resource
    private TSafeRiskPointRepo tSafeRiskPointRepo;

    @Resource
    private RiskOwnerManageService riskOwnerManageService;

    @Resource
    private RiskPointSourceManageService riskPointSourceManageService;

    @Resource
    private SysDictDataService dictDataService;

    @Resource
    private NewSysOrgService newSysOrgService;

    /**
     * 编辑空间
     *
     * @param riskPointDto
     * @return
     */
    @Transactional
    public BaseResponse<TSafeRiskPointDTO> editRiskPoint(TSafeRiskPointDTO riskPointDto) throws RuntimeException {
        BaseResponse<TSafeRiskPointDTO> baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        riskPointDto.setOrgId(curUserOrgId);

        List<TSafeRiskOwnerDTO> riskOwnerDTOList = riskPointDto.getRiskOwnerList();
       if(riskOwnerDTOList == null || riskOwnerDTOList.size() == 0) {
           baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
           baseResponse.setMsg("管控部门与责任人不能位空");
           return baseResponse;
       }

        List<TSafeRiskPointSourceDTO> pointSourceList = riskPointDto.getPointSourceList();
        if(pointSourceList == null || pointSourceList.size() == 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("关联危险源不能位空");
            return baseResponse;
        }

        // 处理区域公司 、 基层单位
        String orgStrs = orgService.getById(curUserOrgId).getParentIds()+","+curUserOrgId;
        if(!StrUtil.isBlank(orgStrs)) {
            String[] orgArr = orgStrs.split(",");
            if(orgArr.length == 3) {
                riskPointDto.setRegionOrgId(orgArr[2]);
            }
            if(orgArr.length > 3) {
                riskPointDto.setRegionOrgId(orgArr[2]);
                riskPointDto.setBasicOrgId(orgArr[orgArr.length-1]);
            }
        }

        // 组装 组装机构全路径
        String departmentId = riskPointDto.getDepartmentId();
        String orgAllPath = orgStrs + ","+departmentId;
        riskPointDto.setOrgAllPath(orgAllPath);
        // 组装 组装机构全路径
//        String departmentId = riskPointDto.getDepartmentId();
//        SysOrg org = orgService.getById(departmentId);
//        String orgAllPath = org.getParentIds()+","+departmentId;
//        riskPointDto.setOrgAllPath(orgAllPath);

        baseResponse = riskPointService.editRiskPoint(curUser.getUserId(), curUserOrgId, riskPointDto);
        if(baseResponse.getCode() != 200) {
            return baseResponse;
        }

        String pointId = baseResponse.getData().getId();
        riskOwnerManageService.editRiskOwner(2, pointId, riskOwnerDTOList);

        boolean result = riskPointSourceManageService.saveBatch(curUserOrgId, pointId, pointSourceList);
        if(!result) {
            throw new RuntimeException("关联的危险源中存在已被其他风险点关联的危险源，关联危险源保存失败");
        }
        return baseResponse;
    }

    public BaseResponseList<TSafeRiskPointVO> listByPage(TSafeRiskPointDTOParam param){

        if(StrUtil.isBlank(param.getOrgId())) {
            UserInfo curUser = ContextUtils.getLoginUser();
            String curUserOrgId = curUser.getOrgId();
            param.setOrgId(curUserOrgId);
        }

        BaseResponseList<TSafeRiskPointVO> responseList = riskPointService.listByPage(param);
        List<TSafeRiskPointVO> riskPointVOList = responseList.getData();
        if(riskPointVOList == null || riskPointVOList.size() == 0) {
            return responseList;
        }

        List<TSafeRiskPointVO> finalRiskPointVOList = riskPointVOList.stream().map(vo -> generateDictData(vo)).collect(Collectors.toList());
        responseList.setData(finalRiskPointVOList);
        return responseList;
    }

    public TSafeRiskPointDTO findById(String id){
        return tSafeRiskPointRepo.findById(id);
    }

    public TSafeRiskPointVO findDetailById(String id){
        TSafeRiskPointVO riskPointVO = tSafeRiskPointRepo.findDetailById(id);
        if(riskPointVO == null) {
            return null;
        }
        riskPointVO = generateDictData(riskPointVO);
        riskPointVO = generateRiskOwner(riskPointVO);
        return riskPointVO;
    }

    @Transactional
    public BaseResponse deleteById(String id) throws BusinessException {
        BaseResponse baseResponse = new BaseResponse<>();
        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        TSafeRiskPointDTO oldRiskPointDto = tSafeRiskPointRepo.findById(id);
        if(!curUserOrgId.equals(oldRiskPointDto.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UNAUTHORIZED.code());
            baseResponse.setMsg("无权限操作");
            return baseResponse;
        }

        tSafeRiskPointRepo.deleteById(id);
        riskOwnerManageService.deleteByRiskBizId(id);
        return baseResponse;
    }

    // 组织 实体中的 数据字典
    public TSafeRiskPointVO generateDictData(TSafeRiskPointVO riskPointVO) {
        if(StrUtil.isBlank(riskPointVO.getId())) {
            return null;
        }
        if(StringHelper.isNotBlank(riskPointVO.getOrgId())){
            SysOrgVo sysOrgVo = newSysOrgService.lookOrg(riskPointVO.getOrgId());
            riskPointVO.setOrgFullName(sysOrgVo.getPath());
        }
        // 危险类型
        SysDictData riskType = dictDataService.getById(riskPointVO.getTypeId());
        if(riskType != null) {
            riskPointVO.setTypeName(riskType.getDictValue());
        }
        // 固有风险
        SysDictData inherentLevel = dictDataService.getById(riskPointVO.getInherentLevelId());
        if(inherentLevel != null) {
            riskPointVO.setInherentLevelName(inherentLevel.getDictValue());
        }
        //现实风险
        SysDictData realType = dictDataService.getById(riskPointVO.getRealLevelId());
        if(realType != null) {
            riskPointVO.setRealLevelName(realType.getDictValue());
        }

        // 管控层级
        SysDictData controlLevel = dictDataService.getById(riskPointVO.getControlLevelId());
        if(controlLevel != null) {
            riskPointVO.setControlLevelName(controlLevel.getDictValue());
        }

        return riskPointVO;
    }

    // 组织 实体中的 风险部门负责人
    public TSafeRiskPointVO generateRiskOwner(TSafeRiskPointVO riskPointVO) {
        if(StrUtil.isBlank(riskPointVO.getId())) {
            return null;
        }

        // 危险类型
        TSafeRiskOwnerDTOParam param = new TSafeRiskOwnerDTOParam();
        param.setStatus(BizConstants.STATUS_ENABLE);
        param.setRiskId(riskPointVO.getId());
        List<TSafeRiskOwnerVO> riskOwnerVOList= riskOwnerManageService.listPage(param).getData();
        riskPointVO.setRiskOwnerList(riskOwnerVOList);
        return riskPointVO;
    }

    /**
     *
     * @param type 1-设备; 2-空间(作业区域)；  3-空间(车间场所)；
     * @param bizId type=1-设备id; 2-空间(作业区域)id；  3-空间(车间场所)id；
     * @return
     */
    @Transactional
    public boolean deleteBySpaceOrEquipment(Integer type, String bizId){
        return tSafeRiskPointRepo.deleteBySpaceOrEquipment(type, bizId);
    }

    public TSafeRiskPointDTO findBySource(String sourceId){
        return tSafeRiskPointRepo.findBySource(sourceId);
    }

    /**
     * 检测 名称 是否都唯一
     * @return true - 唯一； false - 不唯一
     */
    public boolean checkUniqueness(String orgId, String pointId, String name) {
        return riskPointService.checkUniqueness(orgId, pointId, name);
    }

    public TSafeRiskPointDTO save(TSafeRiskPointDTO pointDTO){
        return tSafeRiskPointRepo.insert(pointDTO);
    }
}
