package com.aucma.dms.service.impl;

//import com.hw.common.core.exception.ServiceException;
//import com.hw.common.core.utils.DateUtils;
//import com.hw.common.security.utils.SecurityUtils;
//import com.aucma.dms.domain.DmsBaseShutReason;
//import com.aucma.dms.mapper.DmsBaseShutReasonMapper;
//import com.aucma.dms.service.IDmsBaseShutReasonService;
//import com.hw.system.api.model.LoginUser;

import com.aucma.common.core.domain.model.LoginUser;
import com.aucma.common.exception.ServiceException;
import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.SecurityUtils;
import com.aucma.dms.domain.DmsBaseShutReason;
import com.aucma.dms.domain.DmsBaseShutType;
import com.aucma.dms.domain.vo.DmsShutReasonRecommendVo;
import com.aucma.dms.domain.vo.DmsShutReasonTreeVo;
import com.aucma.dms.mapper.DmsBaseShutReasonMapper;
import com.aucma.dms.service.IDmsBaseShutReasonService;
import com.aucma.dms.service.IDmsBaseShutTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 停机原因信息Service业务层处理
 *
 * @author Open Platform
 * @date 2024-01-12
 */
@Service
public class DmsBaseShutReasonServiceImpl implements IDmsBaseShutReasonService
{
    @Autowired
    private DmsBaseShutReasonMapper dmsBaseShutReasonMapper;

    @Autowired
    private IDmsBaseShutTypeService dmsBaseShutTypeService;

    /**
     * 查询停机原因信息
     *
     * @param shutReasonId 停机原因信息主键
     * @return 停机原因信息
     */
    @Override
    public DmsBaseShutReason selectDmsBaseShutReasonByShutReasonId(Long shutReasonId)
    {
        return dmsBaseShutReasonMapper.selectDmsBaseShutReasonByShutReasonId(shutReasonId);
    }

    /**
     * 查询停机原因信息列表
     *
     * @param dmsBaseShutReason 停机原因信息
     * @return 停机原因信息
     */
    @Override
    public List<DmsBaseShutReason> selectDmsBaseShutReasonList(DmsBaseShutReason dmsBaseShutReason)
    {
        return dmsBaseShutReasonMapper.selectDmsBaseShutReasonList(dmsBaseShutReason);
    }

    /**
     * 查询停机原因树
     *
     * @param deviceId 设备ID
     * @return 停机原因树
     */
    @Override
    public List<DmsShutReasonTreeVo> selectShutReasonTree(Long deviceId)
    {
        DmsBaseShutType typeQuery = new DmsBaseShutType();
        typeQuery.setIsFlag("1");
        List<DmsBaseShutType> typeList = dmsBaseShutTypeService.selectDmsBaseShutTypeList(typeQuery);
        List<DmsBaseShutReason> reasonList = dmsBaseShutReasonMapper.selectAvailableShutReasonList(deviceId);
        if (CollectionUtils.isEmpty(typeList) || CollectionUtils.isEmpty(reasonList))
        {
            return Collections.emptyList();
        }

        Map<Long, List<DmsBaseShutReason>> reasonMap = reasonList.stream()
                .collect(Collectors.groupingBy(DmsBaseShutReason::getShutTypeId, LinkedHashMap::new, Collectors.toList()));

        List<DmsShutReasonTreeVo> treeList = new ArrayList<>();
        boolean deviceScope = deviceId != null;
        for (DmsBaseShutType type : typeList)
        {
            List<DmsBaseShutReason> currentReasonList = reasonMap.get(type.getShutTypeId());
            if (CollectionUtils.isEmpty(currentReasonList))
            {
                continue;
            }
            currentReasonList = new ArrayList<>(currentReasonList);
            // 为什么这样做：同一个大类下优先展示现场更常选择的小类，减少班组维护停机原因时的查找成本。
            currentReasonList.sort((left, right) -> compareReasonByFrequency(left, right, deviceScope));
            DmsShutReasonTreeVo treeVo = new DmsShutReasonTreeVo();
            treeVo.setShutTypeId(type.getShutTypeId());
            treeVo.setTypeCode(type.getTypeCode());
            treeVo.setShutTypeName(type.getShutTypeName());
            treeVo.setReasonCount(currentReasonList.size());
            treeVo.setDeviceFreq(sumDeviceFreq(currentReasonList));
            treeVo.setLineFreq(sumLineFreq(currentReasonList));
            treeVo.setGlobalFreq(sumGlobalFreq(currentReasonList));
            treeVo.setReasonList(currentReasonList);
            treeList.add(treeVo);
        }
        // 为什么这样做：大类按其下原因的频次汇总排序，高频问题域会自然排在树的前面。
        treeList.sort((left, right) -> compareTypeByFrequency(left, right, deviceScope));
        return treeList;
    }

    private int compareReasonByFrequency(DmsBaseShutReason left, DmsBaseShutReason right, boolean deviceScope)
    {
        int result;
        if (deviceScope)
        {
            result = compareFrequencyDesc(left.getDeviceFreq(), right.getDeviceFreq());
            if (result != 0)
            {
                return result;
            }
            result = compareFrequencyDesc(left.getLineFreq(), right.getLineFreq());
            if (result != 0)
            {
                return result;
            }
        }
        result = compareFrequencyDesc(left.getGlobalFreq(), right.getGlobalFreq());
        if (result != 0)
        {
            return result;
        }
        result = compareStringAsc(left.getReasonCode(), right.getReasonCode());
        if (result != 0)
        {
            return result;
        }
        return compareLongAsc(left.getShutReasonId(), right.getShutReasonId());
    }

