package com.hzs.scm.inventory.controller.manage;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.hzs.common.core.annotation.Log;
import com.hzs.common.core.constant.msg.MemberMsgConstants;
import com.hzs.common.core.constant.msg.ScmMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.sale.classify.BdSpecs;
import com.hzs.common.domain.scm.general.ext.IcGeneralOutBExt;
import com.hzs.common.domain.scm.ic.IcOnHandNum;
import com.hzs.common.domain.scm.ic.ext.IcOnHandNumExt;
import com.hzs.common.domain.scm.inventory.ext.IcInventoryBExt;
import com.hzs.common.domain.scm.inventory.ext.IcInventoryHExt;
import com.hzs.common.domain.scm.po.ext.PoOrderExt;
import com.hzs.common.domain.scm.po.ext.PoOrderItemsExt;
import com.hzs.common.domain.scm.pub.ScmOrderApproveLog;
import com.hzs.common.domain.system.sys.SysUser;
import com.hzs.common.security.service.UserTokenService;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.core.utils.TransactionUtils;
import com.hzs.scm.general.vo.IcGeneralOutBVO;
import com.hzs.scm.ic.service.IIcOnHandNumService;
import com.hzs.scm.inventory.param.InventoryBParam;
import com.hzs.scm.inventory.param.InventoryParam;
import com.hzs.scm.inventory.service.IIcInventoryBService;
import com.hzs.scm.inventory.service.IIcInventoryHService;
import com.hzs.scm.inventory.vo.InventoryBVO;
import com.hzs.scm.inventory.vo.InventoryVO;
import com.hzs.scm.po.vo.PoOrderBVo;
import com.hzs.scm.po.vo.PoOrderVo;
import com.hzs.scm.pub.controller.ScmController;
import com.hzs.scm.pub.param.ItemSpecsParam;
import com.hzs.scm.pub.param.ScmApproveParam;
import com.hzs.scm.pub.service.IScmOrderApproveLogService;
import com.hzs.system.sys.IUserServiceApi;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 库存盘点单表头 前端控制器
 */
@RestController
@RequestMapping("/manage/inventory")
public class IcInventoryHController extends ScmController {

    @Autowired
    private IIcInventoryHService inventoryService;

    @DubboReference
    private IUserServiceApi userServiceApi;

    @Autowired
    private IIcOnHandNumService onHandNumService;

    @Autowired
    private IScmOrderApproveLogService scmOrderApproveLogService;

    @Autowired
    private UserTokenService userTokenService;

    @Autowired
    private IIcInventoryBService inventoryBiService;

    /**
     * 查询列表
     *
     * @return cubasdocParam 入参
     */
    @PostMapping("/list")
    @Log(module = EOperationModule.INVENTORY_ORDER, business = EOperationBusiness.INVENTORY_ORDER, method = EOperationMethod.SELECT)
    public TableDataInfo listInventory(@RequestBody InventoryParam inventoryParam) {
        startPage();
        inventoryParam.setPkCountry(SecurityUtils.getPkCountry());
        List<IcInventoryHExt> inventoryExtList = inventoryService.queryDisInventoryExtByCondition(inventoryParam);
        return packageTableDataInfo(inventoryExtList, packageScmReturnVo(inventoryExtList));
    }

    private List<InventoryVO> packageScmReturnVo(List<IcInventoryHExt> inventoryExtList) {
        List<InventoryVO> inventoryVoList = new ArrayList<>();
        for (IcInventoryHExt inventoryExt : inventoryExtList) {
            InventoryVO inventoryVO = BeanUtil.copyProperties(inventoryExt, InventoryVO.class);
            List<IcInventoryBExt> inventoryBiExtList = inventoryExt.getInventoryBiExtList();
            if (CollectionUtil.isNotEmpty(inventoryBiExtList)) {
                List<InventoryBVO> returnbVoList = BeanUtil.copyToList(inventoryBiExtList, InventoryBVO.class);
                inventoryVO.setInventoryBiExtList(returnbVoList);
            }
            inventoryVoList.add(inventoryVO);
        }
        return inventoryVoList;
    }

    /**
     * 查询待入库订单的明细
     *
     * @return cubasdocParam 入参
     */
    @GetMapping("/list-detail/{pkId}")
    public TableDataInfo queryToStorePoOrder(@PathVariable Long pkId) {
        List<IcInventoryBExt> inventoryBiExtList = inventoryBiService.queryInventoryBiByPk(SecurityUtils.getPkCountry(), pkId);
        List<InventoryBVO> scmReturnVoList = new ArrayList<>();
        for (IcInventoryBExt icInventoryBiExt : inventoryBiExtList) {
            scmReturnVoList.add(BeanUtil.copyProperties(icInventoryBiExt, InventoryBVO.class));
        }
        return packageTableDataInfo(inventoryBiExtList, scmReturnVoList);
    }

