package com.testor.module.emergency.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.rule.service.SysRuleService;
import com.testor.biz.sys.dict.data.controller.SysDictDataController;
import com.testor.biz.sys.dict.data.model.domain.SysDictData;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataListResponse;
import com.testor.biz.sys.dict.data.model.dto.SysDictDataParam;
import com.testor.biz.sys.dict.data.service.SysDictDataService;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.common.constant.DefaultRule;
import com.testor.common.constant.StatusEnum;
import com.testor.common.core.exception.ServiceException;
import com.testor.common.util.DateUtil;
import com.testor.ddd.safetyControl.infrastructure.repository.space.dao.TSafeSpaceDao;
import com.testor.ddd.safetyControl.infrastructure.repository.space.entity.TSafeSpaceDO;
import com.testor.ddd.safetyControl.interfaces.model.vo.space.TSafeSpaceVO;
import com.testor.module.emergency.dao.TEmergencyGoodsDao;
import com.testor.module.emergency.model.domain.SFunction;
import com.testor.module.emergency.model.domain.TEmergencyGoods;
import com.testor.module.emergency.model.domain.TEmergencyGoodsPosition;
import com.testor.module.emergency.model.dto.ExportGoodsDTO;
import com.testor.module.emergency.model.dto.TEmergencyGoodsDTO;
import com.testor.module.emergency.model.dto.TEmergencysDTO;
import com.testor.module.emergency.model.execl.ExportGoods;
import com.testor.module.emergency.model.execl.ImportGoods;
import com.testor.module.emergency.model.vo.TEmergencyGoodsPositionVO;
import com.testor.module.emergency.model.vo.TEmergencyGoodsVO;
import com.testor.module.emergency.model.vo.TEmergencyVO;
import com.testor.module.emergency.service.TEmergencyGoodsPositionService;
import com.testor.module.emergency.service.TEmergencyGoodsService;
import com.testor.module.safe.handler.SafeHandler;
import com.testor.module.sys.service.NewSysOrgService;
import com.testor.module.sys.service.TOrgService;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 应急物资Service业务层处理
 *
 * @author testor-framework
 * @date 2022-10-08 17:31:31
 */
@Service("tEmergencyGoodsServiceImpl")
public class TEmergencyGoodsServiceImpl extends SuperServiceImpl<TEmergencyGoodsDao, TEmergencyGoods> implements TEmergencyGoodsService {

    @Autowired
    private TEmergencyGoodsPositionService tEmergencyGoodsPositionService;
    @Autowired(required = false)
    private SysDictDataController sysDictDataController;
    @Autowired(required = false)
    private SysDictDataService sysDictDataService;
    @Autowired
    private SysOrgService sysOrgService;
    @Autowired
    private SysRuleService sysRuleService;
    @Autowired
    private TEmergencyGoodsDao tEmergencyGoodsDao;
    @Autowired
    private TOrgService tOrgService;
    @Autowired
    private TSafeSpaceDao tSafeSpaceDao;
    @Autowired
    private SafeHandler safeHandler;

    @Autowired
    private NewSysOrgService newSysOrgService;


