package com.ruoyi.web.controller.business;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.ruoyi.business.domain.EbsStock;
import com.ruoyi.business.domain.TBaseGoods;
import com.ruoyi.business.domain.TMiStock;
import com.ruoyi.business.service.ITBaseGoodsService;
import com.ruoyi.business.service.ITMiStockService;
import com.ruoyi.business.utils.EbsUtils;
import com.ruoyi.business.utils.OrderCodeFactory;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysConfigService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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.ResponseBody;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * EBS现有量
 *
 * @author 梁州
 */
@Controller
@RequestMapping("/business/ebsConfirm")
public class EbsConfirmController extends BaseController {
    private String prefix = "business/ebsConfirm";
    // 现有量记录报表（导出用）
    List<EbsStock> ebsStockListForExport;
    // 现有量记录报表（导出用）-按批次
    List<EbsStock> ebsStockLotListForExport;

    @Autowired
    private ITMiStockService tMiStockService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private ITBaseGoodsService goodsService;

    /**
     * EBS现有量界面
     *
     * @param mmap
     * @return
     */
    @RequiresPermissions("business:ebsConfirm:view")
    @GetMapping("/ebsConfirm")
    public String ebsConfirm(ModelMap mmap) {
        mmap.put("ebsStock", new EbsStock());
        return prefix + "/ebsConfirm";
    }

    /**
     * EBS现有量界面（按批次）
     *
     * @param mmap
     * @return
     */
    @RequiresPermissions("business:ebsConfirm:view")
    @GetMapping("/ebsConfirmLot")
    public String ebsConfirmLot(ModelMap mmap) {
        mmap.put("ebsStock", new EbsStock());
        return prefix + "/ebsConfirmLot";
    }