    /**
     * 新增库存盘点
     *
     * @param inventoryParam 入参
     */
    @PostMapping("/insert")
    @Log(module = EOperationModule.INVENTORY_ORDER, business = EOperationBusiness.INVENTORY_ORDER, method = EOperationMethod.INSERT)
    public AjaxResult saveInventory(@RequestBody InventoryParam inventoryParam) {
        String message = validateInventoryParam(inventoryParam);
        if (ObjectUtil.isNotEmpty(message)) {
            return AjaxResult.error(TransactionUtils.getContent(message));
        }
        inventoryService.insertInventoryByInventoryParam(inventoryParam, SecurityUtils.getUserId());
        return AjaxResult.success();
    }

    /**
     * 修改库存盘点
     *
     * @param inventoryParam 入参
     */
    @PostMapping("/update")
    @Log(module = EOperationModule.INVENTORY_ORDER, business = EOperationBusiness.INVENTORY_ORDER, method = EOperationMethod.UPDATE)
    public AjaxResult updatePoOrder(@RequestBody InventoryParam inventoryParam) {
        if (inventoryParam.getPkId() == null) {
            return AjaxResult.error(TransactionUtils.getContent(ScmMsgConstants.INVENTORY_ORDER_NOT_EXIST));
        }
        String message = validateInventoryParam(inventoryParam);
        if (ObjectUtil.isNotEmpty(message)) {
            return AjaxResult.error(TransactionUtils.getContent(message));
        }
        // 查询是否存在库存盘点单
        IcInventoryHExt inventoryExt = inventoryService.queryInventoryById(inventoryParam.getPkId(), EScmOrderStatus.SAVE.getValue());
        if (inventoryExt == null) {
            return AjaxResult.error(TransactionUtils.getContent(ScmMsgConstants.INVENTORY_ORDER_NOT_EXIST));
        }
        inventoryService.updateInventoryByInventoryParam(inventoryExt, inventoryParam, SecurityUtils.getUserId());
        return AjaxResult.success();
    }

    /**
     * 删除库存盘点
     *
     * @param pkId 主键
     */
    @DeleteMapping("/{pkId}")
    @Log(module = EOperationModule.INVENTORY_ORDER, business = EOperationBusiness.INVENTORY_ORDER, method = EOperationMethod.DELETE)
    public AjaxResult delete(@PathVariable Long pkId) {
        if (pkId == null) {
            return AjaxResult.error(TransactionUtils.getContent(ScmMsgConstants.INVENTORY_ORDER_NOT_EXIST));
        }
        IcInventoryHExt inventoryExt = inventoryService.queryInventoryById(pkId, EScmOrderStatus.SAVE.getValue());
        if (inventoryExt == null) {
            return AjaxResult.error(TransactionUtils.getContent(ScmMsgConstants.INVENTORY_ORDER_NOT_EXIST));
        }
        inventoryService.deleteInventory(pkId, SecurityUtils.getUserId());
        return AjaxResult.success();
    }