    @Override
    public Boolean addEntity(TEmergencysDTO tEmergencysDTO) {
        BaseResponse<TEmergencysDTO> baseResponse = new BaseResponse<>();
        TEmergencyGoods tEmergencyGoods = tEmergencysDTO.getTEmergencyGoods();
        String orgId = ContextUtils.getLoginUser().getOrgId();
        Integer practicalNum = 0;
        List<TEmergencyGoodsPosition> tEmergencyGoodsPositionList1 = tEmergencysDTO.getTEmergencyGoodsPositionList();
        for (int i = 0; i < tEmergencyGoodsPositionList1.size(); i++) {
            TEmergencyGoodsPosition tEmergencyGoodsPosition = tEmergencyGoodsPositionList1.get(i);

            if (ObjectUtil.isNotEmpty(tEmergencyGoodsPosition.getReserveNumPosition())) {
                practicalNum = practicalNum + tEmergencyGoodsPosition.getReserveNumPosition();
            }

        }
        tEmergencyGoods.setPracticalNum(practicalNum);
        tEmergencyGoods.setOrgId(orgId);
        save(tEmergencyGoods);
        List<TEmergencyGoodsPosition> tEmergencyGoodsPositionList = tEmergencysDTO.getTEmergencyGoodsPositionList()
                .stream().map(tEmergencyGoodsPosition -> {
                    tEmergencyGoodsPosition.setGoodsId(tEmergencyGoods.getId());
                    return tEmergencyGoodsPosition;
                }).collect(Collectors.toList());
        tEmergencyGoodsPositionService.saveBatch(tEmergencyGoodsPositionList);
        baseResponse.setData(tEmergencysDTO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEntity(TEmergencysDTO tEmergencysDTO) {
        TEmergencyGoods tEmergencyGoods = tEmergencysDTO.getTEmergencyGoods();
        String id = tEmergencyGoods.getId();
        List<TEmergencyGoodsPosition> tEmergencyGoodsPositionList = tEmergencysDTO.getTEmergencyGoodsPositionList();
        Integer integer = new Integer(0);
        Integer practicalNum = 0;
        for (TEmergencyGoodsPosition tEmergencyGoodsPosition : tEmergencyGoodsPositionList) {
            practicalNum = practicalNum + tEmergencyGoodsPosition.getReserveNumPosition();
            integer = integer + tEmergencyGoodsPosition.getRepairNum();
            tEmergencyGoodsPosition.setGoodsId(id);
            tEmergencyGoodsPosition.setId(null);
        }
        tEmergencyGoods.setPracticalNum(practicalNum);
        tEmergencyGoods.setAwaitingRepairNum(integer);
        boolean b = updateById(tEmergencyGoods);

        tEmergencyGoodsPositionService.remove(new LambdaQueryWrapper<TEmergencyGoodsPosition>().eq(TEmergencyGoodsPosition::getGoodsId, id));
        boolean b1 = tEmergencyGoodsPositionService.saveBatch(tEmergencyGoodsPositionList);
        return true;
    }

    @Override
    public boolean deleteEntity(String id) {
        boolean b = removeById(id);
        LambdaQueryWrapper<TEmergencyGoodsPosition> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ObjectUtil.isNotEmpty(id), TEmergencyGoodsPosition::getGoodsId, id);
        tEmergencyGoodsPositionService.remove(wrapper);
        return true;
    }

    @Override
    public TEmergencyVO getParticulars(String id) {
        TEmergencyGoods tEmergencyGoods = getById(id);
        TEmergencyGoodsVO tEmergencyGoodsVO = BeanUtil.copyProperties(tEmergencyGoods, TEmergencyGoodsVO.class);
        if (ObjectUtil.isNotEmpty(tEmergencyGoodsVO.getGoodsTypeKey())) {
            String goodsTypeName = sysDictDataController.getDictTypeDetail(null, "GOODS_MATERIALS", tEmergencyGoodsVO.getGoodsTypeKey()).getData().getDictValue();
            tEmergencyGoodsVO.setGoodsTypeName(goodsTypeName);
        }
        if (ObjectUtil.isNotEmpty(tEmergencyGoodsVO.getNameKey())) {
            String goodsName = sysDictDataController.getDictTypeDetail(null, "GOODS_MATERIALS", tEmergencyGoodsVO.getNameKey()).getData().getDictValue();
            tEmergencyGoodsVO.setGoodsName(goodsName);
        }
        String orgName = null;
        if (ObjectUtil.isNotEmpty(tEmergencyGoodsVO.getOrgId())) {
            orgName = sysOrgService.getById(tEmergencyGoodsVO.getOrgId()).getOrgName();
        }
        tEmergencyGoodsVO.setOrgName(orgName);
        LambdaQueryWrapper<TEmergencyGoodsPosition> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ObjectUtil.isNotEmpty(id), TEmergencyGoodsPosition::getGoodsId, id);
        List<TEmergencyGoodsPositionVO> tEmergencyGoodsPositionVOList = tEmergencyGoodsPositionService.list(wrapper).stream().map(tEmergencyGoodsPosition -> {
            TEmergencyGoodsPositionVO tEmergencyGoodsPositionVO = BeanUtil.copyProperties(tEmergencyGoodsPosition, TEmergencyGoodsPositionVO.class);
            if (ObjectUtil.isNotEmpty(tEmergencyGoodsPositionVO.getReserveNumPosition()) && ObjectUtil.isNotEmpty(tEmergencyGoodsPositionVO.getRepairNum())) {
                tEmergencyGoodsPositionVO.setAbleNum(tEmergencyGoodsPositionVO.getReserveNumPosition() - tEmergencyGoodsPositionVO.getRepairNum());
            }
            //获取关联的空间名称
            String spaceId = tEmergencyGoodsPosition.getSpaceId();
            if (StringUtils.isNotBlank(spaceId)) {
                TSafeSpaceVO tSafeSpaceDO = tSafeSpaceDao.getSpaceNameById(spaceId);
                if (ObjectUtil.isNotEmpty(tSafeSpaceDO)) {
                    //赋值到list
                    tEmergencyGoodsPositionVO.setSpaceName(tSafeSpaceDO.getStructureName());
                }
            }
            return tEmergencyGoodsPositionVO;
        }).collect(Collectors.toList());
        TEmergencyVO tEmergencyVO = new TEmergencyVO();
        tEmergencyVO.setTEmergencyGoods(tEmergencyGoodsVO);
        tEmergencyVO.setTEmergencyGoodsPositionVOList(tEmergencyGoodsPositionVOList);
        return tEmergencyVO;
    }

