package com.fjhx.form.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjhx.form.entity.ProductionReportBo;
import com.fjhx.form.entity.ProductionReportSelectDto;
import com.fjhx.form.entity.SaleReportBo;
import com.fjhx.form.mapper.ReportMapper;
import com.fjhx.form.service.ReportService;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.mes.entity.report.po.ReportLossesDetails;
import com.fjhx.mes.service.report.ReportLossesDetailsService;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {

    private final ReportMapper reportMapper;
    private final ReportLossesDetailsService reportLossesDetailsService;
    private final ProductInfoService productInfoService;
    private final ISysDeptService deptService;

    @Autowired
    public ReportServiceImpl(ReportMapper reportMapper, ReportLossesDetailsService reportLossesDetailsService, ProductInfoService productInfoService, ISysDeptService sysDeptService) {
        this.reportMapper = reportMapper;
        this.reportLossesDetailsService = reportLossesDetailsService;
        this.productInfoService = productInfoService;
        this.deptService = sysDeptService;
    }

    @Override
    public Page<ProductionReportBo> productionReport(ProductionReportSelectDto dto) {
        IWrapper<Object> wrapper = IWrapper.getWrapper();

        Page<ProductionReportBo> page = reportMapper.productionReport(dto.getPage(), wrapper);
        List<ProductionReportBo> productionReportBos = page.getRecords();
        List<Long> ptIds = productionReportBos.stream().map(ProductionReportBo::getId).collect(Collectors.toList());


        //获取部门列表
        List<SysDept> companyList = deptService.list();
        Map<Long, String> companyMap = companyList.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getDeptName));

        //获取报损信息
        List<ReportLossesDetails> reportLossesDetails = reportLossesDetailsService.list(q -> q.in(ReportLossesDetails::getProdTaskId, ptIds));
        Map<Long, List<ReportLossesDetails>> reportLossesMap = reportLossesDetails.stream().collect(Collectors.groupingBy(ReportLossesDetails::getProdTaskId));

        for (ProductionReportBo vo : productionReportBos) {
            vo.setFactoryName(companyMap.get(vo.getFactoryId()));

            List<ReportLossesDetails> reportLossesList = reportLossesMap.getOrDefault(vo.getId(), new ArrayList<>());
            //原材料损耗 数量，成本
            List<ReportLossesDetails> rawReportLosses = reportLossesList.stream()
                    .filter(item -> ObjectUtil.equals(item.getMaterialType(), 1)).collect(Collectors.toList());
            BigDecimal rawLossCount = rawReportLosses.stream().map(ReportLossesDetails::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal rawLossAmount = rawReportLosses.stream().map(ReportLossesDetails::getMaterialPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            vo.setRawLossCount(rawLossCount);
            vo.setRawLossAmount(rawLossAmount);
            //普通物料 损耗 数量，成本
            List<ReportLossesDetails> bomReportLosses = reportLossesList.stream()
                    .filter(item -> ObjectUtil.notEqual(item.getMaterialType(), 1)).collect(Collectors.toList());
            BigDecimal bomLossCount = bomReportLosses.stream().map(ReportLossesDetails::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal bomLossAmount = bomReportLosses.stream().map(ReportLossesDetails::getMaterialPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            vo.setBomLossCount(bomLossCount);
            vo.setBomLossAmount(bomLossAmount);
            //返工 道数，成本
            Integer reworkCount = bomReportLosses.stream().map(ReportLossesDetails::getReCount).reduce(Integer::sum).orElse(0);
            BigDecimal reworkAmount = bomReportLosses.stream().map(ReportLossesDetails::getRePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            vo.setReworkCount(reworkCount);
            vo.setReworkAmount(reworkAmount);
            //出错率
            BigDecimal multiply = vo.getRawLossCount().divide(vo.getQuantity(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
            vo.setErrRate(multiply);
        }

        return page;
    }

    @Override
    public Page<SaleReportBo> saleReport(ProductionReportSelectDto dto) {
        IWrapper<Object> wrapper = IWrapper.getWrapper();
        Page<SaleReportBo> saleReportBoPage = reportMapper.saleReport(dto.getPage(), wrapper);
        List<SaleReportBo> records = saleReportBoPage.getRecords();

        //获取部门列表
        List<SysDept> deptList = deptService.list();
        Map<Long, String> deptMap = deptList.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getDeptName));

        for (SaleReportBo record : records) {
            //业务公司
            record.setOfCompanyName(deptMap.get(record.getOfCompanyId()));
            //业务部门
            record.setDeptName(deptMap.get(record.getDeptId()));
            //工厂
            record.setCompanyName(deptMap.get(record.getCompanyId()));
            //不及时率
            BigDecimal untimelyRate = record.getOutInterval().divide(BigDecimal.valueOf(30), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
            record.setUntimelyRate(untimelyRate);
        }
        return saleReportBoPage;
    }
}
