package com.artfess.cqlt.manager.impl;

import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.util.StringUtil;
import com.artfess.cqlt.dao.QfFinanceLiquidityMDao;
import com.artfess.cqlt.manager.QfEnterpriseInfoManager;
import com.artfess.cqlt.manager.QfFinanceLiquidityDetailManager;
import com.artfess.cqlt.manager.QfFinanceLiquidityMManager;
import com.artfess.cqlt.model.QfEnterpriseInfo;
import com.artfess.cqlt.model.QfFinanceLiquidityDetail;
import com.artfess.cqlt.model.QfFinanceLiquidityM;
import com.artfess.i18n.util.I18nUtil;
import com.artfess.poi.util.HeaderNode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
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.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 资金--周资金计划填报主表 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2023-03-02
 */
@Slf4j
@Service
public class QfFinanceLiquidityMManagerImpl extends BaseManagerImpl<QfFinanceLiquidityMDao, QfFinanceLiquidityM> implements QfFinanceLiquidityMManager {

    //资金池公司余额汇总
    private static final String TOTAL_ACTUAL = "Cumulative";

    //集团余额汇总
    private static final String BALANCE_SUMMARY = "SGGR";

    //集团余额警戒值
    private static final String SLR = "SLR";

    //资金池公司余额警戒值
    private static final String SGGR_SLR = "SGGR_SLR";

    @Autowired
    private QfFinanceLiquidityDetailManager liquidityDetailManager;