    /**
     * EBS现有量主界面
     */
    @RequiresPermissions("business:ebsConfirm:list")
    @Log(title = "查询EBS现有量", businessType = BusinessType.INSERT)
    @PostMapping("/ebsConfirm/main")
    @ResponseBody
    public TableDataInfo ebsConfirmMain(EbsStock ebsStock) throws Exception {
        TMiStock stockForQuery = new TMiStock();
        stockForQuery.setGoodsId(ebsStock.getGoodsId());
        stockForQuery.setWhseloc(ebsStock.getSubInventory());
        // 库存信息
        List<TMiStock> stockList = tMiStockService.selectTMiStockOutList(stockForQuery);
        // EBS现有量查询结果
        List<EbsStock> ebsStockList = new LinkedList<>();
        if (stockList.size() < 1) {
            return getDataTable(ebsStockList);
        }
        // 获取token
        JSONObject token = JSON.parseObject(HttpUtils.httpPostJson(configService.selectConfigByKey("token_ip"), "", ""));
        // 一起查询
        String params = JSON.toJSONString(createJsonList(stockList, ebsStock.getSubInventory(), null));
        String result = HttpUtils.httpPostJson(configService.selectConfigByKey("ebs_ip"), params, token.get("access_token").toString());
        JSONObject resultJson = (JSONObject) JSON.parseObject(result).get("obj");
        List<ExistingStock> datas = JSON.parseArray(resultJson.getString("rows"), ExistingStock.class);
        // 生成现有量数据
        for (TMiStock stock : stockList) {
            // 插入的EBS现有量数据
            EbsStock temp = new EbsStock();
            // 查询结果返回的总量
            int sum = 0;
            for (ExistingStock existingStock : datas) {
                if (stock.getGoodsId().equals(existingStock.getItemCode())) {
                    sum += existingStock.getTransactionQuantity();
                }
            }
            // 设定EBS现有量的数据
            temp.setGoodsId(stock.getGoodsId());
            temp.setGoodsName(stock.getGoodsName());
            temp.setSubInventory(ebsStock.getSubInventory());
            temp.setEbsNum(BigDecimal.valueOf(sum));
            temp.setWmsNum(stock.getShelvesNum());
            if (BigDecimal.valueOf(sum).compareTo(stock.getShelvesNum()) != 0) {
                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
                temp.setSts("0");
            } else {
                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
                temp.setSts("1");
            }
            ebsStockList.add(temp);
        }

        // 更新逻辑
        // 1. 传参变化：只传子库
//        String params = JSON.toJSONString(createJsonGetAll(ebsStock.getSubInventory()));
//        String result = HttpUtils.httpPostJson(configService.selectConfigByKey("ebs_ip"), params, token.get("access_token").toString());
//        JSONObject resultJson = (JSONObject) JSON.parseObject(result).get("obj");
//        List<ExistingStock> datas = JSON.parseArray(resultJson.getString("rows"), ExistingStock.class);
//        // 根据本地中库存生成一次现有量数据
//        for (TMiStock stock : stockList) {
//            // 插入的EBS现有量数据
//            EbsStock temp = new EbsStock();
//            // 查询结果返回的总量
//            int sum = 0;
//            for (ExistingStock existingStock : datas) {
//                if (stock.getGoodsId().equals(existingStock.getItemCode())) {
//                    sum += existingStock.getTransactionQuantity();
//                }
//            }
//            // 设定EBS现有量的数据
//            temp.setGoodsId(stock.getGoodsId());
//            temp.setGoodsName(stock.getGoodsName());
//            temp.setSubInventory(ebsStock.getSubInventory());
//            temp.setEbsNum(BigDecimal.valueOf(sum));
//            temp.setWmsNum(stock.getShelvesNum());
//            if (BigDecimal.valueOf(sum).compareTo(stock.getShelvesNum()) != 0) {
//                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
//                temp.setSts("0");
//            } else {
//                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
//                temp.setSts("1");
//            }
//            ebsStockList.add(temp);
//        }
//        // 将本地库存中不存在的数据添加进现有量列表
//        for (ExistingStock existingStock : datas) {
//            // 判断当前物料是否已经存在
//            if (ebsStockList.stream().anyMatch(ebsStock1 -> ebsStock1.getGoodsId().equals(existingStock.getItemCode()))) {
//                continue;
//            }
//            // 插入的EBS现有量数据
//            EbsStock temp = new EbsStock();
//            // 对不存在的库存数据进行处理
//            int sum = 0;
//            for (ExistingStock existingStock1 : datas) {
//                if (existingStock.getItemCode().equals(existingStock1.getItemCode())) {
//                    sum += existingStock1.getTransactionQuantity();
//                }
//            }
//            // 先查询物料表，根据当前的物料编码
//            TBaseGoods goodsTemp = goodsService.selectTBaseGoodsByGoodsId(existingStock.getItemCode());
//            // 设定EBS现有量的数据
//            temp.setGoodsId(existingStock.getItemCode());
//            if (goodsTemp != null) {
//                temp.setGoodsName(goodsTemp.getGoodsName());
//            }
//            temp.setSubInventory(existingStock.getSubinventoryCode());
//            temp.setEbsNum(BigDecimal.valueOf(sum));
//            temp.setWmsNum(BigDecimal.valueOf(0));
//            temp.setDiffNum(BigDecimal.valueOf(sum));
//            temp.setSts("0");
//            ebsStockList.add(temp);
//        }

        // 将不平衡的放到前面
        ebsStockList.sort(Comparator.comparing(EbsStock::getSts));
        // 将当前查询出的现有量保存到导出缓存中
        ebsStockListForExport = new ArrayList<>(ebsStockList);
        logger.info("当前现有量数据：{}", JSON.toJSONString(ebsStockListForExport));

        // 返回分页数据
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        TableDataInfo rspData = new TableDataInfo();
        // 分页数据设置
        rspData.setCode(0);
        rspData.setRows(PageUtils.startPageByList(ebsStockList, pageNum, pageSize));
        rspData.setTotal(new PageInfo(ebsStockList).getTotal());
        return rspData;
    }

