package cn.common.service.impl;

import cn.common.common.constants.BaseConstant;
import cn.common.common.enums.ErrorCode;
import cn.common.common.utils.ValidationUtil;
import cn.common.common.utils.collection.CollectionUtils;
import cn.common.common.utils.common.BaseUtil;
import cn.common.common.utils.common.CheckParam;
import cn.common.common.exception.BusinessException;
import cn.common.interaction.helper.PageBuilder;
import cn.common.repository.entity.AuthRole;
import cn.common.repository.entity.GridArchives;
import cn.common.repository.repository.GridArchivesRepository;
import cn.common.req.HealthArchivesAddReq;
import cn.common.req.HealthArchivesReq;
import cn.common.req.HealthArchivesUpdateReq;
import cn.common.interaction.resp.page.Pagination;
import cn.common.resp.HealthArchivesResp;
import cn.common.req.HealthArchivesImportReq;
import cn.common.resp.HealthArchivesExportResp;
import cn.common.repository.entity.HealthArchives;
import cn.common.repository.repository.HealthArchivesRepository;
import cn.common.service.AuthUserService;
import cn.common.service.HealthArchivesService;
import cn.common.common.utils.ExportExcelHandler;
import cn.common.req.base.BaseDeleteReq;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cn.common.common.utils.spring.SnowflakeIdWorker;
import com.google.common.collect.Lists;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author Singer create by Singer email:singer-coder@qq.com
* @packageName cn.common.service
* @Description: 健康档案表信息相关服务方法实现
* @date 2021-04-23
*/
@Service("healthArchivesService")
@Slf4j
public class HealthArchivesServiceImpl implements HealthArchivesService {

    @Resource
    private HealthArchivesRepository healthArchivesRepository;

    @Resource
    private GridArchivesRepository gridArchivesRepository;

    @Resource
    private MapperFacade mapperFacade;

    @Resource
    private BaseConstant baseConstant;

    @Resource
    private AuthUserService authUserService;

    @Resource
    private HttpServletResponse response;

    @Resource
    private HttpServletRequest request;

    /**
    * 导出数据
    * @author: create by singer - Singer email:singer-coder@qq.com
    * @date 2022/3/21
    * @param pageReq
    * @return java.util.List
    */
    @Override
    public void exportData(HealthArchivesReq pageReq){
        log.info(">>>>>>>>>>>>>>>>>数据导出Req {} <<<<<<<<<<<<<<<<", JSON.toJSONString(pageReq));
        //构建查询条件
        LambdaQueryWrapper<HealthArchives> pageWrapper = new LambdaQueryWrapper<>();
        setPageCriteria(pageWrapper,pageReq);
        pageWrapper.orderBy(true,false,HealthArchives::getCreateTime);
        List<HealthArchives> pageList = healthArchivesRepository.selectList(pageWrapper);
        if (CollectionUtils.isEmpty(pageList)) {
            return;
        }
        List<HealthArchivesExportResp> respList =
            mapperFacade.mapAsList(pageList, HealthArchivesExportResp.class);
        try {
            String fileName = "导出信息.xlsx";
            ExportExcelHandler.setExportResponse(response,fileName);
            ExcelWriter excelWriter = null;
            try {
                // 这里 需要指定写用哪个class去写
                excelWriter = EasyExcel.write(response.getOutputStream(), HealthArchivesExportResp.class).build();
                // 这里注意 如果同一个sheet只要创建一次
                WriteSheet writeSheet = EasyExcel.writerSheet("sheet").build();
                excelWriter.write(respList,writeSheet);
            } finally {
                // 关闭流
                if (excelWriter != null) {
                    excelWriter.finish();
                }
            }
        } catch (Exception e) {
            log.error(">>>>>>>>>>>>>>>>>>>>>导出数据异常:{},{}<<<<<<<<<<<<<<<<<<<<<<",e.getMessage(),e);
            ExportExcelHandler.setExportErrorResponse(response);
            Map<String, String> map = Maps.newHashMap();
            try {
                response.getWriter().println(JSON.toJSONString(map));
            } catch (IOException ioException) {
                log.error(">>>>>>>>>>>>>>>>>导出数据发生异常:{},{}<<<<<<<<<<<<<<<<<",e.getMessage(),e);
                ioException.printStackTrace();
            }
        }
    }