    private int compareTypeByFrequency(DmsShutReasonTreeVo left, DmsShutReasonTreeVo right, boolean deviceScope)
    {
        int result;
        if (deviceScope)
        {
            result = compareFrequencyDesc(left.getDeviceFreq(), right.getDeviceFreq());
            if (result != 0)
            {
                return result;
            }
            result = compareFrequencyDesc(left.getLineFreq(), right.getLineFreq());
            if (result != 0)
            {
                return result;
            }
        }
        result = compareFrequencyDesc(left.getGlobalFreq(), right.getGlobalFreq());
        if (result != 0)
        {
            return result;
        }
        result = compareStringAsc(left.getTypeCode(), right.getTypeCode());
        if (result != 0)
        {
            return result;
        }
        return compareLongAsc(left.getShutTypeId(), right.getShutTypeId());
    }

    private int compareFrequencyDesc(Long left, Long right)
    {
        return Long.compare(nullToZero(right), nullToZero(left));
    }

    private int compareStringAsc(String left, String right)
    {
        String leftValue = left == null ? "" : left;
        String rightValue = right == null ? "" : right;
        return leftValue.compareTo(rightValue);
    }

    private int compareLongAsc(Long left, Long right)
    {
        return Long.compare(nullToZero(left), nullToZero(right));
    }

    private Long sumDeviceFreq(List<DmsBaseShutReason> reasonList)
    {
        return reasonList.stream().mapToLong(reason -> nullToZero(reason.getDeviceFreq())).sum();
    }

    private Long sumLineFreq(List<DmsBaseShutReason> reasonList)
    {
        return reasonList.stream().mapToLong(reason -> nullToZero(reason.getLineFreq())).sum();
    }

    private Long sumGlobalFreq(List<DmsBaseShutReason> reasonList)
    {
        return reasonList.stream().mapToLong(reason -> nullToZero(reason.getGlobalFreq())).sum();
    }

    private long nullToZero(Long value)
    {
        return value == null ? 0L : value;
    }

    /**
     * 查询推荐停机原因
     *
     * @param deviceId 设备ID
     * @return 推荐列表
     */
    @Override
    public List<DmsShutReasonRecommendVo> selectRecommendShutReasonList(Long deviceId)
    {
        if (deviceId == null)
        {
            return Collections.emptyList();
        }
        return dmsBaseShutReasonMapper.selectRecommendReasonList(deviceId);
    }

    /**
     * 新增停机原因信息
     *
     * @param dmsBaseShutReason 停机原因信息
     * @return 结果
     */
    @Override
    public int insertDmsBaseShutReason(DmsBaseShutReason dmsBaseShutReason)
    {
        DmsBaseShutReason ShutReason = new DmsBaseShutReason();
        ShutReason.setReasonCode(dmsBaseShutReason.getReasonCode());
        List<DmsBaseShutReason> dmsBaseShutReasonList =  dmsBaseShutReasonMapper
                .selectDmsBaseShutReasonList(ShutReason);
       if (dmsBaseShutReasonList.size()>0){throw new ServiceException("停机原因编号已存在");}
        LoginUser user = SecurityUtils.getLoginUser();
        dmsBaseShutReason.setIsFlag("1");
        dmsBaseShutReason.setCreateBy(user.getUserId());
        dmsBaseShutReason.setCreateTime(DateUtils.getNowDate());
        return dmsBaseShutReasonMapper.insertDmsBaseShutReason(dmsBaseShutReason);
    }

    /**
     * 修改停机原因信息
     *
     * @param dmsBaseShutReason 停机原因信息
     * @return 结果
     */
    @Override
    public int updateDmsBaseShutReason(DmsBaseShutReason dmsBaseShutReason)
    {
        DmsBaseShutReason ShutReason = new DmsBaseShutReason();
        ShutReason.setReasonCode(dmsBaseShutReason.getReasonCode());
        List<DmsBaseShutReason> dmsBaseShutReasonList = dmsBaseShutReasonMapper
                .selectDmsBaseShutReasonList(ShutReason);
        if (dmsBaseShutReasonList.size()>0 && !dmsBaseShutReason.getShutReasonId()
                .equals(dmsBaseShutReasonList.get(0).getShutReasonId())){
            throw new ServiceException("停机原因编号已存在");
        }
        LoginUser user = SecurityUtils.getLoginUser();
        dmsBaseShutReason.setUpdateBy(user.getUserId());
        dmsBaseShutReason.setUpdateTime(DateUtils.getNowDate());
        return dmsBaseShutReasonMapper.updateDmsBaseShutReason(dmsBaseShutReason);
    }

    /**
     * 批量删除停机原因信息
     *
     * @param shutReasonIds 需要删除的停机原因信息主键
     * @return 结果
     */
    @Override
    public int deleteDmsBaseShutReasonByShutReasonIds(Long[] shutReasonIds)
    {
        return dmsBaseShutReasonMapper.deleteDmsBaseShutReasonByShutReasonIds(shutReasonIds);
    }

    /**
     * 删除停机原因信息信息
     *
     * @param shutReasonId 停机原因信息主键
     * @return 结果
     */
    @Override
    public int deleteDmsBaseShutReasonByShutReasonId(Long shutReasonId)
    {
        return dmsBaseShutReasonMapper.deleteDmsBaseShutReasonByShutReasonId(shutReasonId);
    }
}