    /**
     * EBS现有量（按批次）主界面
     */
    @RequiresPermissions("business:ebsConfirm:list")
    @Log(title = "查询EBS现有量（按批次）", businessType = BusinessType.INSERT)
    @PostMapping("/ebsConfirmLot/main")
    @ResponseBody
    public TableDataInfo ebsConfirmLotMain(EbsStock ebsStock) throws Exception {
        TMiStock stockForQuery = new TMiStock();
        stockForQuery.setGoodsId(ebsStock.getGoodsId());
        stockForQuery.setProduclotid(ebsStock.getLotNumber());
        stockForQuery.setWhseloc(ebsStock.getSubInventory());
        // 库存信息
        List<TMiStock> stockList = tMiStockService.selectTMiStockOutListByLot(stockForQuery);
        // EBS现有量查询结果
        List<EbsStock> ebsStockList = new LinkedList<>();
        if (stockList.size() < 1) {
            return getDataTable(ebsStockList);
        }
        // 获取token
        JSONObject token = JSON.parseObject(HttpUtils.httpPostJson(configService.selectConfigByKey("token_ip"), "", ""));
        // 一起查询
        String params = JSON.toJSONString(createJsonList(stockList, ebsStock.getSubInventory(), null));
        String result = HttpUtils.httpPostJson(configService.selectConfigByKey("ebs_ip"), params, token.get("access_token").toString());
        JSONObject resultJson = (JSONObject) JSON.parseObject(result).get("obj");
        List<ExistingStock> datas = JSON.parseArray(resultJson.getString("rows"), ExistingStock.class);
        // 生成现有量数据
        for (TMiStock stock : stockList) {
            // 插入的EBS现有量数据
            EbsStock temp = new EbsStock();
            // 查询结果返回的总量
            int sum = 0;
            for (ExistingStock existingStock : datas) {
                if (stock.getGoodsId().equals(existingStock.getItemCode()) && stock.getProduclotid().equals(existingStock.getLotNumber())) {
                    sum += existingStock.getTransactionQuantity();
                }
            }
            // 设定EBS现有量的数据
            temp.setGoodsId(stock.getGoodsId());
            temp.setGoodsName(stock.getGoodsName());
            temp.setLotNumber(stock.getProduclotid());
            temp.setSubInventory(ebsStock.getSubInventory());
            temp.setEbsNum(BigDecimal.valueOf(sum));
            temp.setWmsNum(stock.getShelvesNum());
            if (BigDecimal.valueOf(sum).compareTo(stock.getShelvesNum()) != 0) {
                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
                temp.setSts("0");
            } else {
                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
                temp.setSts("1");
            }
            ebsStockList.add(temp);
        }

        // 更新逻辑
        // 1. 传参变化：只传子库
//        String params = JSON.toJSONString(createJsonGetAll(ebsStock.getSubInventory()));
//        String result = HttpUtils.httpPostJson(configService.selectConfigByKey("ebs_ip"), params, token.get("access_token").toString());
//        JSONObject resultJson = (JSONObject) JSON.parseObject(result).get("obj");
//        List<ExistingStock> datas = JSON.parseArray(resultJson.getString("rows"), ExistingStock.class);
//        // 根据本地中库存生成一次现有量数据
//        for (TMiStock stock : stockList) {
//            // 插入的EBS现有量数据
//            EbsStock temp = new EbsStock();
//            // 查询结果返回的总量
//            int sum = 0;
//            if (StringUtils.isEmpty(stock.getProduclotid())) {// 本地库存批次号为空
//                for (ExistingStock existingStock : datas) {
//                    if (stock.getGoodsId().equals(existingStock.getItemCode())) {
//                        sum += existingStock.getTransactionQuantity();
//                    }
//                }
//            } else {
//                for (ExistingStock existingStock : datas) {
//                    if (StringUtils.isEmpty(existingStock.getLotNumber())) {// 批次号为空
//                        continue;
//                    }
//                    if (stock.getGoodsId().equals(existingStock.getItemCode()) && stock.getProduclotid().equals(existingStock.getLotNumber())) {
//                        sum += existingStock.getTransactionQuantity();
//                    }
//                }
//            }
//            // 设定EBS现有量的数据
//            temp.setGoodsId(stock.getGoodsId());
//            temp.setGoodsName(stock.getGoodsName());
//            temp.setLotNumber(stock.getProduclotid());
//            temp.setSubInventory(ebsStock.getSubInventory());
//            temp.setEbsNum(BigDecimal.valueOf(sum));
//            temp.setWmsNum(stock.getShelvesNum());
//            if (BigDecimal.valueOf(sum).compareTo(stock.getShelvesNum()) != 0) {
//                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
//                temp.setSts("0");
//            } else {
//                temp.setDiffNum(BigDecimal.valueOf(sum).subtract(stock.getShelvesNum()));
//                temp.setSts("1");
//            }
//            ebsStockList.add(temp);
//        }
//        // 将本地库存中不存在的数据添加进现有量列表
//        for (ExistingStock existingStock : datas) {
//            if (StringUtils.isEmpty(existingStock.getLotNumber())) {
//                continue;
//            }
//            // 判断当前物料是否已经存在
//            if (ebsStockList.stream().anyMatch(ebsStock1 -> ebsStock1.getGoodsId().equals(existingStock.getItemCode()) && ebsStock1.getLotNumber().equals(existingStock.getLotNumber()))) {
//                continue;
//            }
//            // 插入的EBS现有量数据
//            EbsStock temp = new EbsStock();
//            // 对不存在的库存数据进行处理
//            int sum = 0;
//            for (ExistingStock existingStock1 : datas) {
//                if (existingStock.getItemCode().equals(existingStock1.getItemCode()) && existingStock.getLotNumber().equals(existingStock1.getLotNumber())) {
//                    sum += existingStock1.getTransactionQuantity();
//                }
//            }
//            // 先查询物料表，根据当前的物料编码
//            TBaseGoods goodsTemp = goodsService.selectTBaseGoodsByGoodsId(existingStock.getItemCode());
//            // 设定EBS现有量的数据
//            temp.setGoodsId(existingStock.getItemCode());
//            if (goodsTemp != null) {
//                temp.setGoodsName(goodsTemp.getGoodsName());
//            }
//            temp.setLotNumber(existingStock.getLotNumber());
//            temp.setSubInventory(existingStock.getSubinventoryCode());
//            temp.setEbsNum(BigDecimal.valueOf(sum));
//            temp.setWmsNum(BigDecimal.valueOf(0));
//            temp.setDiffNum(BigDecimal.valueOf(sum));
//            temp.setSts("0");
//            ebsStockList.add(temp);
//        }

        // 将不平衡的放到前面
        ebsStockList.sort(Comparator.comparing(EbsStock::getSts));
        // 将当前查询出的现有量保存到导出缓存中
        ebsStockLotListForExport = new ArrayList<>(ebsStockList);
        logger.info("当前现有量数据(带批次)：{}", JSON.toJSONString(ebsStockLotListForExport));

        // 返回分页数据
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(0);
        rspData.setRows(PageUtils.startPageByList(ebsStockList, pageNum, pageSize));
        rspData.setTotal(new PageInfo(ebsStockList).getTotal());
        return rspData;
    }