    /**
    * 数据导入
    * @author: create by singer - Singer email:singer-coder@qq.com
    * @date 2022/3/21
    * @param file 文件
    * @return
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void importData(MultipartFile file){
        try{
            List<HealthArchivesImportReq> dataList = EasyExcel
                .read(file.getInputStream()).head(HealthArchivesImportReq.class).sheet().doReadSync();
            if(CollectionUtils.isEmpty(dataList)){
                return;
            }
            //进行必要的字段校验
            ValidationUtil.validate(dataList);
            dataList.stream().forEach(item -> {
                HealthArchives entity = mapperFacade.map(item, HealthArchives.class);
                try {
                    String authUserId = authUserService.currentAuthUserId();
                    BaseUtil.setFieldValueNotNull(entity);
                    entity.setHealthArchivesId(SnowflakeIdWorker.uniqueMainId());
                    entity.setOperatorId(authUserId);
                } catch (Exception e) {
                    log.error("导入->设置为空的属性失败 {} , {} ",e.getMessage(),e);
                }
                healthArchivesRepository.insert(entity);
            });
        }catch (Exception e){
            log.info(">>>>>>>>>>导入数据出现异常:{},{}<<<<<<<<<",e.getMessage(),e);
            throw new BusinessException(ErrorCode.IMPORT_ERROR_CODE.getCode(),
                ErrorCode.IMPORT_ERROR_CODE.getMessage()+StrUtil.COLON+e.getMessage());
        }
    }

    /**
     * 新增
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/2/15
     * @param addReq 新增Req
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
        public void addItem(HealthArchivesAddReq addReq){
        log.info(">>>>>>>>>>>>>>>>>新增Req {} <<<<<<<<<<<<<<<<", JSON.toJSONString(addReq));
        String authUserId = authUserService.currentAuthUserId();
        HealthArchives entity = mapperFacade.map(addReq, HealthArchives.class);
        try {
            BaseUtil.setFieldValueNotNull(entity);
        } catch (Exception e) {
            log.error("新增->设置为空的属性失败 {} , {} ",e.getMessage(),e);
            throw new BusinessException(ErrorCode.SET_EMPTY_FIELD_ERROR.getCode()
            ,ErrorCode.SET_EMPTY_FIELD_ERROR.getMessage());
        }
        entity.setHealthArchivesId(SnowflakeIdWorker.uniqueMainId());
        entity.setOperatorId(authUserId);
        healthArchivesRepository.insert(entity);

        String gridUnitId = addReq.getGridUnitId();

        GridArchives gridArchives = new GridArchives();
        gridArchives.setHealthArchivesId(entity.getHealthArchivesId());
        gridArchives.setGridUnitId(gridUnitId);
        gridArchives.setGridArchivesId(SnowflakeIdWorker.uniqueMainId());
        gridArchives.setOperatorId(authUserId);
        try {
            BaseUtil.setFieldValueNotNull(gridArchives);
        } catch (Exception e) {
            log.error("新增->设置为空的属性失败 {} , {} ",e.getMessage(),e);
            throw new BusinessException(ErrorCode.SET_EMPTY_FIELD_ERROR.getCode()
                    ,ErrorCode.SET_EMPTY_FIELD_ERROR.getMessage());
        }
        gridArchivesRepository.insert(gridArchives);
    }

    /**
     * 批量删除信息
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/2/2
     * @param req 需要被删除的信息
     */
    @Override
    public void batchDeleteItem(BaseDeleteReq req){
        List<String> mainIdList = req.getMainIdList();
        if(CollectionUtils.isEmpty(mainIdList)) {
            return;
        }
        List<HealthArchives> entityList = healthArchivesRepository.selectList(
            new LambdaQueryWrapper<HealthArchives>().in(HealthArchives::getHealthArchivesId,mainIdList));
        entityList.stream().forEach(item -> {
            healthArchivesRepository.deleteById(item);
        });
    }

