package com.ruoyi.wms.controller;

import com.cmeim.common.core.exception.ServiceException;
import com.cmeim.common.core.utils.BeanUtil;
import com.cmeim.common.core.utils.ExcelExportUtil;
import com.cmeim.common.core.utils.StringUtils;
import com.cmeim.common.core.web.controller.GenericController;
import com.cmeim.common.core.web.domain.Respond;
import com.cmeim.common.core.web.domain.RespondEnum;
import com.cmeim.common.core.web.page.PageVo;
import com.ruoyi.wms.repository.OrderInfoRepository;
import com.ruoyi.wms.repository.ShelfInfoRepository;
import com.ruoyi.wms.po.OrderInfo;
import com.ruoyi.wms.po.ShelfInfo;
import com.google.common.collect.Lists;
import com.ruoyi.ruiYiController.annotation.Log;
import com.ruoyi.ruiYiController.enums.BusinessType;
import com.ruoyi.wms.vo.ContainerInfoExportVo;
import com.ruoyi.wms.vo.ShelfInfoExportVo;
import com.ruoyi.wms.vo.ShelfVo;
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.*;

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 = "shelf")
@Slf4j
public class ShelfController extends GenericController {
    @Autowired
    private ShelfInfoRepository shelfInfoRepository;
    @Autowired
    private OrderInfoRepository orderInfoRepository;

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

    @ApiOperation(value = "根据货架编码查询")
    @GetMapping(value = "listWithoutPage")
    public Respond listWithoutPage(String shelfCode) {
        ShelfInfo shelfInfo = shelfInfoRepository.findByShelfCode(shelfCode);
        ShelfVo shelfVo = BeanUtil.copyProperties(shelfInfo, ShelfVo.class);
        if (StringUtils.isNotBlank(shelfInfo.getProductionTask())) {
            OrderInfo orderInfo = orderInfoRepository.findByProductionTask(shelfInfo.getProductionTask());
            shelfVo.setOrderInfo(orderInfo);
        }
        return buildSuccess(shelfVo);
    }

    @ApiOperation(value = "导出excel")
    @PostMapping("exportExcel")
    public void export(ShelfInfo shelfInfo, HttpServletResponse response) throws Exception {
        List<ShelfInfo> list = shelfInfoRepository.findAll(buildSpecification(shelfInfo));
        List<ShelfInfoExportVo> exportList = new ArrayList<>();
        for(ShelfInfo shelf:list){
            ShelfInfoExportVo shelfInfoExportVo = BeanUtil.copyProperties(shelf, ShelfInfoExportVo.class);
            exportList.add(shelfInfoExportVo);
        }
        // 创建工作簿对象
        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 (ShelfInfoExportVo vo : exportList) {
            if(vo.getShelfStatus() == 5){
                vo.setShelfStatusShow("空闲");
            }else if(vo.getShelfStatus() == 10){
                vo.setShelfStatusShow("占用");
            }else if(vo.getShelfStatus() == 15){
                vo.setShelfStatusShow("禁用");
            }

            if(vo.getOrderStatus() == 5){
                vo.setOrderStatusShow("待校验");
            }else if(vo.getOrderStatus() == 10){
                vo.setOrderStatusShow("校验中");
            }else if(vo.getOrderStatus() == 15){
                vo.setOrderStatusShow("校验完成");
            }else if(vo.getOrderStatus() == 20){
                vo.setOrderStatusShow("待抽检");
            }else if(vo.getOrderStatus() == 25){
                vo.setOrderStatusShow("待出库(缓存区)");
            }else if(vo.getOrderStatus() == 30){
                vo.setOrderStatusShow("待出库(出库位)");
            }else if(vo.getOrderStatus() == 35){
                vo.setOrderStatusShow("出库完成");
            }else if(vo.getOrderStatus() == 40){
                vo.setOrderStatusShow("空箱");
            }

            objs = new Object[rowsName.length];
            objs[0] = i;
            objs[1] = vo.getShelfCode();
            objs[2] = vo.getShelfStatusShow();
            objs[3] = vo.getProductionTask();
            objs[4] = vo.getQty();
            objs[5] = vo.getOrderStatusShow();
            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, "Shelf", workbook);
    }