    /**
     * 导出EBS现有量记录
     */
    @RequiresPermissions("business:ebsConfirm:export")
    @Log(title = "导出EBS现有量记录", businessType = BusinessType.EXPORT)
    @PostMapping("/ebsConfirm/export")
    @ResponseBody
    public AjaxResult export() {
        ExcelUtil<EbsStock> util = new ExcelUtil<EbsStock>(EbsStock.class);
        return util.exportExcel(ebsStockListForExport, "EBS现有量");
    }

    /**
     * 导出EBS现有量记录
     */
    @RequiresPermissions("business:ebsConfirm:export")
    @Log(title = "导出EBS现有量(按批次)记录", businessType = BusinessType.EXPORT)
    @PostMapping("/ebsConfirmLot/export")
    @ResponseBody
    public AjaxResult exportLot() {
        ExcelUtil<EbsStock> util = new ExcelUtil<EbsStock>(EbsStock.class);
        return util.exportExcel(ebsStockLotListForExport, "EBS现有量（按批次）");
    }

    /**
     * 创建参数Json
     *
     * @return
     */
    public JSONObject createJsonGetAll(String subInventoryCode) {
        // 创建系统参数
        JSONObject systemParams = new JSONObject();
        systemParams.put("requestId", OrderCodeFactory.getOrderCode("ebs", ""));
        systemParams.put("application", "NT_WMS");
        systemParams.put("sourceSystem", "NT_WMS");
        systemParams.put("targetSystem", "EBS");
        systemParams.put("serviceName", "getExistingStock");
        systemParams.put("nonce", 1);
        systemParams.put("timestamp", 1);
        systemParams.put("serviceOperation", "S");
        systemParams.put("serviceVersion", "1.0");
        systemParams.put("token", "fd");

        // 创建查询参数
        JSONObject baseQueryParams = new JSONObject();
        baseQueryParams.put("organizationId", configService.selectConfigByKey("organizationId"));
        baseQueryParams.put("startPosition", 1);
        baseQueryParams.put("rowsCnt", 2000);

        // 创建数据
        JSONObject businessData = new JSONObject();
        businessData.put("itemCode", null);
        businessData.put("subInventoryCode", subInventoryCode);
        businessData.put("locatorId", EbsUtils.LOCATOR_AREA_MAP.get(subInventoryCode));
        businessData.put("lotNumber", null);

        JSONArray jsonArray = new JSONArray();
        jsonArray.add(businessData);

        JSONObject result = new JSONObject();
        result.put("systemParams", systemParams);
        result.put("baseQueryParams", baseQueryParams);
        result.put("businessData", jsonArray);

        return result;
    }

