package com.sunda.spmsweb.wmscontroller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmsorder.service.IFileOperationService;
import com.sunda.spmsweb.util.JWTUtil;
import com.sunda.spmswms.dto.WhsSearchDTO;
import com.sunda.spmswms.service.IWhsStorageInventoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/whsInventoryInfo")
@Api(tags = "仓库储位库存信息", description = "仓库储位库存信息接口")
public class WhsStorageInventoryController {

    @Autowired
    IWhsStorageInventoryService iWhsStorageInventoryService;
    
    @Autowired
    IFileOperationService iFileOperationService;

    /* 根据日期获取最近有出入库的贸易货储位库存*/
    @PostMapping("getStorageMByDate")
    @ApiOperation(value = "根据日期获取最近有出入库的贸易货储位库存", notes = "根据日期获取最近有出入库的贸易货储位库存" +
            "{\n" +
            "  \"werks\":\"werks, 要查询的工厂\",\n" +
            "  \"whsLocationCode\":\"whsLocationCode，要查询的仓库代码\",\n" +
            "  \"startDate\":\"2021-05-01 12:00:00\",\n" +
            "  \"endDate\":\"2021-05-21 13:00:00\"\n" +
            "}")
    public ResponseResult getStorageMByDate(@RequestBody JSONObject params) {
        String werks = params.getString("werks");
        String whsLocationCode = params.getString("whsLocationCode");
        String startDate = params.getString("startDate");
        String endDate = params.getString("endDate");
        if (StringUtils.isEmpty(werks) || StringUtils.isEmpty(whsLocationCode)
                || StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
            return ResponseResult.error("werks,whsLocationCode,startDate and endDate are all mandatory required");
        }
        return iWhsStorageInventoryService.getStorageMByDate(werks, whsLocationCode, startDate, endDate);
    }

    /* 根据日期获取最近有出入库的货储位库存*/
    @PostMapping("getStorageByDate")
    @ApiOperation(value = "根据日期获取最近有出入库的储位库存(海外仓适用)", notes = "根据日期获取最近有出入库的储位库存(海外仓适用)" +
            "{\n" +
            "  \"werks\":\"werks, 要查询的工厂\",\n" +
            "  \"whsLocationCode\":\"whsLocationCode，要查询的仓库代码\",\n" +
            "  \"documentType\":\"2\", 查询的日志类型,默认为 2, 1自管仓仓库库存日志；2自管仓储位库存日志；3海外仓仓库库存日志；4海外仓储位库存日志；\n" +
            "  \"startDate\":\"2021-05-01 12:00:00\",\n" +
            "  \"endDate\":\"2021-05-21 13:00:00\"\n" +
            "}")
    public ResponseResult getStorageByDate(@RequestBody JSONObject params) {
        String werks = params.getString("werks");
        String whsLocationCode = params.getString("whsLocationCode");
        String startDate = params.getString("startDate");
        String endDate = params.getString("endDate");
        String documentType=params.getString("documentType");
        if(StringUtils.isEmpty(documentType)){
            documentType="2";
        }
        if (StringUtils.isEmpty(werks) || StringUtils.isEmpty(whsLocationCode)
                || StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
            return ResponseResult.error("werks,whsLocationCode,startDate and endDate are all mandatory required");
        }
        return iWhsStorageInventoryService.getStorageByDate(werks, whsLocationCode, startDate, endDate,documentType);
    }

    /* 根据日期获取最近有出入库的备件货储位库存*/
    @PostMapping("getStorageXByDate")
    @ApiOperation(value = "根据日期获取最近有出入库的备件货储位库存", notes = "根据日期获取最近有出入库的备件货储位库存" +
            "{\n" +
            "  \"werks\":\"werks, 要查询的工厂\",\n" +
            "  \"whsLocationCode\":\"whsLocationCode，要查询的仓库代码\",\n" +
            "  \"startDate\":\"2021-05-01 12:00:00\",\n" +
            "  \"endDate\":\"2021-05-21 13:00:00\"\n" +
            "}")
    public ResponseResult getStorageXByDate(@RequestBody JSONObject params) {
        String werks = params.getString("werks");
        String whsLocationCode = params.getString("whsLocationCode");
        String startDate = params.getString("startDate");
        String endDate = params.getString("endDate");
        if (StringUtils.isEmpty(werks) || StringUtils.isEmpty(whsLocationCode)
                || StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
            return ResponseResult.error("werks,whsLocationCode,startDate and endDate are all mandatory required");
        }
        return iWhsStorageInventoryService.getStorageXByDate(werks, whsLocationCode, startDate, endDate);
    }

