package com.dk.mdm.service.ivt.outbound;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.mapper.BaseMapper;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.common.service.BaseService;
import com.dk.mdm.infrastructure.convert.ivt.OutboundConvert;
import com.dk.mdm.infrastructure.convert.ivt.OutboundItemConvert;
import com.dk.mdm.mapper.ivt.OutboundItemMapper;
import com.dk.mdm.mapper.ivt.OutboundMapper;
import com.dk.mdm.model.pojo.ivt.Outbound;
import com.dk.mdm.model.pojo.ivt.OutboundItem;
import com.dk.mdm.model.query.ivt.OutboundItemQuery;
import com.dk.mdm.model.response.ivt.OutboundItemResponse;
import com.dk.mdm.model.response.ivt.OutboundResponse;
import com.dk.mdm.model.vo.ivt.OutboundItemVO;
import com.dk.mdm.model.vo.ivt.OutboundVO;
import com.dk.mdm.service.common.CommonService;
import com.dk.mdm.service.ivt.inventory.InventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


/**
 * @author : 寇珊珊
 * @desc : 其他出库业务层
 * @date : 2024/3/18 15:33
 */
@Service
public class OutboundCheckService extends BaseService<Outbound> {

    @Override
    public BaseMapper<Outbound> getRepository() {
        return outboundMapper;
    }

    @Autowired
    private CommonService commonService;

    @Autowired
    private OutboundMapper outboundMapper;

    @Autowired
    private OutboundConvert outboundConvert;

    @Autowired
    private OutboundItemMapper outboundItemMapper;

    @Autowired
    private OutboundItemConvert outboundItemConvert;

    @Autowired
    private InventoryService inventoryService;


    /**
     * @desc : 其他出库新建
     * @date : 2024/3/7 14:13
     * @author : 寇珊珊
     */
    @Transactional(rollbackFor = {Exception.class})
    public OutboundVO otherOutboundInsert(Map<String, Object> map) {
        //region map转json
        JSONObject total = new JSONObject();
        JSONArray detail = new JSONArray();
        //总单
        if (map.get("total") != null) {
            total = (JSONObject) JSON.toJSON(map.get("total"));
        }
        //明细
        if (map.get("total") != null) {
            detail = (JSONArray) JSON.toJSON(map.get("detail"));
        }
        OutboundVO outboundVO = new OutboundVO();
        outboundVO = total.toJavaObject(OutboundVO.class);
        List<OutboundItemVO> outboundItemVOList = detail.toJavaList(OutboundItemVO.class);
        outboundVO.setItemList(outboundItemVOList);
        //endregion

        //region  总单
        //获取 id/单号
        Map<String, Object> codeMap = new HashMap<>();
        // 盘亏出库
        if(Constant.OutType.INVENTORY_LOSS.getName().equals(outboundVO.getOutType())){
            codeMap =  commonService.getUniqueNoteCode(Constant.docNameConstant.INVENTORYLOSEOUTBOUND.getName(), false);
        }
        //仓库调整
        else{
            codeMap =  commonService.getUniqueNoteCode(Constant.docNameConstant.MOVE.getName(), false);
        }
        outboundVO.setOutId(codeMap.get("outId").toString()).
                setOutNo(codeMap.get("outNote").toString());
        //todo  出库类型可能是盘亏可能是库位移动 调用的时候传
        //出库类型
//        outboundVO.setOutType(Constant.OutType.INVENTORY_LOSS.getName());
        //已出库
        outboundVO.setOutStatus(Constant.OutStatus.YICHUKU.getName());
        //出库状态等于已出库 更新合计出库数量/金额 = 出库中数量/出库中金额
        outboundVO
                .setOutQty(outboundVO.getOutingQty())
                .setOutAmt(outboundVO.getOutingAmt())
                .setOutingQty(BigDecimal.ZERO)
                .setOutingAmt(BigDecimal.ZERO)
        ;
        //实体转换
        Outbound outbound = outboundConvert.convertToPo(outboundVO);
        outboundMapper.insert(outbound);
        //endregion

        //region 明细
        //校验明细
        if (outboundVO.getItemList().size() == 0) {
            throw new BaseBusinessException(ErrorCodeEnum.OUTBOUND_ITEM_NOT_EXIST.getCode(),
                    ErrorCodeEnum.OUTBOUND_ITEM_NOT_EXIST.getMessage());
        }
        for (OutboundItemVO outboundItemVO : outboundVO.getItemList()) {
            //region 明细
            // 总单id
            outboundItemVO.setOutId(outboundVO.getOutId());
            //出库类型
            outboundItemVO.setOutType(outboundVO.getOutType());
            //出库状态等于已出库  更新合计出库数量/金额 = 出库中数量/出库中金额
            outboundItemVO
                    .setOutQty(outboundItemVO.getOutingQty())
                    .setOutAmt(outboundItemVO.getOutingAmt())
                    .setOutingQty(BigDecimal.ZERO)
                    .setOutingAmt(BigDecimal.ZERO)
                    .setCostPrice(outboundItemVO.getPriceOut())
                    .setCostAmt(outboundItemVO.getOutQty().multiply(outboundItemVO.getPriceOut()).setScale(2, BigDecimal.ROUND_HALF_UP))
                    .setInvId(outboundItemVO.getInvId())
            ;
            //入库状态
            outboundItemVO.setOutStatus(outboundVO.getOutStatus());
            //实体转换
            OutboundItem outboundItem = outboundItemConvert.convertToPo(outboundItemVO);
            outboundItemMapper.insert(outboundItem);
            outboundItemVO.setItemId(outboundItem.getItemId());

            //endregion

            //region 将库存需要的参数赋值
            outboundItemVO.setInventoryType(Constant.InventoryType.OUTBOUND.getName());
            //盘亏出库
            if(Constant.OutType.INVENTORY_LOSS.getName().equals(outboundItemVO.getOutType())){
                outboundItemVO.setInventoryDocCode(Constant.InventoryDocCode.INVENTORY_LOSS.getValue());
                outboundItemVO.setOutAmt(BigDecimal.ZERO);
            }
            //仓库调整
            else{
                outboundItemVO.setInventoryDocCode(Constant.InventoryDocCode.INVENTORY_LOSS.getValue());
            }
            outboundItemVO.setAddOrEditFlag(true);
            //endregion
        }
        //endregion

        //region 修改库存
        Map<String, Object> invMap = new HashMap<>();
        invMap.put("outDetail", outboundVO.getItemList());
        inventoryService.operatingInventoryInformation(invMap);
        //endregion


        return outboundVO;
    }