    /**
     * 创建参数Json
     *
     * @return
     */
    public JSONObject createJsonList(List<TMiStock> stocks, String subInventoryCode, String locatorId) {
        // 创建系统参数
        JSONObject systemParams = new JSONObject();
        systemParams.put("requestId", new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
        systemParams.put("application", "NT_WMS");
        systemParams.put("sourceSystem", "NT_WMS");
        systemParams.put("targetSystem", "EBS");
        systemParams.put("serviceName", "getExistingStock");
        systemParams.put("nonce", 1);
        systemParams.put("timestamp", 1);
        systemParams.put("serviceOperation", "S");
        systemParams.put("serviceVersion", "1.0");
        systemParams.put("token", "fd");

        // 创建查询参数
        JSONObject baseQueryParams = new JSONObject();
        baseQueryParams.put("organizationId", configService.selectConfigByKey("organizationId"));
        baseQueryParams.put("startPosition", 1);
        baseQueryParams.put("rowsCnt", 2000);

        // 创建数据(一起查询)
        JSONArray jsonArray = new JSONArray();
        String itemCode = "";
        String lotNumber = "";
        for (int i = 0; i < stocks.size(); i++) {
            if (i == 0) {
                itemCode = stocks.get(i).getGoodsId();
                if (StringUtils.isNotEmpty(stocks.get(i).getProduclotid())) {
                    lotNumber = stocks.get(i).getProduclotid();
                }
            } else {
                itemCode += "," + stocks.get(i).getGoodsId();
                if (StringUtils.isNotEmpty(stocks.get(i).getProduclotid())) {
                    lotNumber += "," + stocks.get(i).getProduclotid();
                }
            }
        }
        JSONObject businessData = new JSONObject();
        businessData.put("itemCode", itemCode);
        businessData.put("subInventoryCode", subInventoryCode);
        businessData.put("locatorId", locatorId);
        businessData.put("lotNumber", lotNumber);
        jsonArray.add(businessData);

        JSONObject result = new JSONObject();
        result.put("systemParams", systemParams);
        result.put("baseQueryParams", baseQueryParams);
        result.put("businessData", jsonArray);

        return result;
    }

    static class ExistingStock {
        public String getInventoryItemId() {
            return inventoryItemId;
        }

        public void setInventoryItemId(String inventoryItemId) {
            this.inventoryItemId = inventoryItemId;
        }

        public String getItemCode() {
            return itemCode;
        }

        public void setItemCode(String itemCode) {
            this.itemCode = itemCode;
        }

        public String getLotNumber() {
            return lotNumber;
        }

        public void setLotNumber(String lotNumber) {
            this.lotNumber = lotNumber;
        }

        public String getSubinventoryCode() {
            return subinventoryCode;
        }

        public void setSubinventoryCode(String subinventoryCode) {
            this.subinventoryCode = subinventoryCode;
        }

        public String getExpirationDate() {
            return expirationDate;
        }

        public void setExpirationDate(String expirationDate) {
            this.expirationDate = expirationDate;
        }

        public String getOriginationDate() {
            return originationDate;
        }

        public void setOriginationDate(String originationDate) {
            this.originationDate = originationDate;
        }

        public int getTransactionQuantity() {
            return transactionQuantity;
        }

        public void setTransactionQuantity(int transactionQuantity) {
            this.transactionQuantity = transactionQuantity;
        }

        public int getPnalQty() {
            return pnalQty;
        }

        public void setPnalQty(int pnalQty) {
            this.pnalQty = pnalQty;
        }

        public int getOrganizationId() {
            return organizationId;
        }

        public void setOrganizationId(int organizationId) {
            this.organizationId = organizationId;
        }

        private String inventoryItemId;
        private String itemCode;
        private String lotNumber;
        private String subinventoryCode;
        private String expirationDate;
        private String originationDate;
        private int transactionQuantity;
        private int pnalQty;
        private int organizationId;
    }
}
