package com.yeejoin.amos.fas.business.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.google.common.base.Joiner;
import com.yeejoin.amos.fas.business.action.model.RiskSourceRo;
import com.yeejoin.amos.fas.business.dao.mapper.FmeaEquipmentPointMapper;
import com.yeejoin.amos.fas.business.dao.mapper.FmeaMapper;
import com.yeejoin.amos.fas.business.dao.mapper.FmeaPointInputitemMapper;
import com.yeejoin.amos.fas.business.dao.mapper.RiskSourceMapper;
import com.yeejoin.amos.fas.business.dao.repository.IFmeaDao;
import com.yeejoin.amos.fas.business.dao.repository.IRiskFactorDao;
import com.yeejoin.amos.fas.business.dao.repository.IRiskLevelDao;
import com.yeejoin.amos.fas.business.dao.repository.IRiskSourceDao;
import com.yeejoin.amos.fas.business.feign.RemoteSecurityService;
import com.yeejoin.amos.fas.business.param.CommonPageInfoParam;
import com.yeejoin.amos.fas.business.service.intfc.IFmeaService;
import com.yeejoin.amos.fas.core.util.StringUtil;
import com.yeejoin.amos.fas.dao.entity.Fmea;
import com.yeejoin.amos.fas.dao.entity.RiskFactor;
import com.yeejoin.amos.fas.dao.entity.RiskLevel;
import com.yeejoin.amos.fas.dao.entity.RiskSource;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;

@Service("fmeaService")
public class FmeaServiceImpl implements IFmeaService {

    @Autowired
    private IFmeaDao iFmeaDao;

    @Autowired
    private IRiskSourceDao iRiskSourceDao;

    @Autowired
    private FmeaMapper fmeaMapper;

    @Autowired
    RiskSourceMapper riskSourceMapper;


    @Autowired
    IRiskLevelDao iRiskLevelDao;

    @Autowired
    IRiskFactorDao iRiskFactorDao;

    @Autowired
    private RemoteSecurityService remoteSecurityService;

    @Autowired
    private FmeaEquipmentPointMapper fmeaEquipmentPointMapper;

    @Autowired
    private FmeaPointInputitemMapper fmeaPointInputitemMapper;

    @Override
    public void editFmea(HashMap<String, Object> paramMap) {
        List<Fmea> fmeas = (List<Fmea>) paramMap.get("fmeas");
        fmeas.forEach(fmea -> {
            String userId = paramMap.get("user_id") == null ? "0" : paramMap.get("user_id").toString();
            fmea.setCreateBy(userId);
            iFmeaDao.save(fmea);
        });
    }

    @Override
    public void deleteFmea(Long[] fmeaIds) {
        fmeaEquipmentPointMapper.deleteByFmeaIds(fmeaIds);
        fmeaPointInputitemMapper.deleteByFmeaIds(fmeaIds);
        iFmeaDao.deleteById(fmeaIds);
    }

    @Override
    public Page<HashMap<String, Object>> queryFmeaList(CommonPageInfoParam param,String toke,String product,String appKey) {
        long total = fmeaMapper.countPageData(param);
        List<HashMap<String, Object>> content = fmeaMapper.queryFmeaPage(param);
		if(!CollectionUtils.isEmpty(content)) {
            Set<String> userIds = new HashSet<>();
            for (HashMap<String, Object> map : content) {
                userIds.add(String.valueOf(map.get("companyLeaderId")));
                userIds.add(String.valueOf(map.get("departmentLeaderId")));
                userIds.add(String.valueOf(map.get("groupLeaderId")));
                userIds.add(String.valueOf(map.get("personLeaderId")));
                userIds.add(String.valueOf(map.get("identifyUserId")));
            }
            userIds.remove("null");
            userIds.remove(null);
            userIds.remove("");
            if(!CollectionUtils.isEmpty(userIds)){
                List<AgencyUserModel> users = new ArrayList<>();
                if(!CollectionUtils.isEmpty(userIds)){
                    users = remoteSecurityService.listUserByUserIds(toke, product, appKey, Joiner.on(",").join(userIds));
                }
                if (StringUtil.isNotEmpty(users)) {
                    Map<String, String> userMap = users.stream().collect(Collectors.toMap(AgencyUserModel::getUserId,AgencyUserModel::getRealName));
                    for (HashMap<String, Object> map : content) {
                        map.put("companyLeaderName", userMap.get(map.get("companyLeaderId")));
                        map.put("departmentLeaderName", userMap.get(map.get("departmentLeaderId")));
                        map.put("groupLeaderName", userMap.get(map.get("groupLeaderId")));
                        map.put("personLeaderName", userMap.get(map.get("personLeaderId")));
                        map.put("identifyUserName", userMap.get(map.get("identifyUserId")));
                    }
                }
            }

        }
        return new PageImpl<HashMap<String, Object>>(content, param, total);
    }


