package com.artfess.cqlt.manager.impl;

import com.artfess.base.enums.DelStatusEnum;
import com.artfess.base.enums.OperationTargetTypeEnum;
import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.cqlt.dao.QfOperationCompanyCipDDao;
import com.artfess.cqlt.dao.QfOperationCompanyCipMDao;
import com.artfess.cqlt.manager.QfEnterpriseInfoManager;
import com.artfess.cqlt.manager.QfOperationCompanyCipDManager;
import com.artfess.cqlt.model.QfEnterpriseInfo;
import com.artfess.cqlt.model.QfOperationCompanyCipD;
import com.artfess.cqlt.model.QfOperationCompanyCipM;
import com.artfess.cqlt.model.QfSubjectInternationalInfo;
import com.artfess.cqlt.model.SysSubjectTarget;
import com.artfess.cqlt.utils.FinancialTimeUtils;
import com.artfess.cqlt.vo.OpDateReqVo;
import com.artfess.cqlt.vo.OpReportRespVo;
import com.artfess.cqlt.vo.OpTargetRespVo;
import com.artfess.cqlt.vo.OpReportReqVo;
import com.artfess.i18n.util.I18nUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
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.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 运营--集团持续改进数据-分公司填报详情表 服务实现类
 *
 * @company 阿特菲斯信息技术有限公司
 * @author min.wu
 * @since 2023-02-21
 */
@Service
public class QfOperationCompanyCipDManagerImpl extends BaseManagerImpl<QfOperationCompanyCipDDao, QfOperationCompanyCipD> implements QfOperationCompanyCipDManager {

    private FinancialTimeUtils financialTimeUtils = new FinancialTimeUtils();

    @Resource
    private QfOperationCompanyCipMDao cipMDao;

    @Autowired
    private QfEnterpriseInfoManager enterpriseInfoManager;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSave(QfOperationCompanyCipM t) {
        Assert.hasText(t.getId(), I18nUtil.getMessage("QfOperationKpiM.reportId", LocaleContextHolder.getLocale()));
        QfOperationCompanyCipM QfOperationCompanyCipM = cipMDao.selectById(t.getId());
        Assert.notNull(QfOperationCompanyCipM, I18nUtil.getMessage("filldata.notExist", LocaleContextHolder.getLocale()));
        Assert.isTrue(!"1".equals(QfOperationCompanyCipM.getStatus()),  I18nUtil.getMessage("data_operate", LocaleContextHolder.getLocale()));
        QueryWrapper<QfSubjectInternationalInfo> query = new QueryWrapper<>();
        query.eq("IS_DELE_", DelStatusEnum.N.getType());
        //获取境外企业
        Map<String, QfEnterpriseInfo> enterpriseInfoMap = enterpriseInfoManager.getEnterpriseInfoMap(null);

        List<QfOperationCompanyCipD> list = t.getList();
        StringBuffer sb = new StringBuffer();
        list.forEach(detail -> {
            detail.setMainId(t.getId());
            detail.setFillDate(QfOperationCompanyCipM.getFillDate());
            //获取对应企业信息

            if(StringUtils.isEmpty(detail.getEnterpriseCode())) {
                throw new BaseException(I18nUtil.getMessage("fill.code", LocaleContextHolder.getLocale()));
            }
            if(!enterpriseInfoMap.containsKey(detail.getEnterpriseCode())) {
                sb.append(",");
                sb.append(detail.getEnterpriseCode());
            }else {
                QfEnterpriseInfo qfEnterpriseInfo = enterpriseInfoMap.get(detail.getEnterpriseCode());
                detail.setEnterpriseName(qfEnterpriseInfo.getName());
                detail.setEnterpriseType(qfEnterpriseInfo.getEconomyType());
                detail.setEnterpriseArea(qfEnterpriseInfo.getContinent());
            }
        });
        if(sb.length() > 0) {
            throw new BaseException(sb.substring(1) + I18nUtil.getMessage("code.notExist", LocaleContextHolder.getLocale()));
        }
        boolean b = this.saveOrUpdateBatch(list);
        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<OpTargetRespVo> resultList = Lists.newArrayList();
        typeList.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 ndgssy:
                    yearAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                case ndgs:
                    yearCompanyProportion(target, t, resultList, targetTypeEnum);
                    break;
                case dysj:
                    monthAnalysis(target, t, resultList, targetTypeEnum);
                    break;
                default:
                    break;
            }
        });

        return resultList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdate(QfOperationCompanyCipM t) {
        Assert.hasText(t.getId(), I18nUtil.getMessage("QfOperationKpiM.reportId", LocaleContextHolder.getLocale()));
        QfOperationCompanyCipM QfOperationCompanyCipM = cipMDao.selectById(t.getId());
        QueryWrapper<QfSubjectInternationalInfo> query = new QueryWrapper<>();
        query.eq("IS_DELE_", DelStatusEnum.N.getType());
        Map<String, QfEnterpriseInfo> detailMap = enterpriseInfoManager.getEnterpriseInfoMap(null);
        List<QfOperationCompanyCipD> list = t.getList();
        StringBuffer sb = new StringBuffer();
        list.forEach(detail -> {
            detail.setMainId(t.getId());
            detail.setFillDate(QfOperationCompanyCipM.getFillDate());
            if(StringUtils.isEmpty(detail.getEnterpriseCode())) {
                throw new BaseException(I18nUtil.getMessage("fill.code", LocaleContextHolder.getLocale()));
            }
            if(!detailMap.containsKey(detail.getEnterpriseCode())) {
                sb.append(",");
                sb.append(detail.getEnterpriseCode());
            }else {
                QfEnterpriseInfo qfEnterpriseInfo = detailMap.get(detail.getEnterpriseCode());
                detail.setEnterpriseName(qfEnterpriseInfo.getName());
                detail.setEnterpriseType(qfEnterpriseInfo.getEconomyType());
                detail.setEnterpriseArea(qfEnterpriseInfo.getContinent());
            }
        });
        if(sb.length() > 0) {
            throw new BaseException(sb.substring(1) + I18nUtil.getMessage("code.notExist", LocaleContextHolder.getLocale()));
        }
        boolean b = this.saveOrUpdateBatch(list);
        return b;
    }

    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 yearCompanyProportion(SysSubjectTarget target, OpReportReqVo t, List<OpTargetRespVo> resultList, OperationTargetTypeEnum targetTypeEnum) {
        OpTargetRespVo resultFa = getOpTargetRespVo(target, targetTypeEnum);
        List<OpReportRespVo> opReportRespVos = this.baseMapper.yearCompanyData(t);
        Map<String, QfEnterpriseInfo> enterpriseInfoMap = enterpriseInfoManager.getEnterpriseInfoMap(null);
        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));
            }
            QfEnterpriseInfo qfEnterpriseInfo = enterpriseInfoMap.get(resp.getEnterpriseCode());
            if(null != qfEnterpriseInfo) {
                resp.setEnterpriseName(qfEnterpriseInfo.getShortName());
            }
            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;
    }

}
