package com.hzs.scm.io.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.constant.CacheConstants;
import com.hzs.common.core.constant.SaOrderFieldConstants;
import com.hzs.common.core.constant.SystemFieldConstants;
import com.hzs.common.core.constant.msg.DocumentMsgConstants;
import com.hzs.common.core.constant.msg.ScmMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.service.RedisService;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.TransactionUtils;
import com.hzs.common.domain.scm.general.IcGeneralOutB;
import com.hzs.common.domain.scm.general.IcGeneralOutH;
import com.hzs.common.domain.scm.io.IoOrder;
import com.hzs.common.domain.scm.io.IoOrderItems;
import com.hzs.common.domain.scm.io.ext.IoOrderExt;
import com.hzs.common.domain.scm.io.ext.IoOrderItemsExt;
import com.hzs.common.domain.scm.pub.ScmItemSpecs;
import com.hzs.common.domain.scm.pub.ScmOrderApproveLog;
import com.hzs.common.domain.system.sys.SysUser;
import com.hzs.member.base.IMemberServiceApi;
import com.hzs.sale.order.ISaOrderServiceApi;
import com.hzs.scm.general.service.IIcGeneralOutBService;
import com.hzs.scm.general.service.IIcGeneralOutHService;
import com.hzs.scm.io.mapper.IoOrderMapper;
import com.hzs.scm.io.param.IoOrderItemsParam;
import com.hzs.scm.io.param.IoOrderParam;
import com.hzs.scm.io.service.IIoOrderItemsService;
import com.hzs.scm.io.service.IIoOrderService;
import com.hzs.scm.no.service.IScmBillNoService;
import com.hzs.scm.pub.param.ItemSpecsParam;
import com.hzs.scm.pub.param.ScmApproveParam;
import com.hzs.scm.pub.service.IScmItemSpecsService;
import com.hzs.scm.pub.service.IScmOrderApproveLogService;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.IUserServiceApi;
import com.hzs.system.sys.dto.ApprovalBusinessResultDTO;
import com.hzs.system.sys.dto.LoginUser;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * <p>
 * 业务领用订单表头 服务实现类
 * </p>
 *
 * @author hzs
 * @since 2024-04-22
 */
@Service
public class IoOrderServiceImpl extends ServiceImpl<IoOrderMapper, IoOrder> implements IIoOrderService {

    @DubboReference
    private ICurrencyServiceApi currencyServiceApi;

    @DubboReference
    private IApprovalServiceApi iApprovalServiceApi;

    @DubboReference
    private IUserServiceApi userServiceApi;

    @Autowired
    private IScmBillNoService scmBillNoService;

    @Autowired
    private IIoOrderItemsService ioOrderItemsService;

    @Autowired
    private IScmItemSpecsService scmItemSpecsService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IScmOrderApproveLogService scmOrderApproveLogService;

    @Autowired
    private IIoOrderItemsService orderItemsService;

    @Autowired
    private IIcGeneralOutHService generalOutService;

    @Autowired
    private IIcGeneralOutBService generalOutBiService;

    @DubboReference
    private IMemberServiceApi memberServiceApi;

    @DubboReference
    private ISaOrderServiceApi saOrderServiceApi;