    @Autowired
    private QfEnterpriseInfoManager enterpriseInfoManager;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertInfo(QfFinanceLiquidityM t) {
        QueryWrapper<QfFinanceLiquidityM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("fill_week_", t.getFillWeek());
        queryWrapper.eq("report_id_", t.getReportId());
        List<QfFinanceLiquidityM> QfFinanceLiquidityMS = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(QfFinanceLiquidityMS)) {
            throw new BaseException(I18nUtil.getMessage("QfFinanceLiquidityM.repeat", LocaleContextHolder.getLocale()));
        }
        int insert = this.baseMapper.insert(t);
        if (insert > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInfo(QfFinanceLiquidityM t) {
        QueryWrapper<QfFinanceLiquidityM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("fill_week_", t.getFillWeek());
        queryWrapper.eq("report_id_", t.getReportId());
        queryWrapper.ne("id_", t.getId());
        List<QfFinanceLiquidityM> QfFinanceLiquidityMS = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(QfFinanceLiquidityMS)) {
            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(QfFinanceLiquidityM t) {
        QfFinanceLiquidityM QfFinanceLiquidityM = baseMapper.selectById(t.getId());
        if (null == QfFinanceLiquidityM) {
            return false;
        }
        QfFinanceLiquidityM.setStatus(QfFinanceLiquidityM.getStatus() == 0 ? 1 : 0);
        int i = this.baseMapper.updateById(QfFinanceLiquidityM);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importExcel(List<HeaderNode> list, String mainId) {
        if (CollectionUtils.isEmpty(list)) {
            return false;
        }
        QfFinanceLiquidityM mainInfo = this.baseMapper.selectById(mainId);
        Assert.notNull(mainInfo, I18nUtil.getMessage("filldata.notExist", LocaleContextHolder.getLocale()));
        Assert.isTrue(!"1".equals(mainInfo.getStatus()),  I18nUtil.getMessage("data_operate", LocaleContextHolder.getLocale()));
        this.removeInfo(mainId);

        //获取境外企业
        Map<String, QfEnterpriseInfo> enterpriseInfoMap = enterpriseInfoManager.getEnterpriseInfoMap(null);
        //获取表头
        List<HeaderNode> headerNodeList = list.stream().collect(Collectors.groupingBy(HeaderNode::getRow)).get(0);
        Map<Integer, String> headerMap = Maps.newHashMap();
        for (HeaderNode headerNode : headerNodeList) {
            headerMap.put(headerNode.getColumn(), headerNode.getHeaderName());
        }

        //获取境外企业、资金池公司余额汇总、资金池公司余额警戒值、集团余额汇总、集团余额警戒值所在列
        Map<Integer, List<HeaderNode>> detailMap = list.stream().collect(Collectors.groupingBy(HeaderNode::getColumn));
        List<HeaderNode> periodList = detailMap.get(1);
        Map<Integer, String> periodMap = Maps.newHashMap();
        Map<Integer, String> dataTypeMap = Maps.newHashMap();
        Map<Integer, String> slrMap = Maps.newHashMap();
        for (HeaderNode headerNode : periodList) {
            periodMap.put(headerNode.getRow(), headerNode.getHeaderName());
        }
        periodList = detailMap.get(0);
        for (HeaderNode headerNode : periodList) {
            if (!StringUtils.isEmpty(headerNode.getHeaderName())) {
                dataTypeMap.put(headerNode.getRow(), headerNode.getHeaderName());
            }
        }

        periodList = detailMap.get(2);
        for (HeaderNode headerNode : periodList) {
            if (!StringUtils.isEmpty(headerNode.getHeaderName()) && headerNode.getHeaderName().contains("SLR")) {
                slrMap.put(headerNode.getRow(), headerNode.getHeaderName());
            }
        }

        LocalDate localDate = LocalDate.of(mainInfo.getFillYear(), 1, 1);
        Integer fillWeek = mainInfo.getFillWeek();

        List<QfFinanceLiquidityDetail> actualList = Lists.newArrayList();
        for (Map.Entry<Integer, List<HeaderNode>> entry : detailMap.entrySet()) {
            Integer column = entry.getKey();
            List<HeaderNode> nodes = entry.getValue();
            //获取企业编码
            for (HeaderNode node : nodes) {
                if (0 == node.getRow()) {
                    continue;
                }

                if (1 == node.getColumn() || 0 == node.getColumn()) {
                    continue;
                }

                Integer week = fillWeek + column - 2;
                String period = periodMap.get(node.getRow());

                QfFinanceLiquidityDetail detail = new QfFinanceLiquidityDetail();
                detail.setMainId(mainInfo.getId());
                detail.setFillYear(mainInfo.getFillYear());
                detail.setFillDate(mainInfo.getFillDate());
                detail.setFillWeek(week);
                detail.setSn(node.getRow());
                LocalDate startTime = localDate.with(TemporalAdjusters.dayOfWeekInMonth(week - 1, DayOfWeek.SATURDAY));
                LocalDate endTime = localDate.with(TemporalAdjusters.dayOfWeekInMonth(week, DayOfWeek.FRIDAY));
                detail.setFillStartDate(startTime);
                detail.setFillEndDate(endTime);
                if (week.equals(mainInfo.getFillWeek())) {
                    detail.setFillType(1);
                } else {
                    detail.setFillType(2);
                }
                createDetail(enterpriseInfoMap, dataTypeMap, actualList, slrMap, node, period, detail);
            }
        }

        liquidityDetailManager.saveBatch(actualList);
        return true;
    }

    private void createDetail(Map<String, QfEnterpriseInfo> enterpriseInfoMap,
                              Map<Integer, String> dataTypeMap,
                              List<QfFinanceLiquidityDetail> actualList,
                              Map<Integer, String> slrMap,
                              HeaderNode node,
                              String period,
                              QfFinanceLiquidityDetail detail) {
        //处理企业
        if (enterpriseInfoMap.containsKey(period)) {
            QfEnterpriseInfo qfEnterpriseInfo = enterpriseInfoMap.get(period);
            detail.setEnterpriseCode(qfEnterpriseInfo.getCode());
            detail.setEnterpriseName(qfEnterpriseInfo.getName());
            detail.setEnterpriseNameEn(qfEnterpriseInfo.getNameEn());
        } else if (StringUtil.isNotEmpty(period)) {
            detail.setEnterpriseCode(period);
        } else {
            detail.setEnterpriseCode(slrMap.get(node.getRow()));
        }

        if (dataTypeMap.containsKey(node.getRow()) && !StringUtils.isEmpty(dataTypeMap.get(node.getRow()))) {
            detail.setDataType(Integer.parseInt(dataTypeMap.get(node.getRow())));
        }

        Integer[] dateTypes = new Integer[]{3, 6, 9, 11, 13};
        if (1 == detail.getFillType() && Arrays.asList(dateTypes).contains(detail.getDataType())) {
            detail.setEnterpriseCode(slrMap.get(node.getRow()));
        } else {
            //获取企业周资金实际数据
            if (!StringUtils.isEmpty(node.getHeaderName()) && !"-".equals(node.getHeaderName())) {
                detail.setFillData(new BigDecimal(node.getHeaderName()));
            }
        }

        actualList.add(detail);

    }


    private void removeInfo(String mainId) {
        QueryWrapper<QfFinanceLiquidityDetail> actualQuery = new QueryWrapper<>();
        actualQuery.eq("main_id_", mainId);
        liquidityDetailManager.remove(actualQuery);
    }


}