    @Override
    public int queryControlObjCount(String[] ids) {
        int count1 = iFmeaDao.countAssociatedEquipPointByIds(ids);
        int count2 = iFmeaDao.countAssociatedInputItemByIds(ids);
        if (count1 > 0 || count2 > 0) {
            return count1 + count2;
        }
        return 0;//没有关联对象
    }


    private RiskSourceRo transfer(String bacthNo, RiskSource riskSource, String from, BigDecimal rpni) {
        RiskSourceRo riskSourceRo = new RiskSourceRo();
        riskSourceRo.setBatchNo(bacthNo);
        riskSourceRo.setId(String.valueOf(riskSource.getId()));
        riskSourceRo.setCode(riskSource.getCode());
        riskSourceRo.setFrom(from);
        riskSourceRo.setName(riskSource.getName());
        //riskSourceRo.setNodeState(nodeState);
        //riskSourceRo.setOriginalNodeState(originalNodeState);
        riskSourceRo.setIsRegion(riskSource.getIsRegion());
        riskSourceRo.setRiskFactor(null);
        riskSourceRo.setRpn(riskSource.getRpn());
        riskSourceRo.setRiskState(riskSource.getStatus());

        riskSourceRo.setRpni(rpni);
        Optional<RiskLevel> riskLevel1 = iRiskLevelDao.findById(riskSource.getRiskLevelId());
        RiskLevel riskLevel =null;
        if(riskLevel1.isPresent()){
        	riskLevel=riskLevel1.get();
        }
        if (riskLevel != null) {
            riskSourceRo.setRiskLevel(riskLevel.getLevel());
        }


        List<BigDecimal> RPNiSum = new ArrayList<>();
        List<Fmea> fmeaList = iFmeaDao.findByRiskSourceId(riskSource.getId());
        String riskFactor = "";

        if (!CollectionUtils.isEmpty(fmeaList)) {
            for (Fmea fmea : fmeaList) {
                RPNiSum.add(fmea.getRpni());
                RiskFactor factor =null;
                Optional<RiskFactor> factor1 = iRiskFactorDao.findById(fmea.getRiskFactorsId());
                if(factor1.isPresent()){
                	factor=factor1.get();
                }
                if (factor != null)
                    riskFactor += factor.getName() + "\n";
            }
        }


        //获取所有子节点的rpni值
        List<Map<String, BigDecimal>> rpniList = riskSourceMapper.queryForRiskSourceRpni(riskSource.getId());
        if (!CollectionUtils.isEmpty(rpniList)) {
            for (Map<String, BigDecimal> map : rpniList) {
                RPNiSum.addAll(map.values());
            }
        }

        riskSourceRo.setRiskFactor(riskFactor);
        riskSourceRo.setRPNiSum(RPNiSum);


        //是否是区域节点
        if ("TRUE".equals(riskSource.getIsRegion())) {

            riskSourceRo.setRegionMaxLevel(findRegionMaxLevel(riskSource.getId()));
        }
        return riskSourceRo;
    }

    private Integer findRegionMaxLevel(Long regionRiskSourceId) {
        Integer maxLevel = 0;
        List<RiskSource> anomalyRiskSource = findAnomalyRiskSource(regionRiskSourceId);
        for (RiskSource anomaly : anomalyRiskSource) {
            Optional<RiskLevel> anomalyLevel1 = this.iRiskLevelDao.findById(anomaly.getRiskLevelId());
            RiskLevel anomalyLevel =null;
            if(anomalyLevel1.isPresent()){
            	 anomalyLevel =anomalyLevel1.get();
            }
            if (anomalyLevel != null && anomalyLevel.getLevel() > maxLevel){
                maxLevel = anomalyLevel.getLevel();
            }
        }
        return maxLevel;
    }


    private List<RiskSource> findAnomalyRiskSource(Long riskSourceId) {
        List<RiskSource> returnList = new ArrayList<>();
        List<RiskSource> childs = iRiskSourceDao.findByParentId(riskSourceId);
        if (CollectionUtils.isEmpty(childs)){
            return returnList;
        }
        for (RiskSource child : childs) {
            returnList.add(child);
            returnList.addAll(this.findAnomalyRiskSource(child.getId()));
        }
        return returnList;
    }

}