    /**
    * 查询所有信息
    * @author: create by singer - Singer email:singer-coder@qq.com
    * @date 2022/3/13
    * @param
    * @return java.util.List
    */
    @Override
    public List<HealthArchivesResp> queryAllHealthArchives(){
        List<HealthArchives> entityList = healthArchivesRepository.selectList(new LambdaQueryWrapper<>());
            if(CollectionUtils.isEmpty(entityList)){
            return Lists.newArrayList();
        }
        return mapperFacade.mapAsList(entityList,HealthArchivesResp.class);
    }

    /**
     * 分页查询
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/2/15
     * @param  pageReq 分页查询Req
     * @return Pagination
     */
    @Override
    public Pagination<HealthArchivesResp> queryByPage(
        HealthArchivesReq pageReq){
        log.info(">>>>>>>>>>>>>>>>>分页查询Req {} <<<<<<<<<<<<<<<<", JSON.toJSONString(pageReq));
        //构建查询条件
        LambdaQueryWrapper<HealthArchives> pageWrapper = new LambdaQueryWrapper<>();
        setPageCriteria(pageWrapper,pageReq);
        //网格查询条件
        String gridUnitId = pageReq.getGridUnitId();
        if(!CheckParam.isNull(gridUnitId)){
            List<String> gridArchivesIdList = gridArchivesRepository.selectByGridUnitId(gridUnitId);
            if(!CollectionUtils.isEmpty(gridArchivesIdList)){
                pageWrapper.in(HealthArchives::getHealthArchivesId,gridArchivesIdList);
            }else{
                return PageBuilder.buildPageResult(
                        PageHelper.startPage(pageReq.getCurrentPage(), pageReq.getItemsPerPage())
                        ,new ArrayList<>());
            }
        }
        pageWrapper.orderBy(true,false,HealthArchives::getCreateTime);
        //开始分页
        Page<Object> page = PageHelper.startPage(pageReq.getCurrentPage(), pageReq.getItemsPerPage());
        List<HealthArchives> pageList = healthArchivesRepository.selectList(pageWrapper);
        if (CollectionUtils.isEmpty(pageList)) {
            return PageBuilder.buildPageResult(page,new ArrayList<>());
        }
        List<HealthArchivesResp> respList =
            mapperFacade.mapAsList(pageList, HealthArchivesResp.class);
        List<String> healthArchivesIdList =
                respList.stream().map(item -> item.getHealthArchivesId()).distinct().collect(Collectors.toList());
        List<GridArchives> gridArchivesList = gridArchivesRepository.selectList(
                new LambdaQueryWrapper<GridArchives>().in(GridArchives::getHealthArchivesId, healthArchivesIdList));
        HashMap<String, GridArchives> gridArchivesHashMap = gridArchivesList.stream()
                .collect(Collectors.toMap(GridArchives::getHealthArchivesId, a -> a, (k1, k2) -> k1, HashMap::new));
        Integer startIndex = (pageReq.getItemsPerPage() * pageReq.getCurrentPage()) - pageReq.getItemsPerPage() + 1;
        AtomicInteger idBeginIndex = new AtomicInteger(startIndex);
            respList.stream().forEach(item -> {
                GridArchives gridArchives = gridArchivesHashMap.get(item.getHealthArchivesId());
                if(!CheckParam.isNull(gridArchives)){
                    item.setGridUnitId(gridArchives.getGridUnitId());
                }else{
                    item.setGridUnitId(StrUtil.EMPTY);
                }
                item.setId(Integer.valueOf(idBeginIndex.getAndIncrement()).longValue());
        });
        return PageBuilder.buildPageResult(page,respList);
    }

