package com.artfess.cqlt.manager.impl;

import com.artfess.base.enums.OperationTargetTypeEnum;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.cqlt.dao.QfOperationSopDDao;
import com.artfess.cqlt.dao.QfOperationSopMDao;
import com.artfess.cqlt.manager.QfOperationSopDManager;
import com.artfess.cqlt.model.QfOperationSalesProductM;
import com.artfess.cqlt.model.QfOperationSopD;
import com.artfess.cqlt.model.QfOperationSopM;
import com.artfess.cqlt.model.SysSubjectTarget;
import com.artfess.cqlt.utils.FinancialTimeUtils;
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.google.common.collect.Lists;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * 运营--新项目收入贡献填报详情表 服务实现类
 *
 * @company 阿特菲斯信息技术有限公司
 * @author 黎沐华
 * @since 2023-02-21
 */
@Service
public class QfOperationSopDManagerImpl extends BaseManagerImpl<QfOperationSopDDao, QfOperationSopD> implements QfOperationSopDManager {

    @Resource
    private QfOperationSopMDao sopMDao;

    private FinancialTimeUtils financialTimeUtils = new FinancialTimeUtils();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdate(QfOperationSopM t) {
        Assert.hasText(t.getId(), I18nUtil.getMessage("QfOperationSopM.reportId", LocaleContextHolder.getLocale()));
        QfOperationSopM mainInfo = sopMDao.selectById(t.getId());
        Assert.notNull(mainInfo, I18nUtil.getMessage("filldata.notExist", LocaleContextHolder.getLocale()));
        Assert.isTrue(!"1".equals(mainInfo.getStatus()),  I18nUtil.getMessage("data_operate", LocaleContextHolder.getLocale()));
        t.getList().forEach(detail -> {
            detail.setMainId(t.getId());
        });
        boolean b = this.saveOrUpdateBatch(t.getList());
        return b;
    }

    @Override
    public List<OpReportRespVo> yearData(OpReportReqVo t) {
        return this.baseMapper.yearData(t);
    }

    @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:
                    t.setYear(null);
                    yearAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                case ndkh:
                    yearCustomerProportion(target, t, resultList, targetTypeEnum);
                    break;
                case dysj:
                    monthAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                default:
                    break;
            }
        });

        return resultList;
    }

    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 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 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 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;
    }
}