    @PostMapping("/updateWhsStorageX")
    @ApiOperation(value = "更新备件货储位库存", notes = "更新备件货储位库存" +
            "{\n" +
            "  \"boxNote\":\"箱码\",\n" +
            "  \"werks\":\"工厂\",\n" +
            "  \"whsLocationCode\":\"仓库代码\",\n" +
            "  \"originalStorageUuid\":\"原储位uuid\",\n" +
            "  \"targetStorageUuid\":\"目标储位uuid\",\n" +
            "  \"documentNumber\":\"关联单据号码\",\n" +
            "  \"remarks\":\"备注,从XX储位移到YY储位\",\n" +
            "}")
    public ResponseResult updateWhsStorageX(@RequestBody JSONObject updateDoc) {
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        return iWhsStorageInventoryService.updateWhsStorageX(updateDoc, userId);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("/getWhsList")
    @ApiOperation(value = "获取指定的储位库存信息-分页", notes = "获取指定的储位库存信息-分页\n" +
            "可以指定所属的工厂，仓库，库区，架，层，格 和储位编号，指定的参数需层层递进，\n" +
            "列如，如果只指定了 werks:['CN0']，未指定二级的仓库与下级的储位信息，则返回CN01这个工厂所有的储位库位" +
            " 如果指定了 werks:['CN01'], whsLocationCode['1061'],storageArea:['A'], 则返回CN01-->1061-->A区下的所有储位库位信息" +
            "{ \n" +
            "  werks:['CN01'], \n" +
            "  whsLocationCode:['1061','1011'], \n" +
            "  storageArea:['A'], \n" +
            "  shelfNo:['01'], \n" +
            "  shelfLayer:['01'], \n" +
            "  shelfCell:['01'], \n" +
            "  storageNo:['A010101'], \n" +
            "  materialNo:['130001915'], \n" +
            "  boxNote:['ZX-10215800004-0303'], \n" +
            "  storageCategory:'X',  X-备件货，M-贸易货\n" +
            "  pageNo: 1,\n" +
            "  pageSize: 20\n" +
            "}", httpMethod = "POST")
    public ResponseResult getWhsList(@RequestBody JSONObject searchCriteria) {
        try {
            List<String> werks = searchCriteria.containsKey("werks") ? (List) searchCriteria.getJSONArray("werks") : null;
            List<String> whsLocationCode = searchCriteria.containsKey("whsLocationCode") ? (List) searchCriteria.getJSONArray("whsLocationCode") : null;
            List<String> storageArea = searchCriteria.containsKey("storageArea") ? (List) searchCriteria.getJSONArray("storageArea") : null;
            List<String> shelfNo = searchCriteria.containsKey("shelfNo") ? (List) searchCriteria.getJSONArray("shelfNo") : null;
            List<String> shelfLayer = searchCriteria.containsKey("shelfLayer") ? (List) searchCriteria.getJSONArray("shelfLayer") : null;
            List<String> shelfCell = searchCriteria.containsKey("shelfCell") ? (List) searchCriteria.getJSONArray("shelfCell") : null;
            List<String> storageNo = searchCriteria.containsKey("storageNo") ? (List) searchCriteria.getJSONArray("storageNo") : null;
            List<String> materialNo = searchCriteria.containsKey("materialNo") ? (List) searchCriteria.getJSONArray("materialNo") : null;
            List<String> boxNote = searchCriteria.containsKey("boxNote") ? (List) searchCriteria.getJSONArray("boxNote") : null;
            String storageCategory = searchCriteria.containsKey("storageCategory") ? searchCriteria.getString("storageCategory") : "";
            int pageNo = StringUtils.isEmpty(searchCriteria.getString("pageNo")) ? 1 : searchCriteria.getInteger("pageNo");
            int pageSize = StringUtils.isEmpty(searchCriteria.getString("pageSize")) ? 20 : searchCriteria.getInteger("pageSize");
            return iWhsStorageInventoryService.getWhsList(werks, whsLocationCode, storageArea,
                    shelfNo, shelfLayer, shelfCell, storageNo, materialNo, storageCategory, boxNote, pageNo, pageSize);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("获取指定的储位库存信息出错");
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("/getStorageInventory")
    @ApiOperation(value = "获取指定的储位库存信息-不分页", notes = "获取指定的储位库存信息-不分页\n" +
            "可以指定所属的工厂，仓库，库区，架，层，格 和储位编号，指定的参数需层层递进，\n" +
            "列如，如果只指定了 werks:['CN0']，未指定二级的仓库与下级的储位信息，则返回CN01这个工厂所有的储位库位" +
            " 如果指定了 werks:['CN01'], whsLocationCode['1061'],storageArea:['A'], 则返回CN01-->1061-->A区下的所有储位库位信息" +
            "export = '0' 表示仅分页查询；export = '1' 表示导出全部数据；" +
            "{ \n" +
            "  werks:['CN01'], \n" +
            "  whsLocationCode:['1061','1011'], \n" +
            "  storageArea:['A'], \n" +
            "  shelfNo:['01'], \n" +
            "  shelfLayer:['01'], \n" +
            "  shelfCell:['01'], \n" +
            "  storageNo:['A010101'], \n" +
            "  materialNo:['130001915'], \n" +
            "  boxNote:['ZX-10215800004-0303'], \n" +
            "  storageCategory:'X',  X-备件货，M-贸易货\n" +
            "  export: '0',\n" +
            "  packageNote: 'BJ-20210900170',\n" +
            "  pageNo: 1,\n" +
            "  pageSize: 20\n" +
            "}", httpMethod = "POST")
    public ResponseResult getStorageInventory(@RequestBody JSONObject searchCriteria) {
        try {
            List<String> werks = searchCriteria.containsKey("werks") ? (List) searchCriteria.getJSONArray("werks") : null;
            List<String> whsLocationCode = searchCriteria.containsKey("whsLocationCode") ? (List) searchCriteria.getJSONArray("whsLocationCode") : null;
            List<String> storageArea = searchCriteria.containsKey("storageArea") ? (List) searchCriteria.getJSONArray("storageArea") : null;
            List<String> shelfNo = searchCriteria.containsKey("shelfNo") ? (List) searchCriteria.getJSONArray("shelfNo") : null;
            List<String> shelfLayer = searchCriteria.containsKey("shelfLayer") ? (List) searchCriteria.getJSONArray("shelfLayer") : null;
            List<String> shelfCell = searchCriteria.containsKey("shelfCell") ? (List) searchCriteria.getJSONArray("shelfCell") : null;
            List<String> storageNo = searchCriteria.containsKey("storageNo") ? (List) searchCriteria.getJSONArray("storageNo") : null;
            List<String> materialNo = searchCriteria.containsKey("materialNo") ? (List) searchCriteria.getJSONArray("materialNo") : null;
            List<String> boxNote = searchCriteria.containsKey("boxNote") ? (List) searchCriteria.getJSONArray("boxNote") : null;
            String storageCategory = searchCriteria.containsKey("storageCategory") ? searchCriteria.getString("storageCategory") : "";
            String searchInfo = searchCriteria.containsKey("searchInfo") ? searchCriteria.getString("searchInfo") : "";
            String packageNote = searchCriteria.containsKey("packageNote") ? searchCriteria.getString("packageNote") : "";
            return iWhsStorageInventoryService.getWhsStorageInventory(werks, whsLocationCode, storageArea,
                    shelfNo, shelfLayer, shelfCell, storageNo, materialNo, storageCategory, boxNote, searchInfo, packageNote);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("获取指定的储位库存信息出错");
        }
    }

    @RequestMapping("/getAvailableQtyByUuidBoxNote")
    @ApiOperation(value = "获取储位箱码可用库存", notes = "新建仓库储位", httpMethod = "POST")
    public ResponseResult getAvailableQtyByUuidBoxNote(String storageUuid, String boxNote) {

        return ResponseResult.success().add("info", iWhsStorageInventoryService.getAvailableQtyByUuidBoxNote(storageUuid, boxNote));
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
	@PostMapping("/getWSInventory")
    @ApiOperation(value = "获取多个物料或是箱码的储信库存", notes = "获取多个物料或是箱码的储信库存 \n" +
            "{\n" +
            "  \"materialNo\":[\"material1\",\"material2\"],\n" +
            "  \"boxNote\":[\"box1\",\"box2\"],\n" +
            "  \"werks\":\"CN01\",\n" +
            "  \"whsLocationCode\":\"1061\"\n" +
            "}"
    )
    public ResponseResult getWSInventory(@RequestBody JSONObject jsonObject) {
        try {
            List<String> materialNo = jsonObject.containsKey("materialNo") ? (List) jsonObject.getJSONArray("materialNo") : null;
            List<String> boxNote = jsonObject.containsKey("boxNote") ? (List) jsonObject.getJSONArray("boxNote") : null;
            String werks = jsonObject.getString("werks");
            String whsLocationCode = jsonObject.getString("whsLocationCode");
            return iWhsStorageInventoryService.getWSInventory(werks, whsLocationCode, materialNo, boxNote);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("获取指定的储位库存信息出错");
        }
    }
    
    @RequestMapping("/getWhsStockList")
    @ApiOperation(value = "国内仓库存明细报表报表", notes = "国内仓库存明细报表报表\n" +
    		"所有参数可选输入。示例参数：\n" +
            "{\n" +
            "werks = TF02,\n" +
            "whsLocationCode = 1006,\n" +
            "goodsType = M,\n" +
            "storageNo = B010101,\n" +
            "searchInfo = 210017651,\n" +
            "packageNote = 210017651,\n" +
            "boxNote = 0,\n" +
            "pageNo = 1,\n" +
            "pageSize = 20" +
            "}\n", httpMethod = "POST")
    @RequiresPermissions("whsInventoryInfo-getWhsStockList")
    public ResponseResult getWhsStockList(@RequestBody WhsSearchDTO dto){
        try {
        	if (StringUtils.isEmpty(dto.getWerks()) && CollectionUtils.isEmpty(dto.getWerksList())) {
    			return ResponseResult.error("请求工厂不能为空");
    		}
    		if (StringUtils.isEmpty(dto.getWhsLocationCode()) && CollectionUtils.isEmpty(dto.getWerksList())) {
    			return ResponseResult.error("仓库编号不能为空");
    		}
            return iWhsStorageInventoryService.getWhsStockList(dto);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("请求数据失败").add("error", e.getMessage());
        }
    }
    
    @RequestMapping("/exportWhsStockQtyExcel")
    @ApiOperation(value = "国内仓库存明细报表报表导出EXCEL", notes = "国内仓库存明细报表报表导出EXCEL\n" +
    		"所有参数可选输入。示例参数：\n" +
            "{\n" +
            "werks = TF02,\n" +
            "whsLocationCode = 1006,\n" +
            "goodsType = M,\n" +
            "storageNo = B010101,\n" +
            "searchInfo = 210017651,\n" +
            "packageNote = 210017651,\n" +
            "boxNote = 0\n" +
            "}\n", httpMethod = "POST")
    @RequiresPermissions("whsInventoryInfo-exportWhsStockQtyExcel")
    public ResponseResult exportWhsStockQtyExcel(@RequestBody WhsSearchDTO dto){
        try {
        	if (StringUtils.isEmpty(dto.getWerks())) {
    			return ResponseResult.error("请求工厂不能为空");
    		}
    		if (StringUtils.isEmpty(dto.getWhsLocationCode())) {
    			return ResponseResult.error("仓库编号不能为空");
    		}
    		dto.setPageNo(1);
    		dto.setPageSize(Integer.MAX_VALUE);
            String filename = "WhsStockQty_" + System.currentTimeMillis()+".xlsx";
            // 1.附件缓存路径
            String excelPath = iFileOperationService.saveWhsStockQtyExcel(iWhsStorageInventoryService.getWhsStockList(dto), filename);
            if (StringUtils.isEmpty(excelPath)){
                return ResponseResult.error("附件创建失败");
            }
            // 2.上传附件至minIO文件服务器
            String fileUrl = iFileOperationService.fileUploader(filename, excelPath);
            if (fileUrl.isEmpty()){
                return ResponseResult.error("附件上传失败:" + excelPath + "--" + fileUrl);
            }
            // 3.返回附件地址，上传OA
            return ResponseResult.success().add("fileUrl",fileUrl);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("请求数据失败").add("error", e.getMessage());
        }
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@PostMapping("/getWSInventoryByBoxNote")
    @ApiOperation(value = "获取多个箱码的储信库存", notes = "获取多个箱码的储信库存 \n" +
            "{\n" +
            "  \"materialNo\":[\"material1\",\"material2\"],\n" +
            "  \"boxNote\":[\"box1\",\"box2\"],\n" +
            "  \"werks\":\"CN01\",\n" +
            "  \"whsLocationCode\":\"1061\"\n" +
            "}"
    )
    public ResponseResult getWSInventoryByBoxNote(@RequestBody JSONObject jsonObject) {
        try {
            List<String> boxNote = jsonObject.containsKey("boxNote") ? (List) jsonObject.getJSONArray("boxNote") : null;
            if (CollectionUtils.isEmpty(boxNote)) {
            	return ResponseResult.error("所传箱码参数为空,获取箱码的储位库存信息出错");
            }
            return iWhsStorageInventoryService.getWSInventoryByBoxNote(boxNote);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("获取箱码的储位库存信息出错");
        }
    }
}
