package com.artfess.cqlt.manager.impl;

import com.artfess.base.enums.DelStatusEnum;
import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.util.DateUtils;
import com.artfess.cqlt.dao.QfOperationMacrMDao;
import com.artfess.cqlt.manager.QfOperationMacrDManager;
import com.artfess.cqlt.manager.QfOperationMacrMManager;
import com.artfess.cqlt.manager.QfSubjectInternationalInfoManager;
import com.artfess.cqlt.model.QfOperationMacrD;
import com.artfess.cqlt.model.QfOperationMacrM;
import com.artfess.cqlt.model.QfSubjectInternationalInfo;
import com.artfess.cqlt.vo.FaReportRespVo;
import com.artfess.cqlt.vo.FaTargetRespVo;
import com.artfess.cqlt.vo.ReportReqVo;
import com.artfess.i18n.util.I18nUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.api.client.util.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.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 运营--宏观数据填报主表 服务实现类
 *
 * @company 阿特菲斯信息技术有限公司
 * @author 黎沐华
 * @since 2023-02-21
 */
@Service
public class QfOperationMacrMManagerImpl extends BaseManagerImpl<QfOperationMacrMDao, QfOperationMacrM> implements QfOperationMacrMManager {

    @Autowired
    private QfOperationMacrDManager detailManager;

    @Autowired
    private QfSubjectInternationalInfoManager subjectInfoManager;


    private void processDetail(List<QfOperationMacrD> list, String id) {
        QueryWrapper<QfOperationMacrD> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("main_id_", id);
        detailManager.remove(queryWrapper);
        list.forEach(detail -> {
            detail.setMainId(id);
        });
        detailManager.saveBatch(list);
    }

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

        QueryWrapper<QfSubjectInternationalInfo> query = new QueryWrapper<>();
        query.eq("IS_DELE_", DelStatusEnum.N.getType());
        //获取财务相关国际科目
        query.like("type_", "OP");
        List<QfSubjectInternationalInfo> qfSubjectInternationalInfos = subjectInfoManager.getBaseMapper().selectList(query);
        Map<String, QfSubjectInternationalInfo> subjectMap = qfSubjectInternationalInfos.stream().collect(Collectors.toMap(item -> item.getName(), item -> item));