    /**
     * @desc : 作废
     * @date : 2024/4/16 13:32
     * @author : 寇珊珊
     */
    @Transactional(rollbackFor = {Exception.class})
    public ResponseResultVO<?> outboundRepeal(String fromId) {
        //region  查询总单  查询明细
        //根据来源id查询 此条出库单的数据还未更改前的数据
        OutboundResponse outboundResponse = outboundMapper.selectByFromId(fromId);
        //根据总单id查询
        List<OutboundItemResponse> outboundItemResponseList = outboundItemMapper.selectByCond(new OutboundItemQuery().setOutId(outboundResponse.getOutId()));
        //endregion

        //region 修改明细
        for (OutboundItemResponse outboundItemResponse : outboundItemResponseList) {
            //region 将库存需要的参数赋值
            outboundItemResponse.setInventoryType(Constant.InventoryType.OUTBOUND.getName());
            //盘亏出库
            if(Constant.OutType.INVENTORY_LOSS.getName().equals(outboundResponse.getOutType())){
                outboundItemResponse.setInventoryDocCode(Constant.InventoryDocCode.INVENTORY_LOSS.getValue());
            }
            //仓库调整
            else{
                outboundItemResponse.setInventoryDocCode(Constant.InventoryDocCode.INVENTORY_LOSS.getValue());
            }
            outboundItemResponse.setOutQty(outboundItemResponse.getOutQty().negate());
            outboundItemResponse.setOutAmt(outboundItemResponse.getOutAmt().negate());
            //endregion

            //赋值
            OutboundItem outboundItem = new OutboundItem();
            outboundItem.setItemId(outboundItemResponse.getItemId());
            outboundItem.setFlgValid(false);
            //修改
            outboundItemMapper.update(outboundItem,
                    new UpdateWrapper<OutboundItem>().lambda()
                            .eq(OutboundItem::getItemId, UUID.fromString(outboundItem.getItemId()))
            );
        }
        //endregion

        //region  修改出库总单
        Outbound outbound = new Outbound();
        outbound.setOutId(outboundResponse.getOutId());
        outbound.setFlgValid(false);
        //修改
        outboundMapper.update(outbound,
                new UpdateWrapper<Outbound>().lambda().eq(Outbound::getOutId, UUID.fromString(outbound.getOutId()))
        );
        //endregion

        //region  修改库存
        Map<String, Object> map = new HashMap<>();
        map.put("delOutDetail", outboundItemResponseList);
        inventoryService.operatingInventoryInformation(map);
        //endregion


        return ResponseResultUtil.success();
    }


}
