package com.ruoyi.wms.controller;

import com.cmeim.common.core.utils.BeanUtil;
import com.cmeim.common.core.utils.ExcelExportUtil;
import com.cmeim.common.core.web.controller.GenericController;
import com.cmeim.common.core.web.domain.Respond;
import com.cmeim.common.core.web.page.PageVo;
import com.ruoyi.wms.po.StationInfo;
import com.ruoyi.wms.repository.StoreInfoRepository;
import com.ruoyi.wms.po.StoreInfo;
import com.google.common.collect.Lists;
import com.ruoyi.wms.vo.StationInfoExportVo;
import com.ruoyi.wms.vo.StoreInfoExportVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 李俊辉
 * @version 1.0
 * date: 2023/6/28
 */
@Api(tags = "库位")
@RestController
@RequestMapping(value = "store")
@Slf4j
public class StoreController extends GenericController {
    @Autowired
    private StoreInfoRepository storeInfoRepository;

    @ApiOperation(value = "列表")
    @GetMapping(value = "list")
    public Respond list(PageVo pv, StoreInfo storeInfo) {
        PageRequest pageRequest = PageRequest.of(pv.getPageNo() - 1, pv.getPageSize(),
                Sort.by(sortOrder(storeInfo.getOrders())));
        Page page = storeInfoRepository.findAll(buildSpecification(storeInfo), pageRequest);
        List<StoreInfo> list = page.getContent();
        pv.setRecordsTotal(page.getTotalElements());
        pv.setData(list);
        return buildSuccess(pv);
    }

    @ApiOperation(value = "导出excel")
    @PostMapping("exportExcel")
    public void export(StoreInfo storeInfo, HttpServletResponse response) throws Exception {
        List<StoreInfo> list = storeInfoRepository.findAll(buildSpecification(storeInfo));
        List<StoreInfoExportVo> exportList = new ArrayList<>();
        for(StoreInfo store:list){
            StoreInfoExportVo storeInfoExportVo = BeanUtil.copyProperties(store, StoreInfoExportVo.class);
            exportList.add(storeInfoExportVo);
        }
        // 创建工作簿对象
        SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
        // 创建工作表
        SXSSFSheet sheet = workbook.createSheet("周转箱列表");

        String[] rowsName = new String[]{"序号","库位编码","库位类型","库位状态","库位属于的工位编码","货架编码","创建人","创建时间","更新人","更新时间"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs = null;
        int i = 1;
        for (StoreInfoExportVo vo : exportList) {
            if(vo.getStoreStatus() == 5){
                vo.setStoreStatusShow("空闲");
            }else if(vo.getStoreStatus() == 10){
                vo.setStoreStatusShow("待占用");
            }else if(vo.getStoreStatus() == 15){
                vo.setStoreStatusShow("占用");
            }else if(vo.getStoreStatus() == 20){
                vo.setStoreStatusShow("待空闲");
            }

            if(vo.getStoreType() == 5){
                vo.setStoreTypeShow("干湿库位");
            }else if(vo.getStoreType() == 10){
                vo.setStoreTypeShow("缓存库位");
            }else if(vo.getStoreType() == 15){
                vo.setStoreTypeShow("检验库位");
            }else if(vo.getStoreType() == 20){
                vo.setStoreTypeShow("抽检库位");
            }else if(vo.getStoreType() == 25){
                vo.setStoreTypeShow("成品缓存库位");
            } else if(vo.getStoreType() == 30){
                vo.setStoreTypeShow("成品出库库位");
            }else if(vo.getStoreType() == 35){
                vo.setStoreTypeShow("空车回库库位");
            }

            objs = new Object[rowsName.length];
            objs[0] = i;
            objs[1] = vo.getStoreCode();
            objs[2] = vo.getStoreTypeShow();
            objs[3] = vo.getStoreStatusShow();
            objs[4] = vo.getStationCode();
            objs[5] = vo.getShelfCode();
            objs[6] = vo.getCreatedBy();
            objs[7] = vo.getCreatedDt();
            objs[8] = vo.getUpdatedBy();
            objs[9] = vo.getUpdatedDt();
            dataList.add(objs);
            i += 1;
        }
        ExcelExportUtil.getExportWorkbook(workbook, sheet, rowsName, dataList);
        ExcelExportUtil.sendHttpResponse(response, "Store", workbook);
    }

    private Specification buildSpecification(StoreInfo storeInfo) {
        Specification<StoreInfo> specification = new Specification<StoreInfo>() {
            @Override
            public Predicate toPredicate(Root<StoreInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = Lists.newArrayList();
                if (storeInfo.getStationCode() != null) {
                    predicates.add(cb.like(root.get("stationCode").as(String.class), "%" + storeInfo.getStationCode() + "%"));
                }
                if (storeInfo.getStoreCode() != null) {
                    predicates.add(cb.like(root.get("storeCode").as(String.class), "%" + storeInfo.getStoreCode() + "%"));
                }
                if (storeInfo.getShelfCode() != null) {
                    predicates.add(cb.like(root.get("shelfCode").as(String.class), "%" + storeInfo.getShelfCode() + "%"));
                }
                if (storeInfo.getStoreStatus() != null) {
                    predicates.add(cb.equal(root.get("storeStatus").as(Integer.class), storeInfo.getStoreStatus()));
                }
                if (storeInfo.getStoreType() != null) {
                    predicates.add(cb.equal(root.get("storeType").as(Integer.class), storeInfo.getStoreType()));
                }
                if (storeInfo.getStoreStatusArr() != null) {
                    CriteriaBuilder.In<Integer> in = cb.in(root.get("storeStatus").as(Integer.class));
                    for (Integer status : storeInfo.getStoreStatusArr()) {
                        in.value(status);
                    }
                    predicates.add(in);
                }
                if (storeInfo.getStoreTypeArr() != null) {
                    CriteriaBuilder.In<Integer> in = cb.in(root.get("storeType").as(Integer.class));
                    for (Integer status : storeInfo.getStoreTypeArr()) {
                        in.value(status);
                    }
                    predicates.add(in);
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return specification;
    }
}