    @Override
    public void insertSaveIoOrderByOrderParam(IoOrderParam ioOrderParam, Long pkMember) {
        packageIoOrderByParam(ioOrderParam, pkMember);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateIoOrderByOrderParam(IoOrderExt ioOrderExt, IoOrderParam ioOrderParam, Long pkMember) {
        // 更新规格明细表，先删除在新增 根据主表主键删除
        scmItemSpecsService.deleteItemSpecsById(EScmOrderType.IO_ORDER.getValue(), ioOrderExt.getPkId(), pkMember);
        ioOrderExt.setPkCorp(ioOrderParam.getPkCorp());
        ioOrderExt.setPkCubasdoc(ioOrderParam.getPkCubasdoc());
        ioOrderExt.setOrderDate(ioOrderParam.getOrderDate());
        ioOrderExt.setPkPurpose(ioOrderParam.getPkPurpose());
        ioOrderExt.setRemark(ioOrderParam.getRemark());
        // 更新订单明细表 分为3部分 删除的 新增的 修改的
        List<IoOrderItems> orderItemsList = getIoOrderItems(ioOrderParam, pkMember, ioOrderExt);
        // 重新处理订单明细，将订单明细分为 删除的、新增的、修改的
        List<IoOrderItemsExt> orderItemsExtList = ioOrderExt.getOrderItemsExtList();
        // 剩余的就是需要删除的
        Map<Long, IoOrderItemsExt> orderItemsExtHashMap = new HashMap<>();
        orderItemsExtList.forEach(poOrderItemsExt ->
                orderItemsExtHashMap.put(poOrderItemsExt.getPkId(), poOrderItemsExt));
        List<IoOrderItems> insertOrderItems = new ArrayList<>();
        List<IoOrderItems> updateOrderItems = new ArrayList<>();
        List<ScmItemSpecs> saveScmItemSpecsList = new ArrayList<>();
        for (IoOrderItems orderItemsExt : orderItemsList) {
            if (orderItemsExt.getPkId() != null && orderItemsExtHashMap.containsKey(orderItemsExt.getPkId())) {
                // 修改的
                orderItemsExt.setPkCreator(orderItemsExtHashMap.get(orderItemsExt.getPkId()).getPkCreator());
                updateOrderItems.add(orderItemsExt);
                saveScmItemSpecsList.addAll(orderItemsExt.getScmItemSpecsList());
                orderItemsExtHashMap.remove(orderItemsExt.getPkId());
            } else {
                // 新增的
                orderItemsExt.setPkOrder(ioOrderExt.getPkId());
                insertOrderItems.add(orderItemsExt);
            }
        }
        String purchaseLockKey = CacheConstants.IO_ORDER_LOCK + ioOrderExt.getPkId();
        try {
            if (!redisService.lockKeyOnce(purchaseLockKey)) {
                throw new RuntimeException(ScmMsgConstants.BILL_NOT_OPERATION);
            }
            if (insertOrderItems.size() > 0) {
                // 保存订单明细 新增的
                ioOrderItemsService.saveBatch(insertOrderItems);
                List<ScmItemSpecs> scmItemSpecsList = scmItemSpecsService.packageOrderItemsSpecs(insertOrderItems, ioOrderExt.getPkId());
                if (scmItemSpecsList.size() > 0) {
                    saveScmItemSpecsList.addAll(scmItemSpecsList);
                }
            }
            if (updateOrderItems.size() > 0) {
                // 修改订单明细 修改的
                updateOrderItems.forEach(updateItems ->
                        ioOrderItemsService.updateById(updateItems));

            }
            if (orderItemsExtHashMap.size() > 0) {
                // 删除订单明细 删除的
                List<IoOrderItems> delOrderItems = new ArrayList<>();
                orderItemsExtHashMap.forEach((key, value) -> delOrderItems.add(value));
                ioOrderItemsService.deleteOrderItemsService(delOrderItems, pkMember);
            }
            // 保存订单明细规格
            if (saveScmItemSpecsList.size() > 0) {
                scmItemSpecsService.saveBatch(saveScmItemSpecsList);
            }
            // 更新订单表
            updateById(ioOrderExt);
        } finally {
            redisService.unlock(purchaseLockKey);
        }
    }

    @Override
    public IoOrderExt queryIoOrderById(Long pkOrder, Integer orderStatus) {
        return baseMapper.queryIoOrderById(pkOrder, orderStatus);
    }

    @Override
    public IoOrderExt queryDisIoOrderById(Long pkOrder, Integer orderStatus) {
        IoOrderParam orderParam = new IoOrderParam();
        orderParam.setPkId(pkOrder);
        orderParam.setOrderStatus(orderStatus);
        List<IoOrderExt>  orderExtList = baseMapper.queryIoOrderByCondition(orderParam);
        if(CollectionUtil.isNotEmpty(orderExtList)){
            return orderExtList.get(0);
        }
        return null;
    }

    @Override
    public List<IoOrderExt> queryIoOrderByCondition(IoOrderParam ioOrderParam) {
        if (ioOrderParam.getEndDate() != null) {
            ioOrderParam.setEndDate(DateUtils.afterDate(1, ChronoUnit.DAYS, ioOrderParam.getEndDate()));
        }
        return baseMapper.queryIoOrderByCondition(ioOrderParam);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteIoOrder(Long pkOrder, Long pkMember) {
        String orderLockKey = CacheConstants.IO_ORDER_LOCK + pkOrder;
        if (!redisService.lockKeyOnce(orderLockKey)) {
            throw new RuntimeException(ScmMsgConstants.BILL_NOT_OPERATION);
        }
        // 删除规格明细表
        scmItemSpecsService.deleteItemSpecsById(EScmOrderType.IO_ORDER.getValue(), pkOrder, pkMember);
        // 删除订单明细表
        ioOrderItemsService.deleteOrderItemsByPkOrder(pkOrder, pkMember);
        // 删除订单主表
        UpdateWrapper<IoOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(SystemFieldConstants.DEL_FLAG, EYesNo.NO.getIntValue());
        updateWrapper.set(SystemFieldConstants.PK_MODIFIED, pkMember);
        updateWrapper.set(SystemFieldConstants.MODIFIED_TIME, DateUtils.currentDateTime());
        updateWrapper.eq(SystemFieldConstants.PK_ID, pkOrder);
        update(updateWrapper);
        redisService.unlock(orderLockKey);
    }

    private String approveIoOrderByStatus(ApprovalBusinessResultDTO approvalBusinessResultDTO, Integer scmOrderStatus, Integer approveStatus) {
        // 查询订单日志表
        List<ScmOrderApproveLog> scmOrderApproveLogList = scmOrderApproveLogService.queryScmOrderApproveLogByCondition(null, approvalBusinessResultDTO.getEApprovalBusiness().getValue(), approvalBusinessResultDTO.getBusinessCode());
        if (scmOrderApproveLogList == null || scmOrderApproveLogList.size() == 0) {
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_NOT_EXISTS);
        }
        ScmOrderApproveLog scmOrderApproveLog = scmOrderApproveLogList.get(0);
        // 查询采购订单
        IoOrderExt ioOrderExt = queryIoOrderById(scmOrderApproveLog.getPkOrder(), EScmOrderStatus.SUBMIT.getValue());
        if (ioOrderExt == null) {
            log.error("订单撤单同意处理失败: 签呈已处理!");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }
        // 更新采购入库单状态
        updateIoOrderStatus(ioOrderExt.getPkId(), approvalBusinessResultDTO.getLoginUser(), scmOrderStatus);
        // 更新前程日志表状态
        scmOrderApproveLogService.updateScmOrderApproveStatus(scmOrderApproveLog.getPkId(), approvalBusinessResultDTO.getLoginUser().getUserId(), approveStatus);
        // 审核通过，供应商的生成销售订单，仓库的生成其他出库单
        if(EAgentApprovalStatus.APPROVED.getValue() == approveStatus){
            // 查询带规格的明细
            List<IoOrderItemsExt> orderItemsExtList = orderItemsService.queryListIoOrderItemsByPk(ioOrderExt.getPkCountry(), ioOrderExt.getPkId());
            // 分为2类
            if(ioOrderExt.getPkCubasdoc() == null){
                // 生成其他出库单，其他出库单在走签呈
                IcGeneralOutH icGeneralOutH = IcGeneralOutH.builder()
                        .pkDept(ioOrderExt.getPkDept())
                        .pkCorp(ioOrderExt.getPkCorp())
                        .pkWhsmanager(ioOrderExt.getPkWhsmanager())
                        .orderDate(DateUtils.currentDate())
                        .orderType(EScmOrderType.GENERAL_OUT.getValue())
                        .orderStatus(EScmOrderStatus.SAVE.getValue())
                        .orderCode(scmBillNoService.createScmBillNoByOrderType(EScmOrderType.GENERAL_OUT.getValue()))
                        .remark(ioOrderExt.getOrderCode() + "业务领用单领用")
                        .build();
                icGeneralOutH.setPkCountry(ioOrderExt.getPkCountry());
                icGeneralOutH.setPkCreator(ioOrderExt.getPkCreator());
                List<IcGeneralOutB> generalOutBiList = new ArrayList<>();
                BigDecimal totalNum = BigDecimal.ZERO;
                for (IoOrderItemsExt orderItemsExt : orderItemsExtList) {
                    icGeneralOutH.setPkWarehouse(orderItemsExt.getPkStorehouse());
                    IcGeneralOutB generalOutB = IcGeneralOutB.builder()
                            .pkUnit(orderItemsExt.getPkUnit())
                            .pkProduct(orderItemsExt.getPkProduct())
                            .transType(ETransType.GENERAL_OUT.getValue())
                            .pkStorehouse(orderItemsExt.getPkStorehouse())
                            .pkRate(orderItemsExt.getPkRate())
                            .nnum(orderItemsExt.getNnum())
                            .ncostprice(BigDecimal.ZERO)
                            .ncostmny(BigDecimal.ZERO)
                            .build();
                    totalNum = ComputeUtil.computeAdd(totalNum, generalOutB.getNnum());
                    List<ScmItemSpecs> scmItemSpecsList = orderItemsExt.getScmItemSpecsList();
                    scmItemSpecsService.packageScmItemByParam(scmItemSpecsList, generalOutB, icGeneralOutH.getPkCountry(), icGeneralOutH.getPkCreator(),
                            icGeneralOutH.getPkId(), generalOutB.getPkId(), EScmOrderType.GENERAL_OUT.getValue());
                    generalOutBiList.add(generalOutB);
                }
                icGeneralOutH.setTotalNum(totalNum);
                // 保存主表
                generalOutService.save(icGeneralOutH);
                for (IcGeneralOutB generalOutB : generalOutBiList) {
                    generalOutB.setPkGeneral(icGeneralOutH.getPkId());
                }
                // 保存子表
                generalOutBiService.saveBatch(generalOutBiList);
                List<ScmItemSpecs> saveScmItemSpecsList = scmItemSpecsService.packageOrderItemsSpecs(generalOutBiList, icGeneralOutH.getPkId());
                if (saveScmItemSpecsList.size() > 0) {
                    scmItemSpecsService.saveBatch(saveScmItemSpecsList);
                }
            }else{
                // 生成销售订单
                // 获取201账户，目前订单先挂在201下
//                SaOrderExt saOrderExt = new SaOrderExt();
//                CuMember cuMember = memberServiceApi.getMember(MagicNumberConstants.COUNTRY_MEMBER_CODE).getData();
//                saOrderExt.setOrderCode(CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE.getValue()));
//                saOrderExt.setOrderAmount(BigDecimal.ZERO);
//                saOrderExt.setOrderAchieve(BigDecimal.ZERO);
//                saOrderExt.setOrderAssAchieve(BigDecimal.ZERO);
//                saOrderExt.setPkMember(cuMember.getPkId());
//                saOrderExt.setOrderType(EOrderType.GIFT_ORDER.getValue());
//                saOrderExt.setPkReference(cuMember.getPkParent());
//                saOrderExt.setPkPlacement(cuMember.getPkPlaceParent());
//                saOrderExt.setRecName(ioOrderExt.getRecName());
//                saOrderExt.setRecPhone(ioOrderExt.getRecPhone());
//                saOrderExt.setRecProvince(ioOrderExt.getRecProvince());
//                saOrderExt.setRecCity(ioOrderExt.getRecCity());
//                saOrderExt.setRecCounty(ioOrderExt.getRecCity());
//                saOrderExt.setRecAddress(ioOrderExt.getRecAddress());
//                saOrderExt.setRemark(ioOrderExt.getOrderCode() + "业务领用单领用");
//                saOrderExt.setDeliveryWay(EDelivery.FAST_MAIL.getValue());
//                // 订单状态先设置为待支付，支付的时候更新
//                saOrderExt.setOrderStatus(EOrderStatus.PAY.getValue());
//                saOrderExt.setPkVertex(cuMember.getPkVertex());
//                saOrderExt.setPkCreator(ioOrderExt.getPkCreator());
//                saOrderExt.setPkCountry(ioOrderExt.getPkCountry());
//                saOrderExt.setCreationTime(DateUtils.currentDateTime());
//                // 处理邮费
//                List<SaOrderItems> saOrderItemsList = new ArrayList<>();
//                for (IoOrderItemsExt orderItemsExt : orderItemsExtList) {
//                    SaOrderItems saOrderItems = SaOrderItems.builder()
//                            .pkProduct(orderItemsExt.getPkProduct())
//                            .price(orderItemsExt.getSupplyPrice())
//                            .achievement(BigDecimal.ZERO)
//                            .assAchievement(BigDecimal.ZERO)
//                            .quantity(orderItemsExt.getNnum().intValue())
//                            .waresQuantity(0)
//                            .pkRate(ioOrderExt.getPkRate())
//                            .isGift(EYesNo.NO.getIntValue())
//                            .specsName(orderItemsExt.getSpecsName())
//                            .specsNameId(orderItemsExt.getSpecsNameId())
//                            .isMakerGift(EYesNo.NO.getIntValue())
//                            .shippingChannel(orderItemsExt.getShippingChannel())
//                            .pkSupplier(orderItemsExt.getPkSupplier())
//                            .orderStatus(EOrderStatus.PAY.getValue())
//                            .skuCode(CommonUtil.createSkuCode(orderItemsExt.getProductCode(), orderItemsExt.getSpecsNameId()))
//                            .build();
//                    if(saOrderItems.getIsGift() != null && EYesNo.YES.getIntValue() == saOrderItems.getIsGift()){
//                        saOrderItems.setPrice(BigDecimal.ZERO);
//                    }
//                    saOrderItems.setShippingChannel(saOrderItems.getShippingChannel());
//                    saOrderItems.setPkSupplier(saOrderItems.getPkSupplier());
//                    saOrderItems.setPkCreator(saOrderExt.getPkCreator());
//                    saOrderItems.setCreationTime(saOrderExt.getCreationTime());
//                    saOrderItems.setPkCountry(saOrderExt.getPkCountry());
//                    saOrderItems.setPkGrade(cuMember.getPkSettleGrade());
//                    saOrderItems.setPkAwards(cuMember.getPkAwards());
//                    saOrderItemsList.add(saOrderItems);
//                }
//                saOrderExt.setOrderItemsList(saOrderItemsList);
//                // 第二次封装订单，根据明细表计算订单主表金额、业绩
//                saOrderExt.getOrderItemsList().forEach(saOrderItems -> {
//                    saOrderExt.setPkRate(saOrderItems.getPkRate());
//                    if (EYesNo.YES.getIntValue() == saOrderItems.getIsGift()) {
//                        return;
//                    }
//                    // 总价;
//                    saOrderExt.setOrderAmount(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAmount(), saOrderItems.getPrice(), saOrderItems.getQuantity()));
//                    // 总业绩
//                    saOrderExt.setOrderAchieve(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAchieve(), saOrderItems.getAchievement(), saOrderItems.getQuantity()));
//                    // 总考核业绩
//                    saOrderExt.setOrderAssAchieve(ComputeUtil.computeAddMultiply(saOrderExt.getOrderAssAchieve(), saOrderItems.getAssAchievement(), saOrderItems.getQuantity()));
//                });
//                saOrderExt.setUploadAchieve(saOrderExt.getOrderAchieve());
//                if(!saOrderServiceApi.saveOrder(saOrderExt).isSuccess()){
//                    throw new RuntimeException("保存订单失败");
//                }
            }
        }
        return null;
    }

    /*
     * @description: 将采购订单的参数转换为能保存的订单
     * @author: sui q
     * @date: 2023/11/20 15:53
     * @param: null null
     **/
    private void packageIoOrderByParam(IoOrderParam ioOrderParam, Long pkMember) {
        IoOrder ioOrder = BeanUtil.copyProperties(ioOrderParam, IoOrder.class);
        List<IoOrderItems> orderItemsList = getIoOrderItems(ioOrderParam, pkMember, ioOrder);
        // 生成单据号
        ioOrder.setOrderCode(scmBillNoService.createScmBillNoByOrderType(EScmOrderType.IO_ORDER.getValue()));
        // 保存主表
        save(ioOrder);
        for (IoOrderItems ioOrderItems : orderItemsList) {
            ioOrderItems.setPkOrder(ioOrder.getPkId());
        }
        // 保存子表
        ioOrderItemsService.saveBatch(orderItemsList);
        List<ScmItemSpecs> saveScmItemSpecsList = scmItemSpecsService.packageOrderItemsSpecs(orderItemsList, ioOrder.getPkId());
        if (saveScmItemSpecsList.size() > 0) {
            scmItemSpecsService.saveBatch(saveScmItemSpecsList);
        }
    }

    private List<IoOrderItems> getIoOrderItems(IoOrderParam ioOrderParam, Long pkMember, IoOrder ioOrder) {
        // 根据国家获得汇率
        CurrencyDTO currencyDTO = currencyServiceApi.getCurrency(ioOrderParam.getPkCountry()).getData();
        ioOrder.setPkRate(currencyDTO.getPkId());
        SysUser sysUser = userServiceApi.selectUserById(pkMember).getData();
        // 根据登录账号获得部门
        ioOrder.setPkDept(sysUser.getPkDept().intValue());
        ioOrder.setPkWhsmanager(pkMember);
        // 计算累计数量 累计价税合计
        // 总数量
        BigDecimal totalNum = BigDecimal.ZERO;
        List<IoOrderItems> orderItemsList = new ArrayList<>();
        Date date = DateUtils.currentDateTime();
        for (IoOrderItemsParam orderItemsParam : ioOrderParam.getOrderItemsParamList()) {
            IoOrderItems orderItems = BeanUtil.copyProperties(orderItemsParam, IoOrderItems.class);
            orderItems.setPkRate(currencyDTO.getPkId());
            totalNum = ComputeUtil.computeAdd(totalNum, orderItems.getNnum());
            List<ItemSpecsParam> itemSpecsParamList = orderItemsParam.getScmItemSpecsList();
            scmItemSpecsService.packageScmItemByParam(itemSpecsParamList, orderItems, ioOrderParam.getPkCountry(), pkMember,
                    ioOrderParam.getPkId(), orderItems.getPkId(), EScmOrderType.IO_ORDER.getValue());
            orderItemsList.add(orderItems);
        }
        ioOrder.setPkCountry(ioOrderParam.getPkCountry());
        if (ioOrderParam.getPkId() == null) {
            ioOrder.setPkCreator(pkMember);
        } else {
            ioOrder.setPkModified(pkMember);
            ioOrder.setModifiedTime(date);
        }
        ioOrder.setTotalNum(totalNum);
        return orderItemsList;
    }

    private void updateIoOrderStatus(Long pkId, LoginUser loginUser, Integer orderStatus) {
        UpdateWrapper<IoOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(SaOrderFieldConstants.ORDER_STATUS, orderStatus);
        updateWrapper.set(SystemFieldConstants.PK_MODIFIED, loginUser.getUserId());
        updateWrapper.set(SystemFieldConstants.MODIFIED_TIME, DateUtils.currentDateTime());
        updateWrapper.eq(SystemFieldConstants.PK_ID, pkId);
        update(updateWrapper);
    }
}
