package com.sunda.spmswms.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sunda.spmscommon.Constans;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmswms.entity.WhsInventoryInfo;
import com.sunda.spmswms.mapper.WhsInventoryInfoMapper;
import com.sunda.spmswms.service.ISapDeliveryNoteLogService;
import com.sunda.spmswms.service.IWhsInventoryInfoService;
import com.sunda.spmswms.service.IWhsOperateLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.sunda.spmscommon.Constans.SPARE_PARTS_INTO_WHS;
import static com.sunda.spmscommon.Constans.UPDATE_WHS_INVENTORY;

/**
 * <p>
 * 仓库库存信息表 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-01-28
 */
@Service
public class WhsInventoryInfoServiceImpl extends ServiceImpl<WhsInventoryInfoMapper, WhsInventoryInfo> implements IWhsInventoryInfoService {

    @Autowired
    WhsInventoryInfoMapper whsInventoryInfoMapper;

    @Autowired
    IWhsOperateLogService iWhsOperateLogService;
    @Autowired
    ISapDeliveryNoteLogService iSapDeliveryNoteLogService;

    /**
     * 根据工厂代码查询全部仓库分页库存信息
     */
    @Override
    public Map<String, Object> getWhsInventory(String werks, int pageNo, int pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> mapList = whsInventoryInfoMapper.getWhsInventory(werks);
        PageInfo<Map<String, Object>> pageData = new PageInfo<>(mapList);
        HashMap<String, Object> pageInfo = new HashMap<>();
        pageInfo.put("records", pageData.getList());
        pageInfo.put("total", pageData.getTotal());
        pageInfo.put("size", pageData.getSize());
        pageInfo.put("current", pageData.getPageNum());
        pageInfo.put("pages", pageData.getPages());
        return pageInfo;
    }

