package com.qmth.sop.server.api;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ImmutableMap;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.sop.business.bean.report.QualityAnalyseReportBean;
import com.qmth.sop.business.bean.report.QualityAnalyseReportViewBean;
import com.qmth.sop.business.service.QualityAnalyseReportService;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.InfluenceDegreeEnum;
import com.qmth.sop.common.enums.QualityProblemReasonEnum;
import com.qmth.sop.common.util.Result;
import com.qmth.sop.common.util.ResultUtil;
import io.swagger.annotations.*;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "质量监控分析Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_QUALITY_ANALYSE)
public class QualityAnalyseReportController {

    public static final String IN_FLUENCE_DEGREE_A_TOTAL = "influenceDegreeATotal";

    public static final String IN_FLUENCE_DEGREE_B_TOTAL = "influenceDegreeBTotal";

    public static final String IN_FLUENCE_DEGREE_C_TOTAL = "influenceDegreeCTotal";

    public static final String IN_FLUENCE_DEGREE_D_TOTAL = "influenceDegreeDTotal";

    public static final String IN_FLUENCE_DEGREE_A_RATE_TOTAL = "influenceDegreeARateTotal";

    public static final String IN_FLUENCE_DEGREE_B_RATE_TOTAL = "influenceDegreeBRateTotal";

    public static final String IN_FLUENCE_DEGREE_C_RATE_TOTAL = "influenceDegreeCRateTotal";

    public static final String IN_FLUENCE_DEGREE_D_RATE_TOTAL = "influenceDegreeDRateTotal";

    public static final String REASON_RATE_TOTAL = "reasonRateTotal";

    @Resource
    QualityAnalyseReportService qualityAnalyseReportService;