    protected String validateInventoryParam(InventoryParam inventoryParam) {
        if (validateInventoryFieldParam(inventoryParam)) {
            return MemberMsgConstants.REQUIRED_NOT_EMPTY;
        }
        inventoryParam.setPkCountry(SecurityUtils.getPkCountry());
        // 验证仓库管理员，调整人
        SysUser sysUser = userServiceApi.selectUserById(inventoryParam.getPkAdjustor()).getData();
        if (sysUser == null) {
            return MemberMsgConstants.REQUIRED_NOT_EMPTY;
        }
        // 根据登录账号获得部门
        inventoryParam.setPkDept(sysUser.getPkDept().intValue());
        sysUser = userServiceApi.selectUserById(inventoryParam.getPkWhsmanager()).getData();
        if (sysUser == null) {
            return MemberMsgConstants.REQUIRED_NOT_EMPTY;
        }
        // 验证采购组织
        String msg = validateSysCorp(inventoryParam.getPkCorp(), inventoryParam.getPkCountry());
        if (ObjectUtil.isNotEmpty(msg)) {
            return msg;
        }
        Set<Integer> storeSet = new HashSet<>();
        storeSet.add(inventoryParam.getPkWarehouse());
        validateStorehouse(storeSet, inventoryParam.getPkCountry(), inventoryParam.getPkCorp());
        // 明细表分为2类，一类来源于现存量，一类来源于新增
        List<Long> idList = new ArrayList<>();
        List<InventoryBParam> addInventoryBiList = new ArrayList<>();
        for (InventoryBParam inventoryBiParam : inventoryParam.getInventoryBiParamList()) {
            if (inventoryBiParam.getPkOnhandnum() == null) {
                inventoryBiParam.setNdiffastnum(ComputeUtil.computeSubtract(inventoryBiParam.getNonhandnum(), inventoryBiParam.getNdiffastnum()).abs());
                addInventoryBiList.add(inventoryBiParam);
            } else {
                idList.add(inventoryBiParam.getPkOnhandnum());
            }
        }
        // 根据现存量查询数据
        if (idList.size() > 0) {
            List<IcOnHandNumExt> icOnHandNumList = onHandNumService.queryOnHandNumByList(idList);
            Map<Long, IcOnHandNum> onHandNumMap = icOnHandNumList.stream().collect(Collectors.toMap(IcOnHandNum::getPkId, icOnHandNum -> icOnHandNum));
            for (InventoryBParam inventoryBiParam : inventoryParam.getInventoryBiParamList()) {
                if (onHandNumMap.containsKey(inventoryBiParam.getPkOnhandnum())) {
                    IcOnHandNum icOnHandNum = onHandNumMap.get(inventoryBiParam.getPkOnhandnum());
                    inventoryBiParam.setPkUnit(icOnHandNum.getPkUnit());
                    inventoryBiParam.setPkProduct(icOnHandNum.getPkProduct());
                    inventoryBiParam.setPkCubasdoc(icOnHandNum.getPkCubasdoc());
                    inventoryBiParam.setProductDate(icOnHandNum.getProductDate());
                    inventoryBiParam.setExpireDate(icOnHandNum.getExpireDate());
                    inventoryBiParam.setNonhandnum(icOnHandNum.getNonhandnum());
                    inventoryBiParam.setPkBatchCode(icOnHandNum.getPkBatchCode());
                    inventoryBiParam.setNdiffastnum(ComputeUtil.computeSubtract(icOnHandNum.getNonhandnum(), inventoryBiParam.getNadjustnum()).abs());
                    inventoryBiParam.setScmItemSpecsList(BeanUtil.copyToList(icOnHandNum.getScmItemSpecsList(), ItemSpecsParam.class));
                }
                if (EInventoryType.INVENTORY_OUT.getValue() == inventoryParam.getInvType()) {
                    if (ComputeUtil.compareValue(inventoryBiParam.getNadjustnum(), inventoryBiParam.getNonhandnum())) {
                        return ScmMsgConstants.INVENTORY_OUT;
                    }
                } else {
                    if (ComputeUtil.compareValue(inventoryBiParam.getNonhandnum(), inventoryBiParam.getNadjustnum())) {
                        return ScmMsgConstants.INVENTORY_IN;
                    }
                }
            }
        }
        if (addInventoryBiList.size() > 0) {
            Map<String, BdSpecs> specsMap = new HashMap<>();
            String message = validateProduct(addInventoryBiList, specsMap);
            if (ObjectUtil.isNotEmpty(message)) {
                return message;
            }
            // 验证批次号
            return validateProductBatchCode(addInventoryBiList, specsMap);
        }
        return null;
    }

    protected Boolean validateInventoryFieldParam(InventoryParam inventoryParam) {
        if (inventoryParam == null || inventoryParam.getPkWhsmanager() == null || inventoryParam.getPkAdjustor() == null ||
                inventoryParam.getOrderDate() == null || inventoryParam.getPkWarehouse() == null ||
                inventoryParam.getInvType() == null ||
                inventoryParam.getPkCorp() == null || CollectionUtil.isEmpty(inventoryParam.getInventoryBiParamList())) {
            return Boolean.TRUE;
        }
        // 验证 必输字段不能为空 存在2种情况 1种来源于现存量，一种是没有的新增的
        for (InventoryBParam inventoryBiParam : inventoryParam.getInventoryBiParamList()) {
            if (inventoryBiParam.getPkOnhandnum() == null) {
                if (inventoryBiParam.getPkUnit() == null || inventoryBiParam.getPkProduct() == null ||
                        inventoryBiParam.getPkCubasdoc() == null || inventoryBiParam.getProductDate() == null ||
                        inventoryBiParam.getExpireDate() == null || inventoryBiParam.getNonhandnum() == null ||
                        inventoryBiParam.getNadjustnum() == null || inventoryBiParam.getNdiffastnum() == null ||
                        inventoryBiParam.getNdiffastnum().equals(BigDecimal.ZERO) ||
                        inventoryBiParam.getPkBatchCode() == null || CollectionUtil.isEmpty(inventoryBiParam.getScmItemSpecsList())) {
                    return Boolean.TRUE;
                }
            } else {
                if (inventoryBiParam.getNdiffastnum() == null || inventoryBiParam.getNadjustnum() == null ||
                        inventoryBiParam.getNdiffastnum().equals(BigDecimal.ZERO)) {
                    return Boolean.TRUE;
                }
            }
        }
        return Boolean.FALSE;
    }
}