    @Override
    public Page<TEmergencyGoodsVO> pages(TEmergencyGoodsDTO tEmergencyGoodsDTO) {
        String rule = sysRuleService.dataRuleScope(DefaultRule.DEPT_SUB.name());
        LambdaQueryWrapper<TEmergencyGoods> wrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(rule)) {
            wrapper.apply(rule);
        }
        Page<TEmergencyGoods> page = new Page<>();
        page.setCurrent(tEmergencyGoodsDTO.getPage());
        page.setSize(tEmergencyGoodsDTO.getLimit());

        wrapper.eq(ObjectUtil.isNotEmpty(tEmergencyGoodsDTO.getNameKey()), TEmergencyGoods::getNameKey, tEmergencyGoodsDTO.getNameKey())
                .eq(ObjectUtil.isNotEmpty(tEmergencyGoodsDTO.getGoodsTypeKey()), TEmergencyGoods::getGoodsTypeKey, tEmergencyGoodsDTO.getGoodsTypeKey())
                .in(ObjectUtil.isNotEmpty(tEmergencyGoodsDTO.getOrgId()), TEmergencyGoods::getOrgId, tEmergencyGoodsDTO.getOrgId())
                .between(ObjectUtil.isNotEmpty(tEmergencyGoodsDTO.getValidityEndDate()) && ObjectUtil.isNotEmpty(tEmergencyGoodsDTO.getValidityStartDate()),
                        TEmergencyGoods::getValidityEndDate, tEmergencyGoodsDTO.getValidityStartDate(), tEmergencyGoodsDTO.getValidityEndDate())
                .last("ORDER BY COALESCE(next_check_time, '9999-12-31') ASC, create_date DESC ");

        if (ObjectUtil.isNotEmpty(tEmergencyGoodsDTO.getIsLate())){
            Integer isLate = tEmergencyGoodsDTO.getIsLate();
            Date now = new Date();
            //如果是逾期
            if (isLate == 1) {
                wrapper.le(TEmergencyGoods::getNextCheckTime,now);
            }else {
                wrapper.ge(TEmergencyGoods::getNextCheckTime,now);
            }
        }

