package com.tofly.watermeter.custom.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.custom.entity.CustomSbYjgl;
import com.tofly.watermeter.custom.entity.SearchSb;
import com.tofly.watermeter.custom.entity.file.TurnoverFileInfo;
import com.tofly.watermeter.custom.service.SbManagerService;
import com.tofly.watermeter.entity.*;
import com.tofly.watermeter.service.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

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


/**
 * @author by Wangjieliu
 * @date 2021/3/17.
 */
@Service
@AllArgsConstructor
public class SbManagerServiceImpl implements SbManagerService {

    private final BwrksbdatailService sbDetailService;
    private final BwhbdatailService hbDtailService;
    private final BwsbyjglService yjglService;
    private final BwrktotalService totalService;
    private final BwrkdetailService bwrkdetailService;
    private final BwcjblService bwcjblService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateExchange(Bwhbdatail bwhbdatail) {
        Long jbzd = bwhbdatail.getBwJbzd();
        //TODO
//        Long sblx = bwhbdatail.getBwXblx();
//        Long sbcj = bwhbdatail.getBwXbcj();
//        Long sbkj = bwhbdatail.getBwXbkj();
        Long sbqd = bwhbdatail.getBwXbqd();
//        Long hbry = bwhbdatail.getBwHbry();
        Date hbrq = bwhbdatail.getBwHbrq();
        //更换的新表编号
        String updateXbbh = bwhbdatail.getBwXbbh();
        //查询没改新表编号之前的新表编号
        String beforeSbbh = hbDtailService.getOne(Wrappers.<Bwhbdatail>lambdaQuery().eq(Bwhbdatail::getId, bwhbdatail.getId()).select(Bwhbdatail::getBwXbbh)).getBwXbbh();
//        String updatePrefix = prefix(updateXbbh);
//        Long updateNum = num(updateXbbh);

        //如果不一致，则表示需要修改表编号
        if (!beforeSbbh.equals(updateXbbh)) {
            //先查询错误新表水表编号信息
            String xbbh = hbDtailService.getOne(Wrappers.<Bwhbdatail>lambdaQuery().eq(Bwhbdatail::getId, bwhbdatail.getId()).select(Bwhbdatail::getBwXbbh)).getBwXbbh();
            //错误表前缀、编号
//            String prefix = prefix(xbbh);
//            Long num = num(xbbh);
            //查询错误新表安装的信息
            Bwrksbdatail info = sbDetailService.getOne(Wrappers.<Bwrksbdatail>lambdaQuery().eq(Bwrksbdatail::getBwSbbh, xbbh)
                    .select(Bwrksbdatail::getBwKhbh, Bwrksbdatail::getBwKhxm,
                            Bwrksbdatail::getBwKhdz, Bwrksbdatail::getBwKhdh,
                            Bwrksbdatail::getBwGspq, Bwrksbdatail::getBwSbqd,
                            Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSbkj,
                            Bwrksbdatail::getBwSblx, Bwrksbdatail::getBwAzrq, Bwrksbdatail::getBwAzry));
            //修改需要更换的新表安装信息
            sbDetailService.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .eq(Bwrksbdatail::getBwSbbh, updateXbbh)
                    .set(Bwrksbdatail::getBwKhbh, info.getBwKhbh()).set(Bwrksbdatail::getBwKhxm, info.getBwKhxm())
                    .set(Bwrksbdatail::getBwKhdz, info.getBwKhdz()) //.set(Bwrksbdatail::getBwGspq, jbInfo.getBwGspq())
                    .set(Bwrksbdatail::getBwKhdh, info.getBwKhdh()).set(Bwrksbdatail::getBwSbqd, 0)
                    .set(Bwrksbdatail::getBwAzry, info.getBwAzry()).set(Bwrksbdatail::getBwAzrq, info.getBwAzrq())
                    .set(Bwrksbdatail::getBwSbzt, "57"));
            //错误表设置为未安装状态
            sbDetailService.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .eq(Bwrksbdatail::getBwSbbh, xbbh)
                    .set(Bwrksbdatail::getBwKhbh, "").set(Bwrksbdatail::getBwKhxm, "")
                    .set(Bwrksbdatail::getBwKhdh, "").set(Bwrksbdatail::getBwKhdz, "")
                    .set(Bwrksbdatail::getBwGspq, "").set(Bwrksbdatail::getBwAzry, "")
                    .set(Bwrksbdatail::getBwAzrq, ""));//.set(Bwrksbdatail::getCreateDate, null)


            //如果修改了表编号，则还需要修改第三方客户信息中的水表信息


        }
        //TODO
        //只修改新表水表类型、厂家、口径、换表人员，日期等信息
