package com.artfess.cqlt.manager.impl;

import com.artfess.base.enums.OperationTargetTypeEnum;
import com.artfess.base.enums.ProductSalesDataTypeEnum;
import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.util.StringUtil;
import com.artfess.cqlt.dao.QfOperationSalesProductMDao;
import com.artfess.cqlt.manager.QfOperationSalesProductDManager;
import com.artfess.cqlt.manager.QfOperationSalesProductMManager;
import com.artfess.cqlt.model.QfOperationSalesM;
import com.artfess.cqlt.model.QfOperationSalesProductD;
import com.artfess.cqlt.model.QfOperationSalesProductM;
import com.artfess.cqlt.model.SysSubjectTarget;
import com.artfess.cqlt.utils.FinancialTimeUtils;
import com.artfess.cqlt.vo.DateReqVo;
import com.artfess.cqlt.vo.FaReportRespVo;
import com.artfess.cqlt.vo.OpDateReqVo;
import com.artfess.cqlt.vo.OpReportReqVo;
import com.artfess.cqlt.vo.OpReportRespVo;
import com.artfess.cqlt.vo.OpTargetRespVo;
import com.artfess.i18n.util.I18nUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 运营--产品销售数据填报主表 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2023-02-17
 */
@Service
public class QfOperationSalesProductMManagerImpl extends BaseManagerImpl<QfOperationSalesProductMDao, QfOperationSalesProductM> implements QfOperationSalesProductMManager {

    private FinancialTimeUtils financialTimeUtils = new FinancialTimeUtils();