        list.forEach(detail -> {
            detail.setMainId(mainId);
            QfSubjectInternationalInfo subjectInternationalInfo = subjectMap.get(detail.getSubjectName());
            if(null == subjectInternationalInfo){
                return;
            }
            if("%".equals(detail.getSubjectUnit())) {
                detail.setFillData(detail.getFillData().multiply(new BigDecimal(100)));
            }
            detail.setSubjectCode(subjectInternationalInfo.getCode());
            detail.setSubjectNameEn(subjectInternationalInfo.getNameEn());
            if (!StringUtils.isEmpty(subjectInternationalInfo.getLevel())) {
                detail.setSubjectLevel(Integer.parseInt(subjectInternationalInfo.getLevel()));
            }
            detail.setFillDate(LocalDate.now());

        });
        boolean b = detailManager.saveBatch(list);
        return b;
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertInfo(QfOperationMacrM t) {
        QueryWrapper<QfOperationMacrM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("report_id_", t.getReportId());
        List<QfOperationMacrM> QfOperationMacrMS = this.baseMapper.selectList(queryWrapper);
        if(!CollectionUtils.isEmpty(QfOperationMacrMS)) {
            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(QfOperationMacrM t) {
        QueryWrapper<QfOperationMacrM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("report_id_", t.getReportId());
        queryWrapper.ne("id_", t.getId());
        List<QfOperationMacrM> QfOperationMacrMS = this.baseMapper.selectList(queryWrapper);
        if(!CollectionUtils.isEmpty(QfOperationMacrMS)) {
            throw new BaseException(I18nUtil.getMessage("QfOperationKpiM.repeat", LocaleContextHolder.getLocale()));
        }
        int insert = this.baseMapper.updateById(t);
        if(insert > 0){
            return true;
        }
        return false;
    }

    @Override
    public List<FaTargetRespVo> data(ReportReqVo t) {
        //获取当前指标的年季月趋势数据
        if (null == t.getYear() || t.getYear() <= 0) {
            int year = LocalDate.now().getYear();
            t.setYear(year);
        }

        if (null == t.getStartYear() || null == t.getEndYear()) {
            t.setEndYear(t.getYear());
            t.setStartYear(t.getYear() - 5);
        }
        //时间维度
        List<QfOperationMacrD> list = this.baseMapper.data(t);

        Map<String, List<QfOperationMacrD>> subjectCodeList = list.stream().collect(Collectors.groupingBy(QfOperationMacrD::getSubjectCode));
        List<FaTargetRespVo> data = Lists.newArrayList();
        List<QfOperationMacrD> newList = Lists.newArrayList();
        subjectCodeList.forEach((k,detailList)->{
            if("OP161000".equals(k) || "OP160000".equals(k)){
                newList.addAll(detailList);
                return;
            }
            FaTargetRespVo resultFa = new FaTargetRespVo();
            if(!CollectionUtils.isEmpty(detailList)) {
                resultFa.setTargetName(detailList.get(0).getSubjectName());
                resultFa.setTargetNameEn(detailList.get(0).getSubjectNameEn());
                resultFa.setTargetUnit(detailList.get(0).getSubjectUnit());
                resultFa.setTargetId(detailList.get(0).getSubjectCode());
                resultFa.setStaLat("1");
                resultFa.setType("1");
            }

            Map<Integer, List<QfOperationMacrD>> yearList = detailList.stream().collect(Collectors.groupingBy(QfOperationMacrD::getFillYear));
            List<FaReportRespVo> reportRespVos = Lists.newArrayList();
            yearList.forEach((year,v) ->{
                BigDecimal fillData = v.stream().map(QfOperationMacrD::getFillData).reduce(BigDecimal::add).get();
                FaReportRespVo faReportRespVo = new FaReportRespVo();
                faReportRespVo.setYear(year);
                faReportRespVo.setActual(fillData);

                reportRespVos.add(faReportRespVo);
                resultFa.setResultData(reportRespVos);
            });
            data.add(resultFa);

        });
        FaTargetRespVo resultFa = new FaTargetRespVo();
        resultFa.setTargetName("全球汽车生产销售数据");
        resultFa.setTargetNameEn("Global car production and sales data");
        resultFa.setTargetUnit("辆");
        resultFa.setTargetId("OP160000");
        resultFa.setStaLat("15,16");
        resultFa.setType("1");

        List<FaReportRespVo> reportRespVos = Lists.newArrayList();
        Map<Integer, List<QfOperationMacrD>> yearList = newList.stream().collect(Collectors.groupingBy(QfOperationMacrD::getFillYear));
        yearList.forEach((year,v) ->{
            FaReportRespVo faReportRespVo = new FaReportRespVo();
            faReportRespVo.setYear(year);
            v.forEach(subjectInfo->{
                String subjectCode = subjectInfo.getSubjectCode();
                if("OP160000".equals(subjectCode)) {
                    faReportRespVo.setActual(subjectInfo.getFillData());
                }
                if("OP161000".equals(subjectCode)){
                    faReportRespVo.setBudget(subjectInfo.getFillData());
                }
            });

            reportRespVos.add(faReportRespVo);
            resultFa.setResultData(reportRespVos);
        });

        data.add(resultFa);
        return data;
    }

    @Override
    public List<FaTargetRespVo> fromUnderData(ReportReqVo t) {
        Assert.hasText(t.getTargetId(), "请选择要统计的指标id");
        Map<String, QfSubjectInternationalInfo> subjectMap = subjectInfoManager.getSubjectCodeMap("OP");
        QfSubjectInternationalInfo subjectInternationalInfo = subjectMap.get(t.getTargetId());
        if(null == subjectInternationalInfo) {
            return Lists.newArrayList();
        }
        List<FaTargetRespVo> resultList = Lists.newArrayList();
        //获取当前指标的年季月趋势数据
        if (null == t.getYear() || t.getYear() <= 0) {
            int year = LocalDate.now().getYear();
            t.setYear(year);
        }

        if (null == t.getStartYear() || null == t.getEndYear()) {
            t.setEndYear(t.getYear());
            t.setStartYear(t.getYear() - 10);
        }

        if (null == t.getStartQuarter() || null == t.getEndQuarter()) {
            t.setEndQuarter(4);
            t.setStartQuarter(1);
        }

        if (null == t.getStartMonth() || null == t.getEndMonth()) {
            t.setYear(t.getQuarterYear());
            t.setEndMonth(12);
            t.setStartMonth(1);
        }

        List<QfOperationMacrD> yearData = this.baseMapper.yearData(t);
        if (!CollectionUtils.isEmpty(yearData)) {
            FaTargetRespVo resultFa = new FaTargetRespVo();

            resultFa.setTargetName(subjectInternationalInfo.getSubjectName());
            resultFa.setTargetNameEn(subjectInternationalInfo.getNameEn());
            resultFa.setTargetUnit(subjectInternationalInfo.getUnit());
            resultFa.setTargetId(subjectInternationalInfo.getSubjectCode());
            resultFa.setStaLat("1");
            resultFa.setType("2");
            List<FaReportRespVo> reportRespVos = Lists.newArrayList();
            yearData.forEach(resp ->{
                BigDecimal fillData = resp.getFillData();
                FaReportRespVo faReportRespVo = new FaReportRespVo();
                faReportRespVo.setYear(resp.getFillYear());
                faReportRespVo.setActual(fillData);

                reportRespVos.add(faReportRespVo);
            });
            resultFa.setResultData(reportRespVos);
            resultList.add(resultFa);
        }

        List<QfOperationMacrD> quarterData = this.baseMapper.quarterData(t);
        if (!CollectionUtils.isEmpty(quarterData)) {
            FaTargetRespVo resultFa = new FaTargetRespVo();
            resultFa.setTargetName(subjectInternationalInfo.getSubjectName());
            resultFa.setTargetNameEn(subjectInternationalInfo.getNameEn());
            resultFa.setTargetUnit(subjectInternationalInfo.getUnit());
            resultFa.setTargetId(subjectInternationalInfo.getSubjectCode());
            resultFa.setStaLat("1");
            resultFa.setType("3");
            List<FaReportRespVo> reportRespVos = Lists.newArrayList();
            quarterData.forEach(resp ->{
                BigDecimal fillData = resp.getFillData();
                FaReportRespVo faReportRespVo = new FaReportRespVo();
                faReportRespVo.setYear(t.getYear());
                faReportRespVo.setQuarter(resp.getFillQuarter());
                if("%".equals(resultFa.getTargetUnit())) {
                    faReportRespVo.setActual(fillData.multiply(new BigDecimal(100)));
                }else{
                    faReportRespVo.setActual(fillData);
                }

                reportRespVos.add(faReportRespVo);
            });
            resultFa.setResultData(reportRespVos);
            resultList.add(resultFa);
        }
        List<QfOperationMacrD> monthData = this.baseMapper.monthData(t);
        if (!CollectionUtils.isEmpty(monthData)) {
            FaTargetRespVo resultFa = new FaTargetRespVo();
            resultFa.setTargetName(subjectInternationalInfo.getSubjectName());
            resultFa.setTargetNameEn(subjectInternationalInfo.getNameEn());
            resultFa.setTargetUnit(subjectInternationalInfo.getUnit());
            resultFa.setTargetId(subjectInternationalInfo.getSubjectCode());
            resultFa.setStaLat("1");
            resultFa.setType("4");
            List<FaReportRespVo> reportRespVos = Lists.newArrayList();
            monthData.forEach(resp ->{
                BigDecimal fillData = resp.getFillData();
                FaReportRespVo faReportRespVo = new FaReportRespVo();
                faReportRespVo.setYear(t.getYear());
                faReportRespVo.setMonth(resp.getFillMonth());
                if("%".equals(resultFa.getTargetUnit())) {
                    faReportRespVo.setActual(fillData.multiply(new BigDecimal(100)));
                }else{
                    faReportRespVo.setActual(fillData);
                }

                reportRespVos.add(faReportRespVo);
            });
            resultFa.setResultData(reportRespVos);
            resultList.add(resultFa);
        }
        return resultList;
    }

}
