package com.tofly.xrtygis.custom.service.dma.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.xrtygis.custom.entity.dma.ConstomUserArea;
import com.tofly.xrtygis.custom.mapper.YhBingAreaMapper;
import com.tofly.xrtygis.custom.service.dma.YhBingAreaService;
import com.tofly.xrtygis.entity.Dmaregion;
import com.tofly.xrtygis.entity.Dmausertable;
import com.tofly.xrtygis.service.DmaregionService;
import com.tofly.xrtygis.service.DmausertableService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
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 FlashWJL
 * @date 2021/7/20 11:08
 */
@Service
@AllArgsConstructor
public class YhBingAreaServiceImpl implements YhBingAreaService {

    private final DmaregionService dmaregionService;
    private final DmausertableService dmausertableService;
    private final YhBingAreaMapper yhBingAreaMapper;


//    @Override
//    public void getClientBingExcel(Long id, String areaName, HttpServletResponse response) {
//        if (StringUtil.isNull(id)){
//            throw new ToflyDeniedException("分区ID必传");
//        }
//        if (StringUtil.isEmpty(areaName)){
//            throw new ToflyDeniedException("分区名称必传");
//        }
//        List<Map> result = new ArrayList<>();
//        Map map = new HashMap(6);
//        map.put("id",id);
//        map.put("areaName",areaName);
//        result.add(map);
//        // 根据templateServiceType,templateFlag获取对应模板数据
//        ExcelExportFileTypeEnum excelExportFileTypeEnum = ExcelExportFileTypeEnum.getExcelExportFileTypeEnum("clientBingArea", "1");
//        if (null == excelExportFileTypeEnum) {
//            return ;
//        }
//        //将查询的结果转json字符串的格式，因为导出的时候只能传一个字符串
//        String resultListToString = JSONArray.toJSONString(result);
//        // 从模型类型枚举根据templateServiceType获取策略对应模板数据
//        List<Map<String, Object>> dataList = excelStrategyContext.getExportData("clientBingArea", "1", resultListToString);
//        ExcelUtil.export(dataList.get(0), excelExportFileTypeEnum, Constant.FILE_PATH_TEST_EXPORT_EXCEL, response);
//    }

    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public boolean clientBingArea(Long id, MultipartFile file) {
        if (StringUtil.isNull(id)) {
            throw new ToflyDeniedException("请选择分区");
        }
        if (StringUtil.isNull(file)) {
            throw new ToflyDeniedException("上传文件为空");
        }
        InputStream inputStream = file.getInputStream();
        ExcelUtil opsExcel = new ExcelUtil(ConstomUserArea.class);
        List<ConstomUserArea> list = opsExcel.importExcel(inputStream);
        if (list.size() > 0) {
            //用set来接收，避免重复用户编号的情况
            List<String> yhbhList = list.stream().filter(m -> StringUtil.isNotEmpty(m.getYhbh())).map(ConstomUserArea::getYhbh).collect(Collectors.toList());
            int size = yhbhList.size();
            //向上取整 , 获得次数，但是次数不多，只有几次，所以可以使用for循环分段查询
            int count = (int) Math.ceil(Double.valueOf(size) / 1000d);
            //查询分区的GUID
            Dmaregion dmaregion = dmaregionService.getOne(Wrappers.<Dmaregion>lambdaQuery().eq(Dmaregion::getId, id)
                    .select(Dmaregion::getDmaGid));
            String guid = dmaregion.getDmaGid();
            List<Dmausertable> dmausertableList = new ArrayList<>();

            for (int i = 0; i < count; i++) {
                int startIndex = i * 1000;
                int endIndex = 1000 + i * 1000;
                List<String> subYhbhList;
                //判断是否截取的最后一次数据，如果是最后一次数据，则不能使用endIndex这个参数去截取了，有可能会存在endIndex参数值超过索引最大值的情况
                if (i < count - 1) {
                    //分段采取数据 0~999 ； 1000~1999 , 2000~2999 .....//这里subList方法无法截取最后一位，所以需要多写一位索引
                    subYhbhList = yhbhList.subList(startIndex, endIndex);
                } else {
                    //分段采取最后的数据
                    subYhbhList = yhbhList.subList(startIndex, yhbhList.size());
                }
                //查询用户
                List<Dmausertable> queryExistYhbh = dmausertableService.list(Wrappers.<Dmausertable>lambdaQuery().in(Dmausertable::getYhbh, subYhbhList)
                        .select(Dmausertable::getYhbh, Dmausertable::getDmaIds));
//                existYhbh.addAll(queryExistYhbh.stream().map(Dmausertable::getYhbh).collect(Collectors.toList()));
                dmausertableList.addAll(queryExistYhbh);
            }
            Map<String, String> yhAndDma = new HashMap<>(16);
            dmausertableList.forEach(v -> {
                yhAndDma.put(v.getYhbh(), v.getDmaIds());
            });

            //如果查询出来的个数与传入的个数不相等，那么会有用户输入编号错误的情况，将对这些编号进行筛选出来
            if (!(size == dmausertableList.size())) {
                //过滤用户编号输入错误的
                List<String> errorYhbh = yhbhList.stream().filter(m -> !yhAndDma.containsKey(m)).collect(Collectors.toList());
                if (errorYhbh.size() > 0) {
                    String error = StringUtil.join(errorYhbh, ",");
                    throw new ToflyDeniedException("以下用户编号填写错误：" + error + "请重新填写");
                }
            }
            //存放用户和绑定分区的GUID
            Map<String, String> updateYhAndDma = new HashMap<>(16);
            //过滤已经绑定了该分区的用户
            yhAndDma.forEach((k, v) -> {
                //判断是否第一次绑定分区
                if (StringUtil.isNotEmpty(v)) {
                    //判断是否包含该分区的GUID，只有不包含的才可以更新；如果包含，则不进行再次绑定
                    if (!v.contains(guid)) {
                        //拼接绑定的dmaGuid
                        updateYhAndDma.put(k, v + "," + guid);
                    }
                } else {
                    //第一次绑定分区
                    updateYhAndDma.put(k, guid);
                }
            });

            if (updateYhAndDma.size() > 0) {
                //修改用户绑定分区
                dmausertableService.updateBingDma(updateYhAndDma);
            }

        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cientUnbingArea(Long id, String yhbhS) {
        if (StringUtil.isEmpty(yhbhS)) {
            throw new ToflyDeniedException("请选择需要解绑的用户");
        }
        List<String> yhbhList = Arrays.asList(yhbhS.split(","));
        int size = yhbhList.size();
        //向上取整 , 获得次数，但是次数不多，只有几次，所以可以使用for循环分段查询
        int count = (int) Math.ceil(Double.valueOf(size) / 1000d);
        List<Dmausertable> dmausertableList = new ArrayList();
        for (int i = 0; i < count; i++) {
            int startIndex = i * 1000;
            int endIndex = 1000 + i * 1000;
            List<String> subYhbhList;
            //判断是否截取的最后一次数据，如果是最后一次数据，则不能使用endIndex这个参数去截取了，有可能会存在endIndex参数值超过索引最大值的情况
            if (i < count - 1) {
                //分段采取数据 0~999 ； 1000~1999 , 2000~2999 .....//这里subList方法无法截取最后一位，所以需要多写一位索引
                subYhbhList = yhbhList.subList(startIndex, endIndex);
            } else {
                //分段采取最后的数据
                subYhbhList = yhbhList.subList(startIndex, yhbhList.size());
            }
            //查询用户dmaGuid
            List<Dmausertable> subDmaList = dmausertableService.list(Wrappers.<Dmausertable>lambdaQuery()
                    .in(Dmausertable::getYhbh, subYhbhList).select(Dmausertable::getDmaIds, Dmausertable::getYhbh));
            dmausertableList.addAll(subDmaList);
        }
        //查询分区的GUID
        Dmaregion dmaregion = dmaregionService.getOne(Wrappers.<Dmaregion>lambdaQuery().eq(Dmaregion::getId, id)
                .select(Dmaregion::getDmaGid));
        String guid = dmaregion.getDmaGid();
        //存放最终的用户绑定的分区guid数据
        Map<String, String> yhBingArea = new HashMap<>(16);
        dmausertableList.forEach(v -> {
            //用户绑定的所有分区guid集合
            String dmaGuid = v.getDmaIds();
            /**
             * 转集合  说明：使用Arrays.asList得到的集合数组，不能对它操作add/remove等方法；会报错（UnsupportedOperationException）；
             * 因为Arrays.asList是Arrays的内部类   网址：https://blog.csdn.net/liu_005/article/details/74091805
             */
            List<String> asList = Arrays.asList(dmaGuid.split(","));
            List<String> guidList = new ArrayList<>(asList);
            //移除掉解绑分区的guid
//            for (int i = 0; i < guidList.size(); i++) {
//                //判断只要有匹配的就移除
//                if (guid.equals(guidList.get(i))) {
//                    guidList.remove(i);
//                    //跳出当前移除循环
//                    break;
//                }
//            }
            guidList.remove(guid);
            //转逗号隔开的字符串
            String reslutAreaGuid = StringUtil.join(guidList, ",");
            yhBingArea.put(v.getYhbh(), reslutAreaGuid);
        });
        if (yhBingArea.size() > 0) {
            //修改用户绑定分区
            dmausertableService.updateBingDma(yhBingArea);
        }
        return true;
    }

    @Override
    public Page<Dmausertable> getClientByArea(Long id,String cbbName, String inputcontent , Page<Dmausertable> page) {
        //根据分区ID获取分区Guid
        Dmaregion dmaregion = dmaregionService.getOne(Wrappers.<Dmaregion>lambdaQuery().eq(Dmaregion::getId, id)
                .select(Dmaregion::getDmaGid));
        if (StringUtil.isNotNull(dmaregion)) {
            String guid = dmaregion.getDmaGid() ;
            return yhBingAreaMapper.getClientInfo(page,cbbName,inputcontent,guid);
            /*陈浩：弃用，不满足多条件模糊查询I
            Page<Dmausertable> dmausertableIPage = dmausertableService
                    .page(page, Wrappers.<Dmausertable>lambdaQuery().like(Dmausertable::getDmaIds, guid)
                            .eq(StringUtil.isNotEmpty(cbbName) , Dmausertable::getCbbmc , cbbName)
                            .like(StringUtil.isNotEmpty(inputcontent) ,Dmausertable::getYhxm , inputcontent)
                            .select(Dmausertable::getCbb, Dmausertable::getCbpq, Dmausertable::getYhbh ,
                                    Dmausertable::getYhxm, Dmausertable::getYhdz, Dmausertable::getSbbh ,
                                    Dmausertable::getDayWater, Dmausertable::getZhXgrq ,Dmausertable::getCbbmc , Dmausertable::getCbpqmc)) ;*/
        } else {
            return page ;
        }

    }

    @Override
    public boolean unbingAreaId(Long id) {
        //根据分区ID获取分区Guid
        Dmaregion dmaregion = dmaregionService.getOne(Wrappers.<Dmaregion>lambdaQuery().eq(Dmaregion::getId, id)
                .select(Dmaregion::getDmaGid));
        String guid = dmaregion.getDmaGid();
        //查询该guid下的所有用户
        List<Dmausertable> dmausertableList = dmausertableService.list(Wrappers.<Dmausertable>lambdaQuery()
                .like(Dmausertable::getDmaIds, guid)
                .select(Dmausertable::getDmaIds, Dmausertable::getYhbh));
        //存放最终的用户绑定的分区guid数据
        Map<String, String> yhBingArea = new HashMap<>(16);
        dmausertableList.forEach(v -> {
            //用户绑定的所有分区guid集合
            String dmaGuid = v.getDmaIds();
            List<String> asList = Arrays.asList(dmaGuid.split(","));
            List<String> guidList = new ArrayList<>(asList);
            guidList.remove(guid);
            //转逗号隔开的字符串
            String reslutAreaGuid = StringUtil.join(guidList, ",");
            yhBingArea.put(v.getYhbh(), reslutAreaGuid);
        });
        if (yhBingArea.size() > 0) {
            //修改用户绑定分区
            dmausertableService.updateBingDma(yhBingArea);
        }
        return true;
    }


}