//        sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
//                .eq(Bwrksbdatail::getBwSbbh, updateXbbh)
//                .set(StringUtil.isNotNull(sblx), Bwrksbdatail::getBwSblx, sblx).set(StringUtil.isNotNull(sbcj), Bwrksbdatail::getBwSbcj, sbcj)
//                .set(StringUtil.isNotNull(sbkj), Bwrksbdatail::getBwSbkj, sbkj).set(StringUtil.isNotNull(hbrq), Bwrksbdatail::getBwAzrq, hbrq)
//                .set(StringUtil.isNotNull(hbry), Bwrksbdatail::getBwAzry, hbry));
//        //修改换表数据表 旧表止度。新表起度 换表日期、人员 数据
//        hbDtailService.update(Wrappers.<Bwhbdatail>lambdaUpdate().eq(Bwhbdatail::getId, bwhbdatail.getId())
//                .set(StringUtil.isNotNull(sbqd), Bwhbdatail::getBwXbqd, sbqd)
//                .set(StringUtil.isNotNull(jbzd), Bwhbdatail::getBwJbzd, jbzd)
//                .set(StringUtil.isNotNull(hbrq), Bwhbdatail::getBwHbrq, hbrq)
//                .set(StringUtil.isNotNull(hbry), Bwhbdatail::getBwHbry, hbry)
//                .set(!beforeSbbh.equals(updateXbbh), Bwhbdatail::getBwXbbh, updateXbbh));


        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteExchange(Long id) {
        //查询新表编号
        Bwhbdatail bwhbdatail = hbDtailService.getOne(Wrappers.<Bwhbdatail>lambdaQuery().eq(Bwhbdatail::getId, id)
                .select(Bwhbdatail::getBwXbbh, Bwhbdatail::getBwJbbh));
        String sbbh = bwhbdatail.getBwXbbh();

        //修改水表为未安装状态
        sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
                .eq(Bwrksbdatail::getBwSbbh, sbbh).set(Bwrksbdatail::getBwSbzt, "56")
                .set(Bwrksbdatail::getBwKhbh, "").set(Bwrksbdatail::getBwKhxm, "")
                .set(Bwrksbdatail::getBwKhdh, "").set(Bwrksbdatail::getBwKhdz, "")
                .set(Bwrksbdatail::getBwGspq, "").set(Bwrksbdatail::getBwAzry, "")
                .set(Bwrksbdatail::getBwAzrq, ""));

        //修改第三方客户信息中的水表数据； 修改为旧表的数据信息，但是第三方暂未提供接口


        //删除水表换表信息
        return hbDtailService.removeById(id);
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public boolean turnover(CustomSbYjgl bwsbyjgl) {
//        String prefix = bwsbyjgl.getSbqz();
//
//        //由于存在外面的表没有在系统中的，然后故障移交的状态，所以可能没有前缀
////        if (StringUtil.isEmpty(prefix)) {
////            throw new ToflyDeniedException("请正确输入水表前缀信息");
////        }
//
////        bwsbyjgl.getBwBhqh();
////        Long yjlx = bwsbyjgl.getBwYjlx();
//        int state = bwsbyjgl.getFlag();
//        //移交人员目前是当前操作系统的人员
//        bwsbyjgl.setBwYjry(SecurityUtils.getUserId());
////        Long gdId=bwsbyjgl.getGdId();
//        //新表移交涉及多个连号水表移交
//        if (state == 1) {
//            //起号、止号
//            Long qh = bwsbyjgl.getBwBhqh();
//            Long zh = bwsbyjgl.getBwBhzh();
//            //判断一下，如果只有起号，证明只有一个新表移交
//            if (StringUtil.isNull(zh)) {
//                zh = qh;
//            }
//            Long number = zh - qh + 1;//数量
//            //判断一下起号到止号范围内，有没有出现安装的水表
//            List<Bwrksbdatail> sbList = sbDetailService.list(Wrappers.<Bwrksbdatail>lambdaQuery()
//                    .eq(Bwrksbdatail::getBwBhqz, prefix).le(Bwrksbdatail::getRkid, zh).ge(Bwrksbdatail::getRkid, qh)
//                    .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwBhqz, Bwrksbdatail::getBwSbzt));
//            //如果没有查到该水表数据，则提示
//            if (StringUtil.isNull(sbList) || sbList.size() == 0) {
//                throw new ToflyDeniedException("请正确输入水表信息");
//            }
//
//
//            //过滤得到已安装的水表
//            List<String> sbZt = sbList.stream().filter(k -> "57".equals(k.getBwSbzt())).map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
//            if (StringUtil.isNotNull(sbZt) && sbZt.size() > 0) {
//                StringBuilder sbbh = new StringBuilder("");
//                sbZt.forEach(k -> {
//                    sbbh.append(k + ",");
//                });
//                throw new ToflyDeniedException("水表编号为：" + sbbh.substring(0, sbbh.length() - 1) + "的水表在工作状态，不能移交入库");
//            }
//
//            //新表入库则还是为最初的入库状态，水表虽然出库了一次，但是最终没有使用，回到了原来的库，所以还是入库状态
//            //修改水表状态
//            boolean flag = sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
//                    .eq(Bwrksbdatail::getBwBhqz, prefix).le(Bwrksbdatail::getRkid, zh)
//                    .ge(Bwrksbdatail::getRkid, qh).set(Bwrksbdatail::getBwSbzt, "62"));//退库状态
//            if (flag) {
//                //由于新表回来录入是同一批同一批入进来的，所以厂家、类型、口径这些只要知道其中一个就可以
//                Bwrksbdatail bwrksbdatail = sbDetailService.getOne(Wrappers.<Bwrksbdatail>lambdaQuery().eq(Bwrksbdatail::getBwSbbh, prefix + qh)
//                        .select(Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSblx, Bwrksbdatail::getBwSbkj));
//
//                //先查询库存中的记录
//                Bwrktotal totalList = totalService.getOne(Wrappers.<Bwrktotal>lambdaQuery()
//                        .eq(Bwrktotal::getBwSblx, bwrksbdatail.getBwSblx()).eq(Bwrktotal::getBwSbkj, bwrksbdatail.getBwSbkj()).eq(Bwrktotal::getBwSbcj, bwrksbdatail.getBwSbcj())
//                        .select(Bwrktotal::getBwKcsl, Bwrktotal::getBwSysl, Bwrktotal::getBwKczs, Bwrktotal::getId));
////                只有使用数量大于移交数量才可以移交，为了避免水表没有出库就移交入库的情况
//                if (totalList.getBwSysl() < number) {
//                    throw new ToflyDeniedException("输入的水表信息暂无法移交，可能由于水表数目不统一");
//                }
//                //修改库存数量直接对一条数据修改，因为后期计算都是同一计算的，无法对所有库存记录修改，只能对其中一条修改库存数据，即使修改后这条数据为负数，但是最后的库存数量是所有口径、类型相同的库存计算结果
//                totalService.update(Wrappers.<Bwrktotal>lambdaUpdate().eq(Bwrktotal::getId, totalList.getId())
//                        .set(Bwrktotal::getBwKcsl, totalList.getBwKcsl() + number).set(Bwrktotal::getBwSysl, totalList.getBwSysl() - number));
//                bwsbyjgl.setBwYjsl(number);
//                //起号编号设置
//                bwsbyjgl.setSbzsbh(prefix + qh);
//                //移交人员目前是当前操作系统的人员
//                bwsbyjgl.setBwYjry(SecurityUtils.getUserId());
//
//                yjglService.save(bwsbyjgl);
//            }//||(bwsbyjgl.getBwYjlx()).equals(51)
//        } else if (state == 2) {//旧表移交
//            //查询该水表是否是安装工作状态
//            Bwrksbdatail sbZt = sbDetailService.getOne(Wrappers.<Bwrksbdatail>lambdaQuery()
//                    .eq(Bwrksbdatail::getBwSbbh, prefix + bwsbyjgl.getBwBhqh()).select(Bwrksbdatail::getBwSbzt));
//
//            if (StringUtil.isNotNull(sbZt)) {
//                if ("57".equals(sbZt.getBwSbzt())) {
//                    throw new ToflyDeniedException("该水表为工作状态，无法直接移交入库");
////                throw new ToflyDeniedException("请按照水表移交顺序流程进行移交");
//                }//根据水表编号修改水表状态
//                sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate().eq(Bwrksbdatail::getBwSbbh, prefix + bwsbyjgl.getBwBhqh())
//                        .set(Bwrksbdatail::getBwSbzt, "61"));//状态为旧表报废
//                //旧表移交只能一个一个的移交
//                bwsbyjgl.setBwYjsl(1L);
//                //水表编号
//                bwsbyjgl.setSbzsbh(prefix + bwsbyjgl.getBwBhqh());
//                //是否检查
//                bwsbyjgl.setCheckFlag("0");
//                yjglService.save(bwsbyjgl);
//            } else {
//                //如果数据库中没有该水表，则该水表是外来的，从来没有入过表务系统登记的
//                bwsbyjgl.setBwYjsl(1L);
//                //水表编号
//                bwsbyjgl.setSbzsbh(prefix + bwsbyjgl.getBwBhqh());
//                bwsbyjgl.setCheckFlag("0");
//                yjglService.save(bwsbyjgl);
//            }
//
//
//        } else {
//            throw new ToflyDeniedException("请正确填写水表移交类型");
//        }
//        return true;
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean turnoverTwo(CustomSbYjgl bwsbyjgl) {

        String sbbhS = bwsbyjgl.getSbbhList().trim();
        Long cj = bwsbyjgl.getBwSbcj();
        Long lx = bwsbyjgl.getBwSblx();
        Long kj = bwsbyjgl.getBwSbkj();
        Long yjlx = bwsbyjgl.getBwYjlx();
        Long deptId = bwsbyjgl.getBwJsbm();
        Long jrUser = bwsbyjgl.getBwJsry();
        Date yjTime = bwsbyjgl.getBwYjrq();
        int state = bwsbyjgl.getFlag();

        if (StringUtil.isEmpty(sbbhS)) {
            throw new ToflyDeniedException("请传入水表编号");
        }
        List<String> sbbhList = Arrays.asList(sbbhS.split(","));
        if (sbbhList.size() > 1000) {
            throw new ToflyDeniedException("最多移交1000支水表");
        }
        Long number = Long.valueOf(sbbhList.size());
        //判断移交水表中有没有出现安装的水表
        List<Bwrksbdatail> sbList = sbDetailService.list(Wrappers.<Bwrksbdatail>lambdaQuery().in(Bwrksbdatail::getBwSbbh, sbbhList)
                .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwBhqz, Bwrksbdatail::getBwSbzt));
        //如果没有查到该水表数据，则提示
        if (StringUtil.isNull(sbList) || sbList.size() == 0) {
            throw new ToflyDeniedException("请正确输入水表信息");
        }
        //过滤得到已安装的水表
        List<String> sbZt = sbList.stream().filter(k -> "57".equals(k.getBwSbzt())).map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
        if (sbZt.size() > 0) {
            StringBuilder sbbh = new StringBuilder("");
            sbZt.forEach(k -> {
                sbbh.append(k + ",");
            });
            throw new ToflyDeniedException("水表编号为：" + sbbh.substring(0, sbbh.length() - 1) + "的水表在工作状态，不能移交");
        }
        //移交数量
        bwsbyjgl.setBwYjsl(number);
        //水表编号
        bwsbyjgl.setSbzsbh(sbbhS);
        //新表移交涉及多个连号水表移交
        if (state == 1) {
            //新表移交入库，状态是 退库状态
            //修改水表状态//退库状态
            sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .in(Bwrksbdatail::getBwSbbh, sbbhList).set(Bwrksbdatail::getBwSbzt, "62"));
            //根据 厂家、类型、口径 查询库存中的记录
            Bwrktotal totalList = totalService.getOne(Wrappers.<Bwrktotal>lambdaQuery()
                    .eq(Bwrktotal::getBwSblx, lx).eq(Bwrktotal::getBwSbkj, kj).eq(Bwrktotal::getBwSbcj, cj)
                    .select(Bwrktotal::getBwKcsl, Bwrktotal::getBwSysl, Bwrktotal::getBwKczs, Bwrktotal::getId));
//                只有使用数量大于移交数量才可以移交，为了避免水表没有出库就移交入库的情况
            if (totalList.getBwSysl() < number) {
                throw new ToflyDeniedException("移交数目与库存数目不对应");
            }
            //修改移交过后的库存数量
            totalService.update(Wrappers.<Bwrktotal>lambdaUpdate().eq(Bwrktotal::getId, totalList.getId())
                    .set(Bwrktotal::getBwKcsl, totalList.getBwKcsl() + number).set(Bwrktotal::getBwSysl, totalList.getBwSysl() - number));
            //移交人员目前是当前操作系统的人员
            bwsbyjgl.setBwYjry(SecurityUtils.getUserId());
            yjglService.save(bwsbyjgl);
        }
        //旧表移交
        else if (state == 2) {
            //旧表只能单个移交
            String sbbh = sbbhList.get(0);
            Bwrksbdatail bwrksbdatail = sbDetailService.getOne(Wrappers.<Bwrksbdatail>lambdaQuery().eq(Bwrksbdatail::getBwSbbh, sbbh)
                    .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwSbzt));
            //如果根据移交水表编号查询出来有结果数据，则代表是系统库中的水表，系统库中的水表只能旧表移交一次，之后就报废了
            if (StringUtil.isNotNull(bwrksbdatail)) {
                String sbzt = bwrksbdatail.getBwSbzt();
                if ("61".equals(sbzt)) {
                    throw new ToflyDeniedException("水表：" + sbbh + "已经移交，不能重复移交");
                }
            }
            //状态为旧表报废
            sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .in(Bwrksbdatail::getBwSbbh, sbbhList).set(Bwrksbdatail::getBwSbzt, "61"));
            //是否检查
            bwsbyjgl.setCheckFlag("0");
            yjglService.save(bwsbyjgl);
        } else {
            throw new ToflyDeniedException("请正确填写水表移交类型");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean turnoverThree(CustomSbYjgl bwsbyjgl, MultipartFile file) {
        String sbbhS = bwsbyjgl.getSbbhList().trim();
        String lsbh = DateUtil.parseDateToStr("yyyyMMddHHmmss", Date8Util.getCurrentDate());
        bwsbyjgl.setBwLsbh(lsbh);
        bwsbyjgl.setCreateUser(SecurityUtils.getUserId());
        bwsbyjgl.setCreateDate(Date8Util.getCurrentDate());
        if (StringUtil.isEmpty(sbbhS)) {
            throw new ToflyDeniedException("请传入水表编号");
        }
        List<String> sbbhList = Arrays.asList(sbbhS.split(","));
        if (sbbhList.size() > 1000) {
            throw new ToflyDeniedException("最多移交1000支水表");
        }
        //判断移交水表中有没有出现安装的水表
        List<Bwrksbdatail> sbList = sbDetailService.list(Wrappers.<Bwrksbdatail>lambdaQuery().in(Bwrksbdatail::getBwSbbh, sbbhList)
                .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwBhqz, Bwrksbdatail::getBwSbzt,
                        Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSbkj, Bwrksbdatail::getBwSblx));
        //旧表移交
        //过滤得到已移交报废的水表
        List<String> sbZt1 = sbList.stream().filter(k -> !"630".equals(k.getBwSbzt())).map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
        if (sbZt1.size() > 0) {
            String sbbh = StringUtil.join(sbZt1, ",");
            throw new ToflyDeniedException("水表：" + sbbh.substring(0, sbbh.length() - 1) + "不能移交；请规范操作");
        }
        //如果传递的水表与查询出来的水表个数不一致；则表示有户外表的情况
        if (!(sbbhList.size() == sbList.size())) {
            //过滤不在本套系统中的水表
            List<String> filterSbList = sbbhList.stream()
                    .filter(inputSb -> !sbList.stream().anyMatch(querySb -> Objects.equals(inputSb, querySb.getBwSbbh()))).collect(Collectors.toList());
            //还可能存在户外表的情况：本系统验证其他系统的水表，
//                List<Qfkhjbxx> qfkhjbxxList = qfkhjbxxService.list(Wrappers.<Qfkhjbxx>lambdaQuery().in(Qfkhjbxx::getSbbh , filterSbList)
//                        .select(Qfkhjbxx::getSbbh , Qfkhjbxx::getSbcj , Qfkhjbxx::getSbkj , Qfkhjbxx::getSblx));
            //由于户外表肯定是要走换表下来的；户外表信息只有在换表里面才保存了本身厂家、口径、类型信息；所以只能走换表里面拿；如果走客户档案表里面获取；是不能得到数据的；因为移交是换下来的水表；客户档案在换表的时候水表信息已经变了
            List<Bwhbdatail> bwhbdatailList = hbDtailService.list(Wrappers.<Bwhbdatail>lambdaQuery()
                    .in(Bwhbdatail::getBwJbbh, filterSbList)
                    .select(Bwhbdatail::getBwJbbh, Bwhbdatail::getBwJbcj, Bwhbdatail::getBwJbkj, Bwhbdatail::getBwJblx));
            //如果查询到有户外表的情况；则将户外表add到sbList里面；然后再移交
            if (StringUtil.isNotNull(bwhbdatailList)) {
                Map<String, Bwhbdatail> map = bwhbdatailList.stream().collect(Collectors.toMap(Bwhbdatail::getBwJbbh, m -> m, (k1, k2) -> k1));
                map.forEach((k, v) -> {
                    Bwrksbdatail bwrksbdatail = new Bwrksbdatail();
                    bwrksbdatail.setBwSbbh(v.getBwJbbh());
                    //TODO
//                    bwrksbdatail.setBwSbkj(v.getBwJbkj());
//                    bwrksbdatail.setBwSblx(v.getBwJblx());
//                    bwrksbdatail.setBwSbcj(v.getBwJbcj());
                    sbList.add(bwrksbdatail);
                });
            }
        }
        //再次比较，判断是否有输错水表的情况
        if (!(sbbhList.size() == sbList.size())) {
//            sbList.stream().map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
            //过滤出具体哪些水表输错的情况
            String errorSbbh = sbbhList.stream().filter(inputSb -> sbList.stream().noneMatch(querySb -> Objects.equals(inputSb, querySb.getBwSbbh())))
                    .collect(Collectors.joining(","));
            throw new ToflyDeniedException("以下水表编号错误，请仔细检查：" + errorSbbh);
        }
        //状态为旧表报废
        sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
                .in(Bwrksbdatail::getBwSbbh, sbbhList).set(Bwrksbdatail::getBwSbzt, "61"));
        //查看水表抽检比例
        List<Bwcjbl> bwcjblList = bwcjblService.list(Wrappers.<Bwcjbl>lambdaQuery().select(Bwcjbl::getBwSbkj, Bwcjbl::getBwHgsl));
        Map<Long, Integer> cjblMap = bwcjblList.stream().collect(Collectors.toMap(Bwcjbl::getBwSbkj, Bwcjbl::getBwHgsl));
        //对本批次移交水表进行口径分组，根据抽检比例计算抽检数量；然后标识具体哪些水表需要进行抽检
        Map<Long, List<Bwrksbdatail>> sbkjMap = sbList.stream().collect(Collectors.groupingBy(Bwrksbdatail::getBwSbkj));
        //存放最后需要移交的水表信息
        List<Bwrksbdatail> sbyjList = new ArrayList<>();
        sbkjMap.forEach((k, v) -> {
            if (cjblMap.containsKey(k)) {
                //对应口径下的水表移交个数
                int kjYjsize = v.size();
                //根据抽检比例计算抽检数量
                Integer ratio = cjblMap.get(k);
                //抽检个数
                int ratioNum = kjYjsize * ratio / 100;
                //如果不满足1个的时候，则强行修改为1个
                if (ratioNum == 0) {
                    ratioNum = 1;
                }
                //根据抽检个数 修改需要抽检的
                for (int i = 0; i < ratioNum; i++) {
                    v.get(i).setCheckFlag("0");
                }
            }
            sbyjList.addAll(v);
        });
        //得到最大ID
        Long maxId = bwrkdetailService.getMaxId("TF_YWPN_BWSBYJGL_W");
        //设置批量新增的ID
        for (int i = 0; i < sbyjList.size(); i++) {
            sbyjList.get(i).setId(maxId + i);
        }
