package com.diagbot.aggregate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.diagbot.dto.NumDTO;
import com.diagbot.facade.BehospitalInfoFacade;
import com.diagbot.facade.QcresultInfoFacade;
import com.diagbot.util.BeanUtil;
import com.diagbot.util.ListUtil;
import com.diagbot.vo.FilterVO;
import com.google.common.collect.Lists;

import io.github.lvyahui8.spring.annotation.DataConsumer;
import io.github.lvyahui8.spring.annotation.DataProvider;
import io.github.lvyahui8.spring.annotation.InvokeParameter;

/**
 * @Description:缺陷相关统计
 * @author: gaodm
 * @time: 2024/4/22 18:09
 */
@Component
public class ResultStatisticsAggregate {
    @Autowired
    private QcresultInfoFacade qcresultInfoFacade;
    @Autowired
    private BehospitalInfoFacade behospitalInfoFacade;

    @DataProvider("setAllResult")
    public Map<String, Object> setAllResult(
            @InvokeParameter("filterVO") FilterVO filterVO,
            @DataConsumer("entryByDept") List<NumDTO> deptList,
            @DataConsumer("entryCountGroupByEntry") List<NumDTO> entryList,
            @DataConsumer("entryCountGroupByCase") List<NumDTO> caseList) {
        Map<String, Object> retMap = new LinkedHashMap<>();
        retMap.put("各科室缺陷占比", Lists.newLinkedList());
        retMap.put("各模块缺陷占比排行", Lists.newLinkedList());
        retMap.put("条目缺陷占比", Lists.newLinkedList());
        if (ListUtil.isNotEmpty(deptList)) {
            retMap.put("各科室缺陷占比", deptList);
        }
        if (ListUtil.isNotEmpty(caseList)) {
            retMap.put("各模块缺陷占比排行", caseList);
        }
        if (ListUtil.isNotEmpty(entryList)) {
            retMap.put("条目缺陷占比", entryList);
        }

        return retMap;
    }

    /**
     * 各模块缺陷占比排行
     *
     * @param filterVO
     * @return
     */
    @DataProvider("entryCountGroupByCase")
    public List<NumDTO> entryCountGroupByCase(@InvokeParameter("filterVO") FilterVO filterVO) {
        List<NumDTO> qcEntryNumList = qcresultInfoFacade.entryCountGroupByCase(filterVO);
        return qcEntryNumList;
    }

    /**
     * 条目缺陷占比
     *
     * @param filterVO
     * @return
     */
    @DataProvider("entryCountGroupByEntry")
    public List<NumDTO> entryCountGroupByEntry(@InvokeParameter("filterVO") FilterVO filterVO) {
        Integer limitCount = filterVO.getLimitCount();
        List<NumDTO> numDTOList = qcresultInfoFacade.entryCountGroupByEntry(filterVO);
        if (ListUtil.isNotEmpty(numDTOList)) {
            List<NumDTO> retList = Lists.newLinkedList();
            if (numDTOList.size() <= limitCount) {
                retList = numDTOList;
            } else {
                retList = numDTOList.subList(0, limitCount);
            }
            return retList;
        }
        return null;
    }

    /**
     * 各科室缺陷占比-全院-首页
     *
     * @param filterVO
     * @return
     */
    @DataProvider("entryByDept")
    public List<NumDTO> entryByDept(@InvokeParameter("filterVO") FilterVO filterVO) {
        Integer limitCount = filterVO.getLimitCount();
        List<NumDTO> numDTOList = behospitalInfoFacade.entryByDept(filterVO);
        if (ListUtil.isNotEmpty(numDTOList)) {
            int totle = numDTOList
                    .stream()
                    .map(NumDTO::getNum)
                    .reduce(0, Integer::sum);
            numDTOList.forEach(result -> {
                Double percent = BigDecimal.valueOf(result.getNum())
                        .divide(BigDecimal.valueOf(totle), 4, RoundingMode.HALF_UP)
                        .doubleValue();
                result.setPercent(percent);
            });
            List<NumDTO> retList = Lists.newLinkedList();
            if (numDTOList.size() <= limitCount) {
                retList = BeanUtil.listCopyTo(numDTOList, NumDTO.class);
            } else {

                Double rate = 0d;
                Integer num = 0;
                for (NumDTO numDTO : numDTOList) {
                    if (retList.size() < limitCount - 1) {
                        rate = BigDecimal.valueOf(rate)
                                .add(BigDecimal.valueOf(Double.valueOf(numDTO.getPercent())))
                                .doubleValue();
                        retList.add(numDTO);
                    } else {
                        num += numDTO.getNum();
                    }
                }
                NumDTO otherNumDTO = new NumDTO();
                otherNumDTO.setName("其他");
                otherNumDTO.setNum(num);
                otherNumDTO.setPercent(BigDecimal.valueOf(num)
                        .divide(BigDecimal.valueOf(totle), 4, RoundingMode.HALF_UP)
                        .doubleValue());
                retList.add(otherNumDTO);
            }
            retList.forEach(result -> {
                DecimalFormat df = new DecimalFormat("#0.00");
                String percentStr
                        = df.format(BigDecimal.valueOf(result.getPercent()).multiply(BigDecimal.valueOf(100))) + "%";
                result.setPercentStr(percentStr);
            });
            return retList;
        }
        return null;
    }
}