    /**
     * 设置分页条件
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/5/31
     * @param pageWrapper 查询条件
     * @param pageReq 分页插件
     * @return
     */
    private void setPageCriteria(LambdaQueryWrapper<HealthArchives> pageWrapper, HealthArchivesReq pageReq){

         if(!CheckParam.isNull(pageReq.getGender())){
             pageWrapper.eq(HealthArchives::getGender,pageReq.getGender());
         }

         if(!CheckParam.isNull(pageReq.getBirthday())){
             pageWrapper.eq(HealthArchives::getBirthday,pageReq.getBirthday());
         }

         if(!CheckParam.isNull(pageReq.getRealName())){
             pageWrapper.like(HealthArchives::getRealName,"%"+pageReq.getRealName());
         }

         if(!CheckParam.isNull(pageReq.getNation())){
             pageWrapper.like(HealthArchives::getNation,"%"+pageReq.getNation());
         }

         if(!CheckParam.isNull(pageReq.getOccupation())){
             pageWrapper.like(HealthArchives::getOccupation,"%"+pageReq.getOccupation());
         }

         if(!CheckParam.isNull(pageReq.getAddress())){
             pageWrapper.like(HealthArchives::getAddress,"%"+pageReq.getAddress());
         }

         if(!CheckParam.isNull(pageReq.getIdCardNum())){
             pageWrapper.like(HealthArchives::getIdCardNum,"%"+pageReq.getIdCardNum());
         }

         if(!CheckParam.isNull(pageReq.getContactsName())){
             pageWrapper.like(HealthArchives::getContactsName,"%"+pageReq.getContactsName());
         }

         if(!CheckParam.isNull(pageReq.getContactsPhone())){
             pageWrapper.like(HealthArchives::getContactsPhone,"%"+pageReq.getContactsPhone());
         }

         if(!CheckParam.isNull(pageReq.getTemperature())){
             pageWrapper.eq(HealthArchives::getTemperature,pageReq.getTemperature());
         }

         if(!CheckParam.isNull(pageReq.getStature())){
             pageWrapper.eq(HealthArchives::getStature,pageReq.getStature());
         }

         if(!CheckParam.isNull(pageReq.getRespiratoryRate())){
             pageWrapper.eq(HealthArchives::getRespiratoryRate,pageReq.getRespiratoryRate());
         }

         if(!CheckParam.isNull(pageReq.getPulse())){
             pageWrapper.eq(HealthArchives::getPulse,pageReq.getPulse());
         }

        if(!CheckParam.isNull(pageReq.getPulseMin())){
            pageWrapper.ge(HealthArchives::getPulse,pageReq.getPulseMin());
        }

        if(!CheckParam.isNull(pageReq.getPulseMax())){
            pageWrapper.le(HealthArchives::getPulse,pageReq.getPulseMax());
        }

         if(!CheckParam.isNull(pageReq.getWeight())){
             pageWrapper.eq(HealthArchives::getWeight,pageReq.getWeight());
         }

         if(!CheckParam.isNull(pageReq.getLeftBloodPressureMin())){
             pageWrapper.ge(HealthArchives::getLeftBloodPressure,pageReq.getLeftBloodPressureMin());
         }

        if(!CheckParam.isNull(pageReq.getLeftBloodPressureMax())){
            pageWrapper.le(HealthArchives::getLeftBloodPressure,pageReq.getLeftBloodPressureMax());
        }

        if(!CheckParam.isNull(pageReq.getLeftBloodPressure())){
            pageWrapper.eq(HealthArchives::getLeftBloodPressure,pageReq.getLeftBloodPressure());
        }

         if(!CheckParam.isNull(pageReq.getRightBloodPressure())){
             pageWrapper.eq(HealthArchives::getRightBloodPressure,pageReq.getRightBloodPressure());
         }

         if(!CheckParam.isNull(pageReq.getResidenceType())){
             pageWrapper.eq(HealthArchives::getResidenceType,pageReq.getResidenceType());
         }

         if(!CheckParam.isNull(pageReq.getAuthUserId())){
             pageWrapper.eq(HealthArchives::getAuthUserId,pageReq.getAuthUserId());
         }

         if(!CheckParam.isNull(pageReq.getEndTime())){
             pageWrapper.ge(HealthArchives::getEndTime,pageReq.getEndTime());
         }

         if(!CheckParam.isNull(pageReq.getBeginTime())){
             pageWrapper.le(HealthArchives::getBeginTime,pageReq.getBeginTime());
         }
    }