//        yjglService.insertBatch(sbyjList, bwsbyjgl);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean turnoverFive(CustomSbYjgl bwsbyjgl, MultipartFile file) {
        String lsbh = DateUtil.parseDateToStr("yyyyMMddHHmmss", Date8Util.getCurrentDate());
        bwsbyjgl.setBwLsbh(lsbh);
        bwsbyjgl.setCreateUser(SecurityUtils.getUserId());
        bwsbyjgl.setCreateDate(Date8Util.getCurrentDate());
        //处理Excel文件里面移交数据
        List<TurnoverFileInfo> turnoverFileInfoList = disposeTurnoverFile(file);
        //对处理过后的移交数据进行分组；按照移交选项 1：正常移交；2：无表号移交；3：表号重复移交
//        Map<String, List<TurnoverFileInfo>> groupYjxxMap = turnoverFileInfoList.stream().collect(Collectors.groupingBy(TurnoverFileInfo::getYjxx));
        
        List<Bwhbdatail> yjInfoList = hbDtailService.getYjInfo(turnoverFileInfoList);
        //如果两个数据不匹配
        if (yjInfoList.size() != turnoverFileInfoList.size()) {
            String errorSbbh = turnoverFileInfoList.stream().map(TurnoverFileInfo::getYhbh).filter(turnoverFileInfo ->
                    yjInfoList.stream().noneMatch(querySb -> Objects.equals(turnoverFileInfo, querySb.getBwKhbh())))
                    .collect(Collectors.joining(","));
            throw new ToflyDeniedException("以下用户编号，不符合移交流程，请仔细检查:" + errorSbbh);
        }
        if (yjInfoList.size() > 0) {
            Map<String, Bwhbdatail> hbdatailMap = yjInfoList.stream().collect(Collectors.toMap(Bwhbdatail::getBwKhbh, k1 -> k1));
            turnoverFileInfoList.forEach(v -> {
                //设置水表口径、类型、厂家等信息
                Bwhbdatail bwhbdatail = hbdatailMap.get(v.getYhbh());
                if (StringUtil.isNotNull(bwhbdatail)) {
                    //TODO
//                    v.setBwSbkj(bwhbdatail.getBwJbkj());
//                    v.setBwSblx(bwhbdatail.getBwJblx());
//                    v.setBwSbcj(bwhbdatail.getBwJbcj());
                }
            });
        } else {
            throw new ToflyDeniedException("请正确填写数据");
        }
        //查看水表抽检比例
        List<Bwcjbl> bwcjblList = bwcjblService.list(Wrappers.<Bwcjbl>lambdaQuery().select(Bwcjbl::getBwSbkj, Bwcjbl::getBwHgsl));
        Map<Long, Integer> cjblMap = bwcjblList.stream().collect(Collectors.toMap(Bwcjbl::getBwSbkj, Bwcjbl::getBwHgsl));
        //对本批次移交水表进行口径分组，根据抽检比例计算抽检数量；然后标识具体哪些水表需要进行抽检
        Map<Long, List<TurnoverFileInfo>> sbkjMap = turnoverFileInfoList.stream().collect(Collectors.groupingBy(TurnoverFileInfo::getBwSbkj));
        //存放最后需要移交的水表信息
        List<TurnoverFileInfo> sbyjList = new ArrayList<>();
        sbkjMap.forEach((k, v) -> {
            if (cjblMap.containsKey(k)) {
                //对应口径下的水表移交个数
                int kjYjsize = v.size();
                //根据抽检比例计算抽检数量
                Integer ratio = cjblMap.get(k);
                //抽检个数
                int ratioNum = kjYjsize * ratio / 100;
                //如果不满足1个的时候，则强行修改为1个
                if (ratioNum == 0) {
                    ratioNum = 1;
                }
                //根据抽检个数 修改需要抽检的
                for (int i = 0; i < ratioNum; i++) {
                    v.get(i).setCheckFlag("0");
                }
            }
            sbyjList.addAll(v);
        });
        //得到最大ID
        Long maxId = bwrkdetailService.getMaxId("TF_YWPN_BWSBYJGL_W");
        //设置批量新增的ID
        for (int i = 0; i < sbyjList.size(); i++) {
            sbyjList.get(i).setId(maxId + i);
        }
        yjglService.insertBatch(sbyjList, bwsbyjgl);
        return true;
    }

    /**
     * 处理Excel中的移交表数据
     *
     * @param file 移交文件
     * @return 返回处理后的数据
     */
    private List<TurnoverFileInfo> disposeTurnoverFile(MultipartFile file) {
        //水表移交判断Excel表中是否有重复移交等数据
        if (StringUtil.isNull(file)) {
            throw new ToflyDeniedException("请上传Excel文件");
        }
        //文件流
        InputStream inputStream = null;
        List<TurnoverFileInfo> listFile = null;
        try {
            inputStream = file.getInputStream();
            //实体类与Excel表格式
            ExcelUtil excel = new ExcelUtil(TurnoverFileInfo.class);
            //Excel中的数据导入到实体类
            listFile = excel.importExcel(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //看Excel表中移交的是否有重复表情况
        Map<String, List<TurnoverFileInfo>> groupSbbhMap = listFile.stream().collect(Collectors.groupingBy(TurnoverFileInfo::getSbbh));
        //存放最终整理数据后需要移交的水表集合数据
        List<TurnoverFileInfo> turnoverFileInfoList = new ArrayList<>();
        //判断分组过后
        groupSbbhMap.forEach((k, v) -> {
            //无表号情况 ，则不会判断重复表
            if (StringUtil.isEmpty(k)) {
                v.forEach(list -> {
                    if (StringUtil.isEmpty(list.getYjsm())) {
                        throw new ToflyDeniedException("存在无表号移交，请仔细填写移交说明");
                    }
                    //重复表设置移交选项
                    list.setYjxx("2");
                });
                //如果在无表号的情况下，有相同客户编号；请重新填写
                Map<String, List<TurnoverFileInfo>> groupYhbhMap = v.stream().collect(Collectors.groupingBy(TurnoverFileInfo::getYhbh));
                groupYhbhMap.forEach((yhbh, listInfo) -> {
                    if (listInfo.size() > 1) {
                        throw new ToflyDeniedException("无表号情况；用户编号:" + yhbh + "，请仔细检查用户编号是否冲突了");
                    }
                });
            } else {
                //有表号
                //如果 V 有多个的情况，则表示重复表移交
                if (v.size() > 1) {
                    //重复表，必须要有移交说明；并且用户编号不能一致
                    v.forEach(list -> {
                        if (StringUtil.isEmpty(list.getYjsm())) {
                            throw new ToflyDeniedException("水表编号:" + list.getSbbh() + ",是重复移交水表，请仔细填写移交说明");
                        }
                        //重复表设置移交选项
                        list.setYjxx("3");
                    });
                    //如果重复表情况下，有相同客户编号；请重新填写
                    Map<String, List<TurnoverFileInfo>> groupYhbhMap = v.stream().collect(Collectors.groupingBy(TurnoverFileInfo::getYhbh));
                    groupYhbhMap.forEach((yhbh, listInfo) -> {
                        if (listInfo.size() > 1) {
                            throw new ToflyDeniedException("请仔细检查重复水表:" + k + "的用户编号:" + yhbh + "，是否存在用户编号冲突了");
                        }
                    });
                } else {
                    //正常表移交；分组过后 只有一个
                    v.get(0).setYjxx("1");
                }
            }
            //存放移交水表的数据
            turnoverFileInfoList.addAll(v);
        });
        return turnoverFileInfoList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean turnoverFour(CustomSbYjgl bwsbyjgl, MultipartFile file) {
        //如果是单个移交，不是文件移交的情况
        String sbbhS = bwsbyjgl.getSbbhList();
        //水表移交判断Excel表中是否有重复移交等数据
        if (StringUtil.isNull(file) && StringUtil.isEmpty(sbbhS)) {
            throw new ToflyDeniedException("请正确操作；文件或单个移交水表必须填写");
        }
        List<String> sbbhList = null;
        if (StringUtil.isNotEmpty(sbbhS)){
            //读取单个退库情况
            sbbhList = Arrays.asList(sbbhS.split(","));
        }
        //如果不是单个移交，使用文件的情况
        if (StringUtil.isNull(sbbhList) && StringUtil.isNotNull(file)) {
            //文件流
            InputStream inputStream = null;
            List<TurnoverFileInfo> listFile = null;
            try {
                inputStream = file.getInputStream();
                //实体类与Excel表格式
                ExcelUtil excel = new ExcelUtil(TurnoverFileInfo.class);
                //Excel中的数据导入到实体类
                listFile = excel.importExcel(inputStream);
                if (listFile.size() > 0){
                    //文件中的水表编号
                    sbbhList = listFile.stream().map(TurnoverFileInfo::getSbbh).collect(Collectors.toList());
                }else {
                    throw new ToflyDeniedException("请正确填写模板");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (sbbhList.size() > 0) {
            //流水编号
            String lsbh = DateUtil.parseDateToStr("yyyyMMddHHmmss", Date8Util.getCurrentDate());
            Long yjlx = bwsbyjgl.getBwYjlx();
            Long deptId = bwsbyjgl.getBwJsbm();
            Long jrUser = bwsbyjgl.getBwJsry();
            Date yjTime = bwsbyjgl.getBwYjrq();
            int state = bwsbyjgl.getFlag();
            if (sbbhList.size() > 1000) {
                throw new ToflyDeniedException("最多移交1000支水表");
            }
            List<Bwrksbdatail> sbListAll = sbDetailService.list(Wrappers.<Bwrksbdatail>lambdaQuery().in(Bwrksbdatail::getBwSbbh, sbbhList)
                    .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwBhqz, Bwrksbdatail::getBwSbzt,
                            Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSbkj, Bwrksbdatail::getBwSblx, Bwrksbdatail::getRkpcid));
            //如果没有查到该水表数据，则提示；如果退库的数量与查询出来的数量不一致，则表示水表编号输错了
            if (StringUtil.isNull(sbListAll) || sbListAll.size() == 0 || sbbhList.size() != sbListAll.size()) {
                throw new ToflyDeniedException("请正确输入水表信息");
            }
            //过滤提示水表编号具体哪些输错情况（暂时没有）

            //对水表进行分组；可以得到各类型的个数
            Map<String, List<Bwrksbdatail>> groupMap = sbListAll.stream()
                    .collect(Collectors.groupingBy(v -> "口径" + v.getBwSbkj() + "厂家" + v.getBwSbcj() + "类型" + v.getBwSblx()));
            //遍历需要移交的水表；循环次数不多
            groupMap.forEach((k, v) -> {
                Bwrksbdatail bwrksbdatail = v.get(0);
                Long cj = bwrksbdatail.getBwSbcj();
                Long lx = bwrksbdatail.getBwSblx();
                Long kj = bwrksbdatail.getBwSbkj();
                CustomSbYjgl sbYjgl = new CustomSbYjgl();
                sbYjgl.setFlag(state);
                sbYjgl.setBwSbcj(cj);
                sbYjgl.setBwSblx(lx);
                sbYjgl.setBwSbkj(kj);
                sbYjgl.setBwYjlx(yjlx);
                sbYjgl.setBwJsbm(deptId);
                sbYjgl.setBwJsry(jrUser);
                sbYjgl.setBwYjrq(yjTime);
                sbYjgl.setBwLsbh(lsbh);
                List<String> sbListStr = v.stream().map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
                sbYjgl.setSbbhList(sbListStr.toString());
                sbYjgl.setSbzsbh(sbListStr.toString());
                //同种厂家、口径、类型的水表集合
                List<Bwrksbdatail> sbList = v;
                int number = sbList.size();
                //移交数量
                sbYjgl.setBwYjsl((long) number);
                //判断移交水表中有没有出现安装的水表
                //新表移交涉及多个连号水表移交
                //过滤得到不符合移交的水表
                List<String> sbZt = sbList.stream().filter(kk -> !"56".equals(kk.getBwSbzt())).map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
                if (sbZt.size() > 0) {
                    String sbbh = StringUtil.join(sbZt, ",");
                    throw new ToflyDeniedException("水表编号为：" + sbbh.substring(0, sbbh.length() - 1) + "的水表不符合移交条件，不能移交");
                }
                //新表移交入库，状态是 退库状态
                //修改水表状态//退库状态
                sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
                        .in(Bwrksbdatail::getBwSbbh, sbListStr).set(Bwrksbdatail::getBwSbzt, "62"));
                //根据 厂家、类型、口径 查询库存中的记录
                Bwrktotal totalList = totalService.getOne(Wrappers.<Bwrktotal>lambdaQuery()
                        .eq(Bwrktotal::getBwSblx, lx).eq(Bwrktotal::getBwSbkj, kj).eq(Bwrktotal::getBwSbcj, cj)
                        .select(Bwrktotal::getBwKcsl, Bwrktotal::getBwSysl, Bwrktotal::getBwKczs, Bwrktotal::getId));
//                只有使用数量大于移交数量才可以移交，为了避免水表没有出库就移交入库的情况
                if (totalList.getBwSysl() < number) {
                    throw new ToflyDeniedException("移交数目与库存数目不对应");
                }
                //修改移交过后的库存数量
                totalService.update(Wrappers.<Bwrktotal>lambdaUpdate().eq(Bwrktotal::getId, totalList.getId())
                        .set(Bwrktotal::getBwKcsl, totalList.getBwKcsl() + number).set(Bwrktotal::getBwSysl, totalList.getBwSysl() - number));
                //移交人员目前是当前操作系统的人员
                sbYjgl.setBwYjry(SecurityUtils.getUserId());
                yjglService.save(sbYjgl);
            });
            //修改批次记录库存使用情况
            Map<Long, List<Bwrksbdatail>> groupPcMap = sbListAll.stream().collect(Collectors.groupingBy(Bwrksbdatail::getRkpcid));
            //次数不多  一般情况两三次
            groupPcMap.forEach((k, v) -> {
                //批次记录表退库数量
                int pcTksl = v.size();
                Bwrkdetail bwrkdetail = bwrkdetailService.getOne(Wrappers.<Bwrkdetail>lambdaQuery().eq(Bwrkdetail::getId, k)
                        .select(Bwrkdetail::getBwKczs, Bwrkdetail::getBwKcsl, Bwrkdetail::getBwSysl));
                //数量
                Long sysl = bwrkdetail.getBwSysl();
                Long kcsl = bwrkdetail.getBwKcsl();
                bwrkdetailService.update(Wrappers.<Bwrkdetail>lambdaUpdate().eq(Bwrkdetail::getId, k)
                        .set(Bwrkdetail::getBwSysl, sysl - pcTksl).set(Bwrkdetail::getBwKcsl, kcsl + pcTksl));
            });
        }
        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTurnoverById(Long id) {
        //根据ID查询移交情况
        Bwsbyjgl yjglInfo = yjglService.getById(id);

        Long yjlx = yjglInfo.getBwYjlx();
        //得到水表前缀、起止号
//        String prefix = yjglInfo.getSbqz();
//        Long zh = yjglInfo.getBwBhzh();
//        Long qh = yjglInfo.getBwBhqh();

        Long cj = yjglInfo.getBwSbcj();
        Long kj = yjglInfo.getBwSbkj();
        Long lx = yjglInfo.getBwSblx();

        String sbbhS = yjglInfo.getSbzsbh();
        List<String> sbbhList = Arrays.asList(sbbhS.split(","));
        //如果是删除新表移交
        if (yjlx.equals((long) 63)) {
            //修改水表状态：出库
            sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .in(Bwrksbdatail::getBwSbbh, sbbhList).set(Bwrksbdatail::getBwSbzt, "56"));
            //修改库存数量
            Long number = Long.valueOf(sbbhList.size());
            //先查询库存中的记录
            Bwrktotal totalList = totalService.getOne(Wrappers.<Bwrktotal>lambdaQuery()
                    .eq(Bwrktotal::getBwSblx, lx).eq(Bwrktotal::getBwSbkj, kj).eq(Bwrktotal::getBwSbcj, cj)
                    .select(Bwrktotal::getBwKcsl, Bwrktotal::getBwSysl, Bwrktotal::getBwKczs, Bwrktotal::getId));
            //是删除移交，则新水依旧是出库状态，所以库存数量应减少，使用数量增加
            totalService.update(Wrappers.<Bwrktotal>lambdaUpdate().eq(Bwrktotal::getId, totalList.getId())
                    .set(Bwrktotal::getBwKcsl, totalList.getBwKcsl() - number).set(Bwrktotal::getBwSysl, totalList.getBwSysl() + number));
        }
        //删除旧表移交
        else {
            //状态为换表
            sbDetailService.update(Wrappers.<Bwrksbdatail>lambdaUpdate().in(Bwrksbdatail::getBwSbbh, sbbhList)
                    .set(Bwrksbdatail::getBwSbzt, "630"));
        }
        //删除移交记录
        yjglService.removeById(id);
        return true;
    }

    @Override
    public IPage<Bwsbyjgl> getTurnover(Page<Bwsbyjgl> page, Bwsbyjgl bwsbyjgl) {
        Long cj = bwsbyjgl.getBwSbcj();
        Long lx = bwsbyjgl.getBwSblx();
        Long kj = bwsbyjgl.getBwSbkj();
        return yjglService.page(page, Wrappers.<Bwsbyjgl>lambdaQuery().eq(StringUtil.isNotNull(cj), Bwsbyjgl::getBwSbcj, cj)
                .eq(StringUtil.isNotNull(lx), Bwsbyjgl::getBwSblx, lx).eq(StringUtil.isNotNull(kj), Bwsbyjgl::getBwSbkj, kj)
                .orderByDesc(Bwsbyjgl::getCreateDate));
    }

    @Override
    public List<Map> getTurnoverById(Long id) {
        return yjglService.selectById(id);
    }

    @Override
    public IPage<Map> getZjOrGz(Page page, SearchSb sb) {
        Long cj = sb.getBwSbcj();
        Long kj = sb.getBwSbkj();
        Long lx = sb.getBwSblx();
        Long yjlx = sb.getYjlxId();
        String sbbh = sb.getSbbh();
        if (StringUtil.isNull(yjlx)) {
            throw new ToflyDeniedException("移交类型必传");
        }
        return yjglService.page(page, Wrappers.<Bwsbyjgl>lambdaQuery().eq(Bwsbyjgl::getCheckFlag, "0")
                .eq(Bwsbyjgl::getBwYjlx, yjlx).eq(StringUtil.isNotNull(cj), Bwsbyjgl::getBwSbcj, cj)
                .like(StringUtil.isNotEmpty(sbbh), Bwsbyjgl::getSbzsbh, sbbh)
                .eq(StringUtil.isNotNull(kj), Bwsbyjgl::getBwSbkj, kj)
                .eq(StringUtil.isNotNull(lx), Bwsbyjgl::getBwSblx, lx).orderByDesc(Bwsbyjgl::getBwYjrq));
    }


}











