/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.watermeter.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.common.core.util.Date8Util;
import com.tofly.common.core.util.DateUtil;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.core.util.io.ExcelUtil;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.watermeter.config.ComConstans;
import com.tofly.watermeter.custom.entity.file.CbqydFile;
import com.tofly.watermeter.entity.Cbqybm;
import com.tofly.watermeter.entity.Cbqydbm;
import com.tofly.watermeter.mapper.CbqydbmMapper;
import com.tofly.watermeter.service.CbqybmService;
import com.tofly.watermeter.service.CbqydbmService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 抄表区域段编码
 *
 * @author wangjieliu
 * @date Sat May 29 00:00:00 CST 2021
 */
@Service("cbqydbmService")
public class CbqydbmServiceImpl extends ServiceImpl<CbqydbmMapper, Cbqydbm> implements CbqydbmService {

    @Autowired
    private CbqybmService cbqybmService;

    @Override
    public IPage<Map> allocationParagraph(Page page, String qybm, String qydbm) {
        return baseMapper.allocationParagraph(page, qybm, qydbm);
    }

    @Override
    public List<Integer> getPeriod() {
        return baseMapper.getPeriod();
    }

    @Override
    public Map getPlanIsCb(Long qyd) {
        return baseMapper.getPlanIsCb(qyd);
    }

    @Override
    public List<Map> getDownloadCb(Long qyd) {
        return baseMapper.getDownloadCb(qyd);
    }

    @Override
    public IPage<Map> getQydCollect(Page page , String inputcontent) {
        return baseMapper.getQydCollect(page , inputcontent);
    }

    @Override
    @SneakyThrows
    public boolean importCbqydFile(MultipartFile file) {
        if (StringUtil.isNull(file)) {
            throw new ToflyDeniedException("请上传Excel文件");
        }
        //文件流
        InputStream inputStream = file.getInputStream();
        //实体类与Excel表格式
        ExcelUtil excel = new ExcelUtil(CbqydFile.class);
        //Excel中的数据导入到实体类
        List<CbqydFile> listFileOr = excel.importExcel(inputStream);
        if (StringUtil.isNotNull(listFileOr)) {
            List<CbqydFile> listFile = new ArrayList<>();
            //去空
            for (CbqydFile cbqydFile : listFileOr) {
                if (StringUtil.isNotEmpty(cbqydFile.getQybm()) && StringUtil.isNotEmpty(cbqydFile.getQybm())){
                    listFile.add(cbqydFile);
                }
            }
            if (listFile.size() == 0){
                throw new ToflyDeniedException("请仔细填写模板");
            }
            //取出区域编码；Set过滤重复的
            Set<String> qySet = listFile.stream().map(CbqydFile::getQybm).collect(Collectors.toSet());
            //验证区域是否存在
            List<Cbqybm> cbqybmList = cbqybmService.list(Wrappers.<Cbqybm>lambdaQuery().in(Cbqybm::getQybm , qySet).select(Cbqybm::getQybm));
            //如果两者数量不对等，则存在区域编码错误情况
            if (qySet.size() != cbqybmList.size()){
                //过滤错误区域编码
                String errorQybm = qySet.stream().filter(inputQy -> cbqybmList.stream()
                        .noneMatch(queryCbqybm -> queryCbqybm.getQybm().equals(inputQy))).collect(Collectors.joining(","));
                throw new ToflyDeniedException("请仔细检查区域编码：" + errorQybm + "是否正确");
            }
            //对上传模板中的数据 抄表段分组处理，不能出现同一区域下的抄表段
            Map<String, List<CbqydFile>> groupMap = listFile.stream()
                    .collect(Collectors.groupingBy(v -> "区域："+v.getQybm() +"，抄表段："+v.getQydbmc()));
            groupMap.forEach((k, v) -> {
                //如果大于，有多个相同的抄表段
                if (v.size() > 1) {
                    throw new ToflyDeniedException("模板中存在"+k+"，重复数据");
                }
            });

            //查找数据库中是否有同一区域下，相同区域段的情况
            //根据区域分组；然后查询数据库
            // 抄表模块所有的查询，有很多个都是for循环里面对数据库的操作，因为这个模块要五天干完，完全没时间做其他的优化方案，就直接for循环操作数据库了；没办法，时间不允许
            //王海还要求这里批量，哪里批量的；哎；累
            Map<String , List<CbqydFile>> groupByQyMap = listFile.stream().collect(Collectors.groupingBy(CbqydFile::getQybm));
            groupByQyMap.forEach((k , v) -> {
                //得到区域名称集合
                if (v.size() > 0){
                    List<String> qydmcList = v.stream().map(CbqydFile::getQydbmc).collect(Collectors.toList());
                    int count = this.count(Wrappers.<Cbqydbm>lambdaQuery().eq(Cbqydbm::getQybm , k).in(Cbqydbm::getQydmc , qydmcList));
                    if (count > 0){
                        throw new ToflyDeniedException("区域编码："+ k +"中存在：" + count + "条已添加抄表段");
                    }
                }
            });
            List<Cbqydbm> cbqydbmList = new ArrayList<>();
            Long createUser = SecurityUtils.getUserId();
            Date creatTime = Date8Util.getCurrentDate();
            //用于主键
            String creatTimeStr = DateUtil.parseDateToStr("yyyyMMddHHmmssSSS" , creatTime);
//            Long maxId = this.getMaxId();
            //如果批量数据正常，则直接添加
            for (int i = 0 ; i < listFile.size() ; i++){
                Cbqydbm cbqydbm = new Cbqydbm();
                cbqydbm.setQydbm(creatTimeStr + i);
                cbqydbm.setYxbz("0");
                cbqydbm.setQydmc(listFile.get(i).getQydbmc());
                cbqydbm.setBz(listFile.get(i).getBz());
                cbqydbm.setQybm(listFile.get(i).getQybm());
                cbqydbm.setYhdqh(listFile.get(i).getYhdqh());
                cbqydbm.setCreateUser(createUser);
                cbqydbm.setCreateDate(creatTime);
                cbqydbm.setUpdateFlag("1");
                cbqydbmList.add(cbqydbm);
            }
            //这里我还是注意提出来单独批量新增的，这种很多次循环的情况，还是注意减少对数据库请求了的
            baseMapper.saveCbqyList(cbqydbmList);
        }else {
            throw new ToflyDeniedException("请仔细填写模板");
        }
        return true;
    }

    @Override
    public Long getMaxId() {
        return baseMapper.getMaxId();
    }

    @Override
    public Boolean updateSendZt(List<String> strings) {
        return this.update(new UpdateWrapper<Cbqydbm>()
                .lambda().set(Cbqydbm::getUpdateFlag, ComConstans.STR_ZERO).in(Cbqydbm::getQydbm,strings));
    }
}