    @ApiOperation(value = "大区质量问题统计")
    @RequestMapping(value = "/area_manager/report", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "质量监控分析报表", response = QualityAnalyseReportBean.class) })
    public Result areaManagerReport(@ApiParam(value = "服务单元id", required = true) @RequestParam Long serviceId) {
        return ResultUtil.ok(this.calculateRate(qualityAnalyseReportService.areaQualityReport(serviceId)));
    }

    @ApiOperation(value = "人力商质量问题统计")
    @RequestMapping(value = "/human_supplier/report", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "质量监控分析报表", response = QualityAnalyseReportBean.class) })
    public Result humanSupplierReport(@ApiParam(value = "服务单元id", required = true) @RequestParam Long serviceId) {
        return ResultUtil.ok(this.calculateRate(qualityAnalyseReportService.humanSupplierQualityReport(serviceId)));
    }

    @ApiOperation(value = "质量问题原因分类")
    @RequestMapping(value = "/type/report", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "质量监控分析报表", response = QualityAnalyseReportBean.class) })
    public Result typeReport(@ApiParam(value = "服务单元id", required = true) @RequestParam Long serviceId) {
        List<QualityAnalyseReportBean> qualityAnalyseReportBeanList = qualityAnalyseReportService.reasonQualityReport(
                serviceId);
        Integer total = qualityAnalyseReportBeanList.stream().mapToInt(s -> s.getReasonSum()).sum();
        if (!CollectionUtils.isEmpty(qualityAnalyseReportBeanList)) {
            Set<QualityProblemReasonEnum> qualityAnalyseReportBeanAddSet = new LinkedHashSet<>();
            QualityProblemReasonEnum[] qualityProblemReasonEnums = QualityProblemReasonEnum.values();
            for (QualityProblemReasonEnum q : qualityProblemReasonEnums) {
                List<QualityAnalyseReportBean> tempList = qualityAnalyseReportBeanList.stream()
                        .filter(x -> q == x.getReason()).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(tempList)) {
                    qualityAnalyseReportBeanAddSet.add(q);
                }
            }
            qualityAnalyseReportBeanList.stream().peek(s -> {
                s.setNull();
                for (QualityProblemReasonEnum q : qualityProblemReasonEnums) {
                    if (q == s.getReason()) {
                        BigDecimal reasonRate = new BigDecimal(s.getReasonSum());
                        reasonRate = reasonRate.divide(new BigDecimal(total), 2, BigDecimal.ROUND_HALF_UP)
                                .multiply(SystemConstant.RATE).setScale(2, BigDecimal.ROUND_HALF_UP);
                        s.setReasonRate(reasonRate);
                        break;
                    }
                }
            }).collect(Collectors.toList());
            qualityAnalyseReportBeanAddSet.stream()
                    .peek(s -> qualityAnalyseReportBeanList.add(new QualityAnalyseReportBean(s)))
                    .collect(Collectors.toList());
        }
        Double reasonRateTotal = qualityAnalyseReportBeanList.stream().mapToDouble(s -> s.getReasonRate().doubleValue())
                .sum();
        return ResultUtil.ok(
                new ImmutableMap.Builder<String, Object>().put(ResourceSecurityReportController.TOTAL, total)
                        .put(REASON_RATE_TOTAL, new BigDecimal(reasonRateTotal))
                        .put(ResourceSecurityReportController.RECORDS, qualityAnalyseReportBeanList).build());
    }

    @ApiOperation(value = "报表详情")
    @RequestMapping(value = "/report/view", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "质量监控分析报表详情", response = QualityAnalyseReportViewBean.class) })
    public Result reportView(@ApiParam(value = "服务单元id", required = true) @RequestParam Long serviceId,
            @ApiParam(value = "大区经理id") @RequestParam(required = false) Long areaManagerId,
            @ApiParam(value = "供应商id") @RequestParam(required = false) Long supplierId,
            @ApiParam(value = "问题原因") @RequestParam(required = false) QualityProblemReasonEnum reason,
            @ApiParam(value = "客户名称") @RequestParam(required = false) String customName,
            @ApiParam(value = "影响度") @RequestParam(required = false) InfluenceDegreeEnum influenceDegree,
            @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
            @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        return ResultUtil.ok(
                qualityAnalyseReportService.viewList(new Page<>(pageNumber, pageSize), serviceId, areaManagerId,
                        supplierId, reason, customName, influenceDegree));
    }

    @ApiOperation(value = "报表详情导出")
    @RequestMapping(value = "/report/view/export", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "质量监控分析报表详情", response = QualityAnalyseReportViewBean.class) })
    public void reportViewExport(@ApiParam(value = "服务单元id", required = true) @RequestParam Long serviceId,
            @ApiParam(value = "大区经理id") @RequestParam(required = false) Long areaManagerId,
            @ApiParam(value = "机构id") @RequestParam(required = false) Long supplierId,
            @ApiParam(value = "问题原因") @RequestParam(required = false) QualityProblemReasonEnum reason,
            @ApiParam(value = "客户名称") @RequestParam(required = false) String customName,
            @ApiParam(value = "影响度") @RequestParam(required = false) InfluenceDegreeEnum influenceDegree) {
        qualityAnalyseReportService.viewListExport(serviceId, areaManagerId, supplierId, reason, customName,
                influenceDegree);
    }

    /**
     * 计算比率
     *
     * @param qualityAnalyseReportBeanList
     * @return
     */
    protected Map<String, Object> calculateRate(List<QualityAnalyseReportBean> qualityAnalyseReportBeanList) {
        Integer total = qualityAnalyseReportBeanList.stream().mapToInt(s -> s.getSum()).sum();
        Integer influenceDegreeATotal = qualityAnalyseReportBeanList.stream().mapToInt(s -> s.getInfluenceDegreeA())
                .sum();
        Integer influenceDegreeBTotal = qualityAnalyseReportBeanList.stream().mapToInt(s -> s.getInfluenceDegreeB())
                .sum();
        Integer influenceDegreeCTotal = qualityAnalyseReportBeanList.stream().mapToInt(s -> s.getInfluenceDegreeC())
                .sum();
        Integer influenceDegreeDTotal = qualityAnalyseReportBeanList.stream().mapToInt(s -> s.getInfluenceDegreeD())
                .sum();
        BigDecimal influenceDegreeARateTotal = new BigDecimal(influenceDegreeATotal);
        BigDecimal influenceDegreeBRateTotal = new BigDecimal(influenceDegreeBTotal);
        BigDecimal influenceDegreeCRateTotal = new BigDecimal(influenceDegreeCTotal);
        BigDecimal influenceDegreeDRateTotal = new BigDecimal(influenceDegreeDTotal);

        if (Objects.nonNull(total) && total.intValue() > 0) {
            influenceDegreeARateTotal = influenceDegreeARateTotal.divide(new BigDecimal(total), 2,
                    BigDecimal.ROUND_HALF_UP).multiply(SystemConstant.RATE).setScale(2, BigDecimal.ROUND_HALF_UP);
            influenceDegreeBRateTotal = influenceDegreeBRateTotal.divide(new BigDecimal(total), 2,
                    BigDecimal.ROUND_HALF_UP).multiply(SystemConstant.RATE).setScale(2, BigDecimal.ROUND_HALF_UP);
            influenceDegreeCRateTotal = influenceDegreeCRateTotal.divide(new BigDecimal(total), 2,
                    BigDecimal.ROUND_HALF_UP).multiply(SystemConstant.RATE).setScale(2, BigDecimal.ROUND_HALF_UP);
            influenceDegreeDRateTotal = influenceDegreeDRateTotal.divide(new BigDecimal(total), 2,
                    BigDecimal.ROUND_HALF_UP).multiply(SystemConstant.RATE).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        return new ImmutableMap.Builder<String, Object>().put(ResourceSecurityReportController.TOTAL, total)
                .put(IN_FLUENCE_DEGREE_A_TOTAL, influenceDegreeATotal)
                .put(IN_FLUENCE_DEGREE_B_TOTAL, influenceDegreeBTotal)
                .put(IN_FLUENCE_DEGREE_C_TOTAL, influenceDegreeCTotal)
                .put(IN_FLUENCE_DEGREE_D_TOTAL, influenceDegreeDTotal)
                .put(IN_FLUENCE_DEGREE_A_RATE_TOTAL, influenceDegreeARateTotal)
                .put(IN_FLUENCE_DEGREE_B_RATE_TOTAL, influenceDegreeBRateTotal)
                .put(IN_FLUENCE_DEGREE_C_RATE_TOTAL, influenceDegreeCRateTotal)
                .put(IN_FLUENCE_DEGREE_D_RATE_TOTAL, influenceDegreeDRateTotal)
                .put(ResourceSecurityReportController.RECORDS, qualityAnalyseReportBeanList).build();
    }
}