        Page<TEmergencyGoods> page1 = this.page(page, wrapper);
        List<TEmergencyGoods> records = page1.getRecords();
        List<TEmergencyGoodsVO> tEmergencyGoodsVOList = records.stream().map(tEmergencyGoods -> {
            TEmergencyGoodsVO tEmergencyGoodsVO = BeanUtil.copyProperties(tEmergencyGoods, TEmergencyGoodsVO.class);
            SysOrg regionalCompany = tOrgService.getRegionalCompany(tEmergencyGoodsVO.getOrgId());
            if (regionalCompany != null) {
                tEmergencyGoodsVO.setBusinessOrgName(regionalCompany.getOrgName());
            }
            return tEmergencyGoodsVO;
        }).collect(Collectors.toList());
        dictTranslate(tEmergencyGoodsVOList, TEmergencyGoodsVO::getGoodsTypeKey, TEmergencyGoodsVO::setGoodsTypeName);
        dictTranslate(tEmergencyGoodsVOList, TEmergencyGoodsVO::getNameKey, TEmergencyGoodsVO::setGoodsName);
       // Map<String, String> sysOrgMap = sysOrgService.list().stream().collect(Collectors.toMap(SysOrg::getOrgId, SysOrg::getOrgName));
        List<TEmergencyGoodsVO> collect = tEmergencyGoodsVOList.stream().map(tEmergencyGoodsVO -> {
            String orgName = newSysOrgService.findOrgPathNameByOrgId(tEmergencyGoodsVO.getOrgId());
            if (ObjectUtil.isNotEmpty(tEmergencyGoodsVO.getPracticalNum()) && ObjectUtil.isNotEmpty(tEmergencyGoodsVO.getAwaitingRepairNum())) {
                tEmergencyGoodsVO.setAbleNum(tEmergencyGoodsVO.getPracticalNum() - tEmergencyGoodsVO.getAwaitingRepairNum());
            } else {
                tEmergencyGoodsVO.setAbleNum(0);
            }
            if (tEmergencyGoodsVO.getPracticalNum() == null) {
                tEmergencyGoodsVO.setPracticalNum(0);
            }
            tEmergencyGoodsVO.setOrgName(orgName);
            if (tEmergencyGoodsVO.getNextCheckTime() != null) {
                Date now = new Date();

                //如果当前时间在下次检点日期前
                if (now.compareTo(tEmergencyGoodsVO.getNextCheckTime())>0) {
                    tEmergencyGoodsVO.setIsLate(0);
                }else {
                    tEmergencyGoodsVO.setIsLate(1);
                }
            }
            return tEmergencyGoodsVO;
        }).collect(Collectors.toList());
        Page<TEmergencyGoodsVO> tEmergencyGoodsVOPage = new Page<>();
        tEmergencyGoodsVOPage.setRecords(collect);
        tEmergencyGoodsVOPage.setTotal(page1.getTotal());
        return tEmergencyGoodsVOPage;
    }

    @SneakyThrows
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public BaseResponse<String> importGoods(MultipartFile file) {
        BaseResponse<String> baseResponse = new BaseResponse<>();
        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        //判断是否为null
        if (file.equals("") || file.getSize() <= 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("上传文件数据错误");
            return baseResponse;
        }
        List<Integer> errorNum = new ArrayList<>();
        final String[] goodsId = {""};
//        try {
        EasyExcel.read(file.getInputStream(), ImportGoods.class, new AnalysisEventListener<ImportGoods>() {
                    @SneakyThrows
                    @Override
                    public void invoke(ImportGoods importGoods, AnalysisContext analysisContext) {
                        ReadRowHolder readRowHolder = analysisContext.readRowHolder();
                        Integer rowIndex = readRowHolder.getRowIndex() + 1;
                        if (rowIndex > 5) {
                            if (importGoods.getOrgCode() != null) {
                                TEmergencyGoods tEmergencyGoods = new TEmergencyGoods();
                                BeanUtils.copyProperties(importGoods, tEmergencyGoods);
                                setNextCheckTimePara(importGoods, tEmergencyGoods,rowIndex);

                                //存放机构id
                                SysOrg sysOrg = sysOrgService.getOne(new QueryWrapper<SysOrg>()
                                        .eq("org_code", importGoods.getOrgCode())
                                        .eq("status", "0")
                                        .eq("is_dept", "0"));
                                if (sysOrg != null) {
                                    if (!sysOrg.getOrgId().equals(curUser.getOrgId())){
                                        throw new BusinessException("只能上传本机构数据");
                                    }
                                    tEmergencyGoods.setOrgId(sysOrg.getOrgId());
                                } else {
                                    throw new BusinessException("企业：" + importGoods.getOrgName() + "不存在");
                                }
                                //获取物资类型
                                SysDictData goodsType = sysDictDataService.getOne(new QueryWrapper<SysDictData>()
                                        .eq("dict_id", "518cfb65ca4944378fd40c3f66c0276d")
                                        .eq("parent_id", "0")
                                        .eq("dict_value", importGoods.getGoodsTypeName())
                                        .eq("status", "0"));
                                if (goodsType != null) {
                                    tEmergencyGoods.setGoodsTypeKey(goodsType.getDictKey());
                                    //获取物资名称
                                    List<SysDictData> list = sysDictDataService.list(new QueryWrapper<SysDictData>()
                                            .eq("dict_id", "518cfb65ca4944378fd40c3f66c0276d")
                                            .eq("parent_id", goodsType.getDictDataId())
                                            .eq("dict_value", importGoods.getGoodsName()).eq("status", "0"));
                                    SysDictData goodsName = null;
                                    if (!CollectionUtils.isEmpty(list)) {
                                        goodsName = list.get(0);
                                    }
                                    if (goodsName != null) {
                                        tEmergencyGoods.setNameKey(goodsName.getDictKey());
                                    } else {
                                        throw new BusinessException("物资名称：" + importGoods.getGoodsName() + "不存在");
                                    }
                                } else {
                                    throw new BusinessException("物资类型：" + importGoods.getGoodsTypeName() + "不存在");
                                }

                                //获取有效期
                                String validityDate = importGoods.getValidityDate();
                                String[] date = validityDate.split("至");
                                Date validityStartDate = new Date();
                                Date validityEndDate = new Date();
                                if (date[0] != null && date[0] != "") {
                                    validityStartDate = DateUtil.convertStrToDate(date[0], "yyyy/MM/dd");
                                }
                                if (date[1] != null && date[1] != "") {
                                    validityEndDate = DateUtil.convertStrToDate(date[1], "yyyy/MM/dd");
                                }
                                //存放有效期
                                tEmergencyGoods.setValidityStartDate(validityStartDate);
                                tEmergencyGoods.setValidityEndDate(validityEndDate);
                                //位置信息
                                TEmergencyGoodsPosition tEmergencyGoodsPosition = setEmergencyGoodsPositionSpace(importGoods,rowIndex);
                                boolean save = save(tEmergencyGoods);
                                if (save) {
                                    tEmergencyGoodsPosition.setGoodsId(tEmergencyGoods.getId());
                                    boolean position = tEmergencyGoodsPositionService.save(tEmergencyGoodsPosition);
                                    if (!position) {
                                        errorNum.add(rowIndex);
                                    } else {
                                        goodsId[0] = tEmergencyGoods.getId();
                                    }

                                }
                            } else {
                                //位置信息
                                TEmergencyGoodsPosition tEmergencyGoodsPosition = setEmergencyGoodsPositionSpace(importGoods,rowIndex);
                                if (goodsId[0] != null && goodsId[0] != "") {
                                    tEmergencyGoodsPosition.setGoodsId(goodsId[0]);
                                    boolean position = tEmergencyGoodsPositionService.save(tEmergencyGoodsPosition);
                                    if (!position) {
                                        errorNum.add(rowIndex);
                                    }
                                }
                            }
                        }

                    }

                    @Override
                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

                    }
                }
        ).sheet().doRead();