    @Override
    public void addBoxNoteToWhsInventoryInfo(JSONObject sapDeliveryNote, JSONArray sapBoxNote, String userId) {
        String deliveryNoteSap = sapDeliveryNote.getString("deliveryNoteSap");
        for (int i = 0; i < sapBoxNote.size(); i++) {
            //  2021-09-08 KP: 判断只有实收数量大于0的,才加仓库库存
            if (StringUtils.isNotEmpty(sapBoxNote.getJSONObject(i).getString("boxQtyReceived"))
            && Integer.parseInt(sapBoxNote.getJSONObject(i).getString("boxQtyReceived")) != 0){
                String boxNote = sapBoxNote.getJSONObject(i).getString("boxNote");
            if (this.baseMapper.selectOne(new QueryWrapper<WhsInventoryInfo>().eq("BOX_NOTE", boxNote)) == null) {
                this.baseMapper.addBoxNoteToWhsInventoryInfo(deliveryNoteSap, boxNote, userId);
                JSONObject doc = getWerksWhsLocationCode(deliveryNoteSap);
                /** 自管仓 备件货 按箱 验收入库 增加仓库库存日志 */
                iWhsOperateLogService.insertWhsOperateLogBR(boxNote, 1.0, deliveryNoteSap, "", SPARE_PARTS_INTO_WHS, userId,
                        doc.getString("werks"), doc.getString("whsLocationCode"));
            }
            }
        }
        /** 自管仓备件货按箱验收入库增加仓库库存之后，给交货单增加日志 —— 已更新仓库库存 */
        iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_WHS_INVENTORY);
    }

    JSONObject getWerksWhsLocationCode(String deliveryNoteSap){
        JSONObject doc = new JSONObject();
        Map<String, Object> werksAndWhsLocationCode = this.baseMapper.getWerksAndWhsLocationCode(deliveryNoteSap);
        String werks = werksAndWhsLocationCode.get("werks") == null ? "" : werksAndWhsLocationCode.get("werks").toString();
        String whsLocationCode = werksAndWhsLocationCode.get("whsLocationCode") == null ? "" : werksAndWhsLocationCode.get("whsLocationCode").toString();
        doc.put("werks", werks);
        doc.put("whsLocationCode", whsLocationCode);
        return doc;
    }

    @Override
    public ResponseResult deductWhsInventoryInfoX(String werks, String whsLocationCode, String boxNote, String userId) {
        try {
            QueryWrapper queryWrapper = new QueryWrapper<WhsInventoryInfo>().eq("BOX_NOTE", boxNote).eq("WERKS", werks).eq("WHS_LOCATION_CODE", whsLocationCode);

            whsInventoryInfoMapper.delete(queryWrapper);

            iWhsOperateLogService.insertWhsOperateLogBC(boxNote, 1.0, "", Constans.SPARE_PARTS_OUT_WHS, userId, werks, whsLocationCode);

            return ResponseResult.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("扣减仓库库存,失败");
        }
    }

    @Override
    public WhsInventoryInfo getWhsInventoryInfoByBoxNote(String boxNote, String werks, String whsLocationCode) {
        return whsInventoryInfoMapper.selectOne(new QueryWrapper<WhsInventoryInfo>().eq("BOX_NOTE", boxNote).eq("WERKS", werks).eq("WHS_LOCATION_CODE", whsLocationCode));
    }

    @Override
    public String getQuantityByBoxNote(String werks, String whsLocationCode, String boxNote) {
        return whsInventoryInfoMapper.getQuantityByBoxNote(werks, whsLocationCode, boxNote);
    }

    @Override
    public int deleteBoxNoteWhsInventory(String werks, String whsLocationCode, String boxNote) {
        return whsInventoryInfoMapper.delete(new QueryWrapper<WhsInventoryInfo>()
                .eq("WERKS", werks).eq("WHS_LOCATION_CODE", whsLocationCode).eq("BOX_NOTE", boxNote));
    }

    @Override
    public int addWhsInventory(String werks, String whsLocationCode, String boxNote, double quantity, String userId) {
        deleteBoxNoteWhsInventory(werks, whsLocationCode, boxNote);
        WhsInventoryInfo whsInventoryInfo = new WhsInventoryInfo();
        whsInventoryInfo.setWerks(werks);
        whsInventoryInfo.setWhsLocationCode(whsLocationCode);
        whsInventoryInfo.setBoxNote(boxNote);
        whsInventoryInfo.setQuantity(quantity);
        whsInventoryInfo.setUpdateUser(userId);
        return this.baseMapper.insert(whsInventoryInfo);
    }

    /** 线程安全控制————备件货仓库库存操作，包括库存校验，operateType = add 加库存；operateType = sub 减库存；加减库存时 qty 都取1；此法不带操作日志； */
    @Override
    public synchronized ResponseResult updateWhsInventoryX(String werks, String whsLocationCode, String boxNote, double qty, String operateType, String userId) {
        synchronized (this) {
            if (StringUtils.isEmpty(werks) || StringUtils.isEmpty(whsLocationCode) || StringUtils.isEmpty(boxNote)) {
                return ResponseResult.error().add("error", "werks 或 whsLocationCode 或 boxNote 不能为空");
            }
            if (qty == 0) {
                return ResponseResult.error().add("error", "qty 不能为0");
            }
            try {
                QueryWrapper<WhsInventoryInfo> queryWrapper = new QueryWrapper<WhsInventoryInfo>().eq("BOX_NOTE", boxNote)
                        .eq("WERKS", werks).eq("WHS_LOCATION_CODE", whsLocationCode);
                WhsInventoryInfo whsInventoryInfo = this.baseMapper.selectOne(queryWrapper);
                // 箱码具有唯一性 加仓库库存——已存在则报错；不存在则新增；
                if ("add".equals(operateType)) {
                    if (null != whsInventoryInfo){
                        return ResponseResult.error().add("error", "箱码" + boxNote + "在仓库" + werks + whsLocationCode + "已存在，请勿重复操作");
                    } else {
                        WhsInventoryInfo inventoryInfo = new WhsInventoryInfo();
                        inventoryInfo.setWerks(werks);
                        inventoryInfo.setWhsLocationCode(whsLocationCode);
                        inventoryInfo.setQuantity(qty);
                        inventoryInfo.setBoxNote(boxNote);
                        inventoryInfo.setUpdateUser(userId);
                        this.baseMapper.insert(inventoryInfo);
                        return ResponseResult.success();
                    }
                }
                // 箱码具有唯一性 减仓库库存——已存在则删除；不存在则报错；
                if ("sub".equals(operateType)) {
                    if (null != whsInventoryInfo){
                        this.baseMapper.delete(queryWrapper);
                        return ResponseResult.success();
                    } else {
                        return ResponseResult.error().add("error", "箱码" + boxNote + "在仓库" + werks + whsLocationCode + "不存在，请检查重试");
                    }
                }
                return ResponseResult.error().add("error", "操作类型不正确");
            }catch (Exception e){
                e.printStackTrace();
                return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: updateWhsInventoryX");
            }
        }
    }
}