    @Autowired
    private QfOperationSalesProductDManager operationSalesDManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertInfo(QfOperationSalesProductM t) {
        QueryWrapper<QfOperationSalesProductM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("fill_month_", t.getFillMonth());
        queryWrapper.eq("report_id_", t.getReportId());
        List<QfOperationSalesProductM> QfOperationSalesProductMS = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(QfOperationSalesProductMS)) {
            throw new BaseException(I18nUtil.getMessage("QfOperationKpiM.repeat", LocaleContextHolder.getLocale()));
        }
        int insert = this.baseMapper.insert(t);
        if (insert > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInfo(QfOperationSalesProductM t) {
        QueryWrapper<QfOperationSalesProductM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("fill_month_", t.getFillMonth());
        queryWrapper.eq("report_id_", t.getReportId());
        queryWrapper.ne("id_", t.getId());
        List<QfOperationSalesProductM> QfOperationSalesProductMS = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(QfOperationSalesProductMS)) {
            throw new BaseException(I18nUtil.getMessage("QfOperationKpiM.repeat", LocaleContextHolder.getLocale()));
        }
        int insert = this.baseMapper.updateById(t);
        if (insert > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(QfOperationSalesProductM t) {
        QfOperationSalesProductM QfOperationSalesProductM = baseMapper.selectById(t.getId());
        if (null == QfOperationSalesProductM) {
            return false;
        }
        QfOperationSalesProductM.setStatus(QfOperationSalesProductM.getStatus() == 0 ? 1 : 0);
        int i = this.baseMapper.updateById(QfOperationSalesProductM);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importExcel(List<QfOperationSalesProductD> list, String mainId) {
        QfOperationSalesProductM QfOperationSalesProductM = this.baseMapper.selectById(mainId);
        Assert.notNull(QfOperationSalesProductM, I18nUtil.getMessage("filldata.notExist", LocaleContextHolder.getLocale()));
        Assert.isTrue(!"1".equals(QfOperationSalesProductM.getStatus()),  I18nUtil.getMessage("data_operate", LocaleContextHolder.getLocale()));
        QueryWrapper<QfOperationSalesProductD> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("main_id_", mainId);
        operationSalesDManager.remove(queryWrapper);

        //获取上个月的信息
        Map<String, QfOperationSalesProductD> historyMap = this.historyList(QfOperationSalesProductM);
        list.forEach(detail -> {
            detail.setMainId(mainId);
            detail.setFillDate(QfOperationSalesProductM.getFillDate());

            if (null == detail.getBudgetYtd()) {
                detail.setBudgetYtd(BigDecimal.ZERO);
            }
            if (null == detail.getActualYtd()) {
                detail.setActualYtd(BigDecimal.ZERO);
            }
            if (!historyMap.containsKey(detail.getProduct())) {
                detail.setActual(detail.getActualYtd());
                detail.setBudget(detail.getActualYtd());
            } else {
                QfOperationSalesProductD salesProductD = historyMap.get(detail.getProduct());
                if (null == salesProductD.getBudgetYtd()) {
                    detail.setBudget(BigDecimal.ZERO);
                } else {
                    detail.setBudget(detail.getBudgetYtd().subtract(salesProductD.getBudgetYtd()));
                }
                if (null == salesProductD.getActualYtd()) {
                    detail.setActual(BigDecimal.ZERO);
                } else {
                    detail.setActual(detail.getActualYtd().subtract(salesProductD.getActualYtd()));
                }
                if (null == salesProductD) {
                    detail.setActual(detail.getActualYtd());
                    detail.setBudget(detail.getActualYtd());
                }
            }

            String dataType = ProductSalesDataTypeEnum.getType(detail.getDataType());
            detail.setDataType(dataType);
        });
        boolean b = operationSalesDManager.saveBatch(list);
        return b;
    }

    @Override
    public List<OpTargetRespVo> dataAnalysis(OpReportReqVo t, SysSubjectTarget target) {
        List<String> typeList = Arrays.asList(target.getType().split(","));
        //展示第一个以后数据统计图
        List<String> newTypeList = Lists.newArrayList();
        for (int i = 0; i < typeList.size(); i++) {
            if (i > 0) {
                newTypeList.add(typeList.get(i));
            }
        }
        List<OpTargetRespVo> resultList = Lists.newArrayList();
        newTypeList.forEach(type -> {
            OperationTargetTypeEnum targetTypeEnum = OperationTargetTypeEnum.getTarget(type);
            if (null == targetTypeEnum) {
                return;
            }
            OpDateReqVo dateReqVo = financialTimeUtils.processOpDateReqVo(t, type);
            financialTimeUtils.processOpDateQuery(t, dateReqVo);
            switch (targetTypeEnum) {
                case ndsj:
                    yearAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                case ndkhsy:
                    yearCustomerAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                case ndkh:
                    yearCustomerProportion(target, t, resultList, targetTypeEnum);
                    break;
                case ndcpsy:
                    yearProductAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                case ndcp:
                    yearProductProportion(target, t, resultList, targetTypeEnum);
                    break;
                case dysj:
                    monthAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                default:
                    break;
            }
        });

        return resultList;
    }

    private void monthAnalysis(SysSubjectTarget target, OpReportReqVo t, List<OpTargetRespVo> resultList, OperationTargetTypeEnum targetTypeEnum) {
        OpTargetRespVo resultFa = getOpTargetRespVo(target, targetTypeEnum);
        List<OpReportRespVo> opReportRespVos = this.baseMapper.monthAnalysis(t);
        opReportRespVos.forEach(resp -> {
            resp.setYear(t.getYear());
        });
        resultFa.setResultData(opReportRespVos);
        resultList.add(resultFa);
    }

    private void yearProductProportion(SysSubjectTarget target, OpReportReqVo t, List<OpTargetRespVo> resultList, OperationTargetTypeEnum targetTypeEnum) {
        OpTargetRespVo resultFa = getOpTargetRespVo(target, targetTypeEnum);
        List<OpReportRespVo> opReportRespVos = this.baseMapper.yearProductDetail(t);
        BigDecimal totalActual = opReportRespVos.stream().map(OpReportRespVo::getActual).reduce(BigDecimal.ZERO, BigDecimal::add);
        opReportRespVos.stream().forEach(resp -> {
            BigDecimal actual = BigDecimal.ZERO;
            if (null != resp.getActual() && 0 != resp.getActual().doubleValue()) {
                actual = resp.getActual().divide(totalActual, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            }
            resp.setProduct(ProductSalesDataTypeEnum.getDesc(resp.getProduct()));
            resp.setActual(actual);
            resp.setBudget(null);
        });
        resultFa.setResultData(opReportRespVos);
        resultList.add(resultFa);
    }

    private void yearProductAnalysis(SysSubjectTarget target, OpReportReqVo t, List<OpTargetRespVo> resultList, OperationTargetTypeEnum targetTypeEnum) {
        if (StringUtil.isEmpty(t.getProduct())) {
            t.setProduct(ProductSalesDataTypeEnum.ONE.getType());
        }
        OpTargetRespVo resultFa = getOpTargetRespVo(target, targetTypeEnum);
        List<OpReportRespVo> opReportRespVos = this.baseMapper.yearProductData(t);
        resultFa.setResultData(opReportRespVos);
        resultList.add(resultFa);
    }

    private void yearCustomerProportion(SysSubjectTarget target, OpReportReqVo t, List<OpTargetRespVo> resultList, OperationTargetTypeEnum targetTypeEnum) {
        OpTargetRespVo resultFa = getOpTargetRespVo(target, targetTypeEnum);
        List<OpReportRespVo> opReportRespVos = this.baseMapper.yearCustomerData(t);
        BigDecimal totalActual = opReportRespVos.stream().map(OpReportRespVo::getActual).reduce(BigDecimal.ZERO, BigDecimal::add);
        opReportRespVos.stream().forEach(resp -> {
            BigDecimal actual = BigDecimal.ZERO;
            if (null != resp.getActual() && 0 != resp.getActual().doubleValue()) {
                actual = resp.getActual().divide(totalActual, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            }

            resp.setActual(actual);
            resp.setBudget(null);
        });
        resultFa.setResultData(opReportRespVos);
        resultList.add(resultFa);

    }

    private void yearCustomerAnalysis(SysSubjectTarget target, OpReportReqVo t, List<OpTargetRespVo> resultList, OperationTargetTypeEnum targetTypeEnum) {
        OpTargetRespVo resultFa = getOpTargetRespVo(target, targetTypeEnum);
        List<OpReportRespVo> opReportRespVos = this.baseMapper.yearData(t);
        resultFa.setResultData(opReportRespVos);
        resultList.add(resultFa);
    }

    private OpTargetRespVo getOpTargetRespVo(SysSubjectTarget target, OperationTargetTypeEnum targetTypeEnum) {
        String type = targetTypeEnum.getType().toString();
        OpTargetRespVo resultFa = new OpTargetRespVo();
        resultFa.setTargetId(target.getId());
        resultFa.setTargetName(targetTypeEnum.getTargetName());
        resultFa.setTargetNameEn(targetTypeEnum.getTargetNameEn());
        resultFa.setTargetUnit(target.getUnit());
        resultFa.setType(type);
        resultFa.setSn(targetTypeEnum.getType());
        resultFa.setStaLat(targetTypeEnum.getStaLat());
        return resultFa;
    }

    private void yearAnalysis(SysSubjectTarget target, OpReportReqVo t, List<OpTargetRespVo> resultList, OperationTargetTypeEnum targetTypeEnum) {
        OpTargetRespVo resultFa = getOpTargetRespVo(target, targetTypeEnum);
        List<OpReportRespVo> opReportRespVos = this.baseMapper.yearData(t);
        resultFa.setResultData(opReportRespVos);
        resultList.add(resultFa);
    }

    private Map<String, QfOperationSalesProductD> historyList(QfOperationSalesProductM QfFinancePlBudgetM) {
        //获取上个月的数据
        List<QfOperationSalesProductD> historyList = this.baseMapper.historyList(QfFinancePlBudgetM.getFillMonth() - 1, QfFinancePlBudgetM.getFillYear());
        if (CollectionUtils.isEmpty(historyList)) {
            return Maps.newHashMap();
        }
        Map<String, QfOperationSalesProductD> historyProduct = historyList.stream().collect(Collectors.toMap(item -> item.getProduct(), item -> item));
        return historyProduct;
    }

}