//        }catch (ExcelAnalysisException e){
//            e.printStackTrace();
//            throw new ServiceException("文件中数据格式填写异常,请检查关键字为["+getWordAfterConvertData(e.getMessage())+"]的数据");
//        }
        if (errorNum.size() != 0) {
            baseResponse.setCode(400);
            baseResponse.setData("第" + errorNum + "行导入失败");
        }
        baseResponse.setData("导入成功");
        return baseResponse;
    }

    public static String getWordAfterConvertData(String message) {
        // 查找 "Convert data" 后面的部分
        int index = message.indexOf("Convert data ");
        if (index != -1) {
            // 提取 "Convert data" 后面的子字符串
            String substring = message.substring(index + "Convert data ".length()).trim();
            // 返回第一个单词
            String[] words = substring.split(" ");
            if (words.length > 0) {
                return words[0];
            }
        }
        return null;
    }

    /**
     * 设置  点检时间和周期字段
     */
    private void setNextCheckTimePara(ImportGoods importGoods,TEmergencyGoods tEmergencyGoods,Integer rowIndex) throws BusinessException {
        Integer cycle = importGoods.getCycle();
        if (cycle == null) {
            throw new BusinessException(String.format("Convert data 第%s行,点检周期不能为空", rowIndex));
        }
        String nextCheckTime = importGoods.getNextCheckTime();
        if (StringUtils.isBlank(nextCheckTime)){
            throw new BusinessException(String.format("Convert data 第%s行,下一点检时间不能为空", rowIndex));
        }
        tEmergencyGoods.setNextCheckTime(DateUtil.convertStrToDate(nextCheckTime, "yyyy-MM-dd HH:mm:ss"));
        tEmergencyGoods.setCycle(cycle);
    }



    private TEmergencyGoodsPosition setEmergencyGoodsPositionSpace(ImportGoods importGoods,Integer rowIndex) throws BusinessException {
        TEmergencyGoodsPosition tEmergencyGoodsPosition = new TEmergencyGoodsPosition();
        BeanUtils.copyProperties(importGoods, tEmergencyGoodsPosition);
        tEmergencyGoodsPosition.setReserveDate(DateUtil.convertStrToDate(importGoods.getReserveDate(), "yyyy-MM-dd HH:mm:ss"));
        String spaceCode = importGoods.getSpaceCode();
        if (StringUtils.isBlank(spaceCode)) {
            throw new BusinessException(String.format("Convert data 第%s行,存放位置不能为空", rowIndex));
        }
        TSafeSpaceDO tSafeSpaceDO = tSafeSpaceDao.selectOne(new LambdaQueryWrapper<TSafeSpaceDO>().eq(TSafeSpaceDO::getCode, spaceCode).eq(TSafeSpaceDO::getStatus, StatusEnum.USE.getCode()));
        if(tSafeSpaceDO != null){
            if (tSafeSpaceDO.getLevel() != 2){
                throw new BusinessException(String.format("Convert data 第%s行,存放位置请按照填写说明填写", rowIndex));
            }
            tEmergencyGoodsPosition.setSpaceId(tSafeSpaceDO.getId());
        }
        return tEmergencyGoodsPosition;
    }

    /**
     * 获取 导出相关方组织机构的 数据源
     *
     * @return
     */
    public List<TEmergencyGoodsVO> exportPartnerOrg(String dsName, String datasetName, Map<String, Object> parameters) {

        List<TEmergencyGoods> records = this.list();
        List<TEmergencyGoodsVO> tEmergencyGoodsVOList = records.stream().map(tEmergencyGoods -> {
            return BeanUtil.copyProperties(tEmergencyGoods, TEmergencyGoodsVO.class);
        }).collect(Collectors.toList());
        dictTranslate(tEmergencyGoodsVOList, TEmergencyGoodsVO::getGoodsTypeKey, TEmergencyGoodsVO::setGoodsTypeName);
        dictTranslate(tEmergencyGoodsVOList, TEmergencyGoodsVO::getNameKey, TEmergencyGoodsVO::setGoodsName);
        Map<String, String> sysOrgMap = sysOrgService.list().stream().collect(Collectors.toMap(SysOrg::getOrgId, SysOrg::getOrgName));
        tEmergencyGoodsVOList = tEmergencyGoodsVOList.stream().map(tEmergencyGoodsVO -> {
            String orgName = sysOrgMap.get(tEmergencyGoodsVO.getOrgId());
            tEmergencyGoodsVO.setOrgName(orgName);
            return tEmergencyGoodsVO;
        }).collect(Collectors.toList());
        List<TEmergencyGoodsPosition> tEmergencyGoodsPositions = tEmergencyGoodsPositionService.list();
        Map<String, List<TEmergencyGoodsPosition>> collect = tEmergencyGoodsPositions.stream().collect(Collectors.groupingBy(TEmergencyGoodsPosition::getGoodsId));
        ArrayList<TEmergencyGoodsVO> tEmergencyGoodsVOS = new ArrayList<>();
        tEmergencyGoodsVOList.forEach(tEmergencyGoodsVO -> {
            if (ObjectUtil.isNotEmpty(collect.get(tEmergencyGoodsVO.getId()))) {
                collect.get(tEmergencyGoodsVO.getId()).forEach(tEmergencyGoodsPosition -> {
                    tEmergencyGoodsVO.setPosition(tEmergencyGoodsPosition.getPosition());
                    tEmergencyGoodsVO.setRepairNum(tEmergencyGoodsPosition.getRepairNum());
                    tEmergencyGoodsVO.setReserveDate(tEmergencyGoodsPosition.getReserveDate());
                    tEmergencyGoodsVO.setPosition(tEmergencyGoodsPosition.getPosition());
                    tEmergencyGoodsVOS.add(tEmergencyGoodsVO);
                });
            } else {
                tEmergencyGoodsVOS.add(tEmergencyGoodsVO);
            }
        });
        return tEmergencyGoodsVOS;
    }

    public <T> void dictTranslate(Collection<T> entities, Function<T, String> getKey, SFunction<T, String> setValue) {
        if (Objects.isNull(entities) || entities.isEmpty()) {
            return;
        }

        Set<String> keys = new HashSet<>();


        for (T x : entities) {
            String deptId = getKey.apply(x);
            if (Objects.nonNull(deptId)) {
                keys.add(deptId);
            }
        }
        if (ObjectUtil.isEmpty(keys)) {
            log.warn("字典没有当前值");
            return;
        }
        SysDictDataParam sysDictDataParam = new SysDictDataParam();
        sysDictDataParam.setDictId("518cfb65ca4944378fd40c3f66c0276d");
        BaseResponse<BaseResponseList<SysDictDataListResponse>> baseResponseListBaseResponse = sysDictDataController.listAllEntity(sysDictDataParam);
        List<SysDictDataListResponse> data = baseResponseListBaseResponse.getData().getData();
        Map<String, String> dictMap = data.stream().collect(Collectors.toMap(SysDictDataListResponse::getDictKey, SysDictDataListResponse::getDictValue));

        entities = entities.stream().map(entity -> {
            String apply = getKey.apply(entity);
            if (apply != null) {
                String deptName = dictMap.get(apply);
                if (ObjectUtil.isNotEmpty(deptName)) {
                    setValue.set(entity, deptName);
                } else {
                    setValue.set(entity, "");
                }

            } else {
                setValue.set(entity, "");
            }

            return entity;
        }).collect(Collectors.toList());
    }

    @SneakyThrows
    @Override
    public void exportGoods(HttpServletResponse response, TEmergencyGoodsDTO tEmergencyGoodsDTO) {
        tEmergencyGoodsDTO.setSize(Long.valueOf(-1));
        List<ExportGoodsDTO> dtoList = tEmergencyGoodsDao.exportGoods(tEmergencyGoodsDTO);
        List<ExportGoods> exportGoods = setDictNameAndJybDqName(dtoList);
        String fileName = "应急物资列表";
        //内容策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();

        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置 垂直居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
        EasyExcel.write(response.getOutputStream())
                .head(ExportGoods.class)
                // 合并策略：合并相同数据的行。第一个参数表示从哪一行开始进行合并，由于表头占了两行，因此从第2行开始（索引从0开始）
                //设置列宽
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(22))
                //设置内容样式（垂直居中）
                .registerWriteHandler(horizontalCellStyleStrategy)
                // 注意：需要先调用registerWriteHandler()再调用sheet()方法才能使合并策略生效！！！
                .sheet("应急物资列表")
                //数据源 dataList(List<List<Object>>)双层list集合
                .doWrite(exportGoods);
    }


    private  List<ExportGoods> setDictNameAndJybDqName(List<ExportGoodsDTO> dtos){
        List<ExportGoods> linkedQueue = new ArrayList<>();
        if (CollectionUtils.isEmpty(dtos)) {
            return linkedQueue;
        }
        dtos.forEach(exportGoodsDTO -> {
            if (ObjectUtil.isNotEmpty(exportGoodsDTO.getGoodsTypeName())) {
                String goodsTypeName = sysDictDataController.getDictTypeDetail(null, "GOODS_MATERIALS", exportGoodsDTO.getGoodsTypeName()).getData().getDictValue();
                exportGoodsDTO.setGoodsTypeName(goodsTypeName);
            }
            if (ObjectUtil.isNotEmpty(exportGoodsDTO.getGoodsName())) {
                String goodsName = sysDictDataController.getDictTypeDetail(null, "GOODS_MATERIALS", exportGoodsDTO.getGoodsName()).getData().getDictValue();
                exportGoodsDTO.setGoodsName(goodsName);
            }
            //    大区/经营部/xxxx粮库
            String orgPathName = newSysOrgService.findOrgPathNameByOrgId(exportGoodsDTO.getOrgId());
            if (StringUtils.isNotBlank(orgPathName)) {
                String[] split = StringUtils.split(orgPathName, "/");
                if (split.length == 3) {
                    exportGoodsDTO.setJybName(split[1]);
                    exportGoodsDTO.setDqName(split[0]);
                }
                if (split.length == 2) {
                    exportGoodsDTO.setJybName(split[1]);
                    exportGoodsDTO.setDqName(split[0]);
                    exportGoodsDTO.setOrgName("");
                }
                if (split.length == 1) {
                    exportGoodsDTO.setJybName("");
                    exportGoodsDTO.setDqName(split[0]);
                    exportGoodsDTO.setOrgName("");
                }

            }
            ExportGoods exportGood = new ExportGoods();
            BeanUtils.copyProperties(exportGoodsDTO, exportGood);
            linkedQueue.add(exportGood);
        });
        return linkedQueue;
    }


    @Override
    public Boolean confirmSpotChecks(String id) {
        TEmergencyGoods byId = this.getById(id);
        Integer cycle = byId.getCycle();
        if (cycle == null) {
            throw new ServiceException("该数据未配置点检周期");
        }
        Date nextCheckTime = byId.getNextCheckTime();
        if (nextCheckTime == null) {
            throw new ServiceException("该数据未配置下一点检周期");
        }
        LocalDateTime nextCheckTimeLocalDateTime = cn.hutool.core.date.DateUtil.toLocalDateTime(nextCheckTime);

        LocalDateTime localDateTime = nextCheckTimeLocalDateTime.plusDays(cycle);
        Date date = DateUtil.localDateTimeToDate(localDateTime);
        byId.setNextCheckTime(date);
        return this.updateById(byId);
    }


    public static void main(String[] args) {
        String[] split = StringUtils.split("大区/经营部/xxxx粮库", "/");
        System.out.println(split[0]);
        System.out.println(split[1]);
        System.out.println(split[2]);

    }

}