    @ApiOperation(value = "修改货架状态")
    @Log(title = "货架", businessType = BusinessType.UPDATE)
    @PostMapping(value = "updateShelfStatus")
    public Respond updateStationStatus(@RequestBody ShelfInfo shelfInfo) {
        ShelfInfo shelf = shelfInfoRepository.findByShelfCode(shelfInfo.getShelfCode());
        if (shelf == null) {
            throw new ServiceException(RespondEnum.PARAMETER_ERROR, "未找到该货架");
        }
        //出库完成则清空任务单和优先级
        if (shelfInfo.getShelfStatus() == 35) {
            //修改任务单的出库中数量和出库数量
            OrderInfo orderInfo = orderInfoRepository.findByProductionTask(shelf.getProductionTask());
            orderInfo.setProductOnoutingQty(orderInfo.getProductOnoutingQty() - shelfInfo.getQty());
            orderInfo.setProductOutQty(orderInfo.getProductOutQty() + shelfInfo.getQty());
            orderInfoRepository.save(orderInfo);
            shelf.setQty(0);
            shelf.setProductionTask(null);
            shelf.setPriority(0);
            shelf.setUpdatedBy(shelfInfo.getUpdatedBy());
            shelf.setUpdatedDt(shelfInfo.getUpdatedDt());
            shelfInfoRepository.save(shelf);
        } else {
            shelf.setQty(shelfInfo.getQty());
            shelf.setUpdatedBy(shelfInfo.getUpdatedBy());
            shelf.setUpdatedDt(shelfInfo.getUpdatedDt());
            shelfInfoRepository.save(shelf);
        }
        return buildSuccess();
    }

    @ApiOperation(value = "修改任务单优先级")
    @Log(title = "货架", businessType = BusinessType.UPDATE)
    @PostMapping(value = "updateShelfPriority")
    public Respond updateShelfPriority(String productionTask) {
        List<ShelfInfo> shelfInfoList = shelfInfoRepository.findByProductionTask(productionTask);
        if (shelfInfoList.size() == 0) {
            throw new ServiceException(RespondEnum.PARAMETER_ERROR, "未找到该该任务对应的货架");
        }
        for (ShelfInfo shelfInfo : shelfInfoList) {
            shelfInfo.setPriority(1);
        }
        shelfInfoRepository.saveAll(shelfInfoList);
        return buildSuccess();
    }

    private Specification buildSpecification(ShelfInfo shelfInfo) {
        Specification<ShelfInfo> specification = new Specification<ShelfInfo>() {
            @Override
            public Predicate toPredicate(Root<ShelfInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = Lists.newArrayList();
                if (shelfInfo.getShelfCode() != null) {
                    predicates.add(cb.like(root.get("shelfCode").as(String.class), "%" + shelfInfo.getShelfCode() + "%"));
                }
                if (shelfInfo.getProductionTask() != null) {
                    predicates.add(cb.like(root.get("productionTask").as(String.class), "%" + shelfInfo.getProductionTask() + "%"));
                }
                if (shelfInfo.getShelfStatus() != null) {
                    predicates.add(cb.equal(root.get("shelfStatus").as(Integer.class), shelfInfo.getShelfStatus()));
                }
                if (shelfInfo.getOrderStatus() != null) {
                    predicates.add(cb.equal(root.get("orderStatus").as(Integer.class), shelfInfo.getOrderStatus()));
                }
                if (shelfInfo.getOrderStatusArr() != null) {
                    CriteriaBuilder.In<Integer> in = cb.in(root.get("orderStatus").as(Integer.class));
                    for (Integer status : shelfInfo.getOrderStatusArr()) {
                        in.value(status);
                    }
                    predicates.add(in);
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return specification;
    }
}