    /**
     * 更新
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/4/2
     * @param updateReq 更新请求参数
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateItem(HealthArchivesUpdateReq updateReq){
        log.info(">>>>>>>>>>>>>>>>>更新请求参数 {} <<<<<<<<<<<<<<<<", JSON.toJSONString(updateReq));
        String mainId = updateReq.getHealthArchivesId();
        HealthArchives result = healthArchivesRepository.selectOne(new LambdaQueryWrapper<HealthArchives>()
                    .eq(HealthArchives::getHealthArchivesId,mainId));
        if (CheckParam.isNull(result)) {
            return;
        }
        setNeedUpdateItem(result,updateReq);
        healthArchivesRepository.updateById(result);

        String authUserId = authUserService.currentAuthUserId();
        //先删除旧的
        gridArchivesRepository.deleteByArchivesId(mainId);
        String gridUnitId = updateReq.getGridUnitId();
        GridArchives gridArchives = new GridArchives();
        gridArchives.setHealthArchivesId(result.getHealthArchivesId());
        gridArchives.setGridUnitId(gridUnitId);
        gridArchives.setGridArchivesId(SnowflakeIdWorker.uniqueMainId());
        gridArchives.setOperatorId(authUserId);
        try {
            BaseUtil.setFieldValueNotNull(gridArchives);
        } catch (Exception e) {
            log.error("新增->设置为空的属性失败 {} , {} ",e.getMessage(),e);
            throw new BusinessException(ErrorCode.SET_EMPTY_FIELD_ERROR.getCode()
                    ,ErrorCode.SET_EMPTY_FIELD_ERROR.getMessage());
        }
        gridArchivesRepository.insert(gridArchives);
    }

    /**
     * 设置需要更新的字段
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/3/30
     * @param updateReq 更新参数
     * @param entity 产业
     */
    private void setNeedUpdateItem(HealthArchives entity,
        HealthArchivesUpdateReq updateReq){
        if(!CheckParam.isNull(updateReq.getGender())){
            entity.setGender(updateReq.getGender());
        }
        if(!CheckParam.isNull(updateReq.getBirthday())){
            entity.setBirthday(updateReq.getBirthday());
        }
        if(!CheckParam.isNull(updateReq.getRealName())){
            entity.setRealName(updateReq.getRealName());
        }
        if(!CheckParam.isNull(updateReq.getNation())){
            entity.setNation(updateReq.getNation());
        }
        if(!CheckParam.isNull(updateReq.getOccupation())){
            entity.setOccupation(updateReq.getOccupation());
        }
        if(!CheckParam.isNull(updateReq.getAddress())){
            entity.setAddress(updateReq.getAddress());
        }
        if(!CheckParam.isNull(updateReq.getIdCardNum())){
            entity.setIdCardNum(updateReq.getIdCardNum());
        }
        if(!CheckParam.isNull(updateReq.getContactsName())){
            entity.setContactsName(updateReq.getContactsName());
        }
        if(!CheckParam.isNull(updateReq.getContactsPhone())){
            entity.setContactsPhone(updateReq.getContactsPhone());
        }
        if(!CheckParam.isNull(updateReq.getTemperature())){
            entity.setTemperature(updateReq.getTemperature());
        }
        if(!CheckParam.isNull(updateReq.getStature())){
            entity.setStature(updateReq.getStature());
        }
        if(!CheckParam.isNull(updateReq.getRespiratoryRate())){
            entity.setRespiratoryRate(updateReq.getRespiratoryRate());
        }
        if(!CheckParam.isNull(updateReq.getPulse())){
            entity.setPulse(updateReq.getPulse());
        }
        if(!CheckParam.isNull(updateReq.getWeight())){
            entity.setWeight(updateReq.getWeight());
        }
        if(!CheckParam.isNull(updateReq.getLeftBloodPressure())){
            entity.setLeftBloodPressure(updateReq.getLeftBloodPressure());
        }
        if(!CheckParam.isNull(updateReq.getRightBloodPressure())){
            entity.setRightBloodPressure(updateReq.getRightBloodPressure());
        }
        if(!CheckParam.isNull(updateReq.getResidenceType())){
            entity.setResidenceType(updateReq.getResidenceType());
        }
        if(!CheckParam.isNull(updateReq.getAuthUserId())){
            entity.setAuthUserId(updateReq.getAuthUserId());
        }
        if(!CheckParam.isNull(updateReq.getEndTime())){
            entity.setEndTime(updateReq.getEndTime());
        }
        if(!CheckParam.isNull(updateReq.getBeginTime())){
            entity.setBeginTime(updateReq.getBeginTime());
        }
    }
}
