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.req.GridUnitAddReq;
import cn.common.req.GridUnitReq;
import cn.common.req.GridUnitUpdateReq;
import cn.common.interaction.resp.page.Pagination;
import cn.common.resp.GridUnitResp;
import cn.common.req.GridUnitImportReq;
import cn.common.resp.GridUnitExportResp;
import cn.common.repository.entity.GridUnit;
import cn.common.repository.repository.GridUnitRepository;
import cn.common.service.AuthUserService;
import cn.common.service.GridUnitService;
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.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.collect.Maps;
import java.util.Map;

/**
* @author Singer create by Singer email:singer-coder@qq.com
* @packageName cn.common.service
* @Description: 网格信息相关服务方法实现
* @date 2021-04-23
*/
@Service("gridUnitService")
@Slf4j
public class GridUnitServiceImpl implements GridUnitService {

    @Resource
    private GridUnitRepository gridUnitRepository;

    @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(GridUnitReq pageReq){
        log.info(">>>>>>>>>>>>>>>>>数据导出Req {} <<<<<<<<<<<<<<<<", JSON.toJSONString(pageReq));
        //构建查询条件
        LambdaQueryWrapper<GridUnit> pageWrapper = new LambdaQueryWrapper<>();
        setPageCriteria(pageWrapper,pageReq);
        pageWrapper.orderBy(true,false,GridUnit::getCreateTime);
        List<GridUnit> pageList = gridUnitRepository.selectList(pageWrapper);
        if (CollectionUtils.isEmpty(pageList)) {
            return;
        }
        List<GridUnitExportResp> respList =
            mapperFacade.mapAsList(pageList, GridUnitExportResp.class);
        try {
            String fileName = "导出信息.xlsx";
            ExportExcelHandler.setExportResponse(response,fileName);
            ExcelWriter excelWriter = null;
            try {
                // 这里 需要指定写用哪个class去写
                excelWriter = EasyExcel.write(response.getOutputStream(), GridUnitExportResp.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<GridUnitImportReq> dataList = EasyExcel
                .read(file.getInputStream()).head(GridUnitImportReq.class).sheet().doReadSync();
            if(CollectionUtils.isEmpty(dataList)){
                return;
            }
            //进行必要的字段校验
            ValidationUtil.validate(dataList);
            dataList.stream().forEach(item -> {
                GridUnit entity = mapperFacade.map(item, GridUnit.class);
                try {
                    String authUserId = authUserService.currentAuthUserId();
                    BaseUtil.setFieldValueNotNull(entity);
                    entity.setGridUnitId(SnowflakeIdWorker.uniqueMainId());
                    entity.setOperatorId(authUserId);
                } catch (Exception e) {
                    log.error("导入->设置为空的属性失败 {} , {} ",e.getMessage(),e);
                }
                gridUnitRepository.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(GridUnitAddReq addReq){
        log.info(">>>>>>>>>>>>>>>>>新增Req {} <<<<<<<<<<<<<<<<", JSON.toJSONString(addReq));
        String authUserId = authUserService.currentAuthUserId();
        GridUnit entity = mapperFacade.map(addReq, GridUnit.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.setGridUnitId(SnowflakeIdWorker.uniqueMainId());
        entity.setOperatorId(authUserId);
        gridUnitRepository.insert(entity);
    }

    /**
     * 批量删除信息
     * @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<GridUnit> entityList = gridUnitRepository.selectList(
            new LambdaQueryWrapper<GridUnit>().in(GridUnit::getGridUnitId,mainIdList));
        entityList.stream().forEach(item -> {
            gridUnitRepository.deleteById(item);
        });
    }

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

    /**
     * 分页查询
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/2/15
     * @param  pageReq 分页查询Req
     * @return Pagination
     */
    @Override
    public Pagination<GridUnitResp> queryByPage(
        GridUnitReq pageReq){
        log.info(">>>>>>>>>>>>>>>>>分页查询Req {} <<<<<<<<<<<<<<<<", JSON.toJSONString(pageReq));
        //构建查询条件
        LambdaQueryWrapper<GridUnit> pageWrapper = new LambdaQueryWrapper<>();
        setPageCriteria(pageWrapper,pageReq);
        pageWrapper.orderBy(true,false,GridUnit::getCreateTime);
        //开始分页
        Page<Object> page = PageHelper.startPage(pageReq.getCurrentPage(), pageReq.getItemsPerPage());
        List<GridUnit> pageList = gridUnitRepository.selectList(pageWrapper);
        if (CollectionUtils.isEmpty(pageList)) {
            return PageBuilder.buildPageResult(page,new ArrayList<>());
        }
        List<GridUnitResp> respList =
            mapperFacade.mapAsList(pageList, GridUnitResp.class);
        Integer startIndex = (pageReq.getItemsPerPage() * pageReq.getCurrentPage()) - pageReq.getItemsPerPage() + 1;
        AtomicInteger idBeginIndex = new AtomicInteger(startIndex);
            respList.stream().forEach(item -> {
                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<GridUnit> pageWrapper, GridUnitReq pageReq){

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

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

    /**
     * 更新
     * @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(GridUnitUpdateReq updateReq){
        log.info(">>>>>>>>>>>>>>>>>更新请求参数 {} <<<<<<<<<<<<<<<<", JSON.toJSONString(updateReq));
        String mainId = updateReq.getGridUnitId();
        GridUnit result = gridUnitRepository.selectOne(new LambdaQueryWrapper<GridUnit>()
                    .eq(GridUnit::getGridUnitId,mainId));
        if (CheckParam.isNull(result)) {
            return;
        }
        setNeedUpdateItem(result,updateReq);
        gridUnitRepository.updateById(result);
    }

    /**
     * 设置需要更新的字段
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/3/30
     * @param updateReq 更新参数
     * @param entity 产业
     */
    private void setNeedUpdateItem(GridUnit entity,
        GridUnitUpdateReq updateReq){
        if(!CheckParam.isNull(updateReq.getUnitName())){
            entity.setUnitName(updateReq.getUnitName());
        }
        if(!CheckParam.isNull(updateReq.getUnitDescription())){
            entity.setUnitDescription(updateReq.getUnitDescription());
        }
    }
}
