package com.bonus.canteen.core.supply.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.menu.enums.LeLevelEnum;
import com.bonus.canteen.core.supply.api.DrpAllocStallApi;
import com.bonus.canteen.core.supply.constant.DrpIntoInventoryStatusEnum;
import com.bonus.canteen.core.supply.constant.DrpOrderGoodsPayAndRefundTypeEnum;
import com.bonus.canteen.core.supply.constant.DrpOrderGoodsStatusEnum;
import com.bonus.canteen.core.supply.constant.DrpPayRefundTypeEnum;
import com.bonus.canteen.core.supply.dto.*;
import com.bonus.canteen.core.supply.mapper.*;
import com.bonus.canteen.core.supply.po.*;
import com.bonus.canteen.core.supply.service.DrpSupplierComeGoService;
import com.bonus.canteen.core.supply.vo.DrpOrderGoodsPayStyleVO;
import com.bonus.canteen.core.supply.vo.DrpSupplierComeAndGoPageVO;
import com.bonus.canteen.core.supply.vo.DrpSupplierMaterialIntoAndOutPageVO;
import com.bonus.common.houqin.utils.LeBeanUtil;
import com.bonus.common.houqin.utils.id.Id;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xliu
 * @date 2025/5/14 10:12
 */
@Service
public class DrpSupplierComeGoServiceImpl implements DrpSupplierComeGoService {

    @Resource
    private DrpSupplierComeGoMapper drpSupplierComeGoMapper;

    @Resource
    private DrpAllocStallApi drpAllocStallApi;

    @Resource
    private DrpIntoInventoryMapper drpIntoInventoryMapper;

    @Resource
    private DrpOrderGoodsPayStyleMapper drpOrderGoodsPayStyleMapper;

    @Resource
    private DrpRefundGoodsMapper drpRefundGoodsMapper;

    @Resource
    private DrpOrderGoodsPayMapper drpOrderGoodsPayMapper;

    @Resource
    private DrpOrderGoodsRefundMapper drpOrderGoodsRefundMapper;

    @Override
    public List<DrpSupplierMaterialIntoAndOutPageVO> pageSupplierMaterialIntoAndOut(DrpSupplierMaterialIntoAndOutPageDTO content) {
//        List<Long> warehouseAuthority = this.drpAuthorityApi.listWarehouseAuthority();
//        List<Long> areaAuth = this.drpAuthorityApi.listAreaAuth();
        if (CharSequenceUtil.isNotEmpty(content.getDrpOrderId())) {
            content.setDrpOrderId(LeBeanUtil.fieldLikeHandle(content.getDrpOrderId()));
        }
        return this.drpSupplierComeGoMapper.pageSupplierMaterialIntoAndOut(content, DrpIntoInventoryStatusEnum.COMMIT.key(), null, null);
    }

    @Override
    public List<DrpSupplierComeAndGoPageVO> pageSupplierComeAndGo(DrpSupplierComeAndGoPageDTO content) {
        if (CharSequenceUtil.isNotEmpty(content.getOrderGoodsId())) {
            content.setOrderGoodsId(LeBeanUtil.fieldLikeHandle(content.getOrderGoodsId()));
        }

        if (CharSequenceUtil.isNotEmpty(content.getOrderTitle())) {
            content.setOrderTitle(LeBeanUtil.fieldLikeHandle(content.getOrderTitle()));
        }

//        List<Long> areaAuth = this.drpAuthorityApi.listAreaAuth();
//        content.setAreaAuth(areaAuth);
//        PageMethod.startPage(content);
        List<DrpSupplierComeAndGoPageVO> resultList = this.drpSupplierComeGoMapper.pageSupplierComeAndGo(content, DrpOrderGoodsStatusEnum.IS_COMMIT.getKey());
        if (CollUtil.isEmpty(resultList)) {
            return resultList;
        } else {
            List<String> orderGoodsIdList = (List)resultList.stream().map(DrpSupplierComeAndGoPageVO::getOrderGoodsId).collect(Collectors.toList());
            List<OrderGoodsPayRefundAmountModel> orderGoodsPayRefundAmountModels = this.drpSupplierComeGoMapper.listPayAndRefundAmount(orderGoodsIdList);
            List<OrderIntoNumModel> intoTotalNumList = this.drpIntoInventoryMapper.listOrderIntoNum(orderGoodsIdList, DrpIntoInventoryStatusEnum.COMMIT.key());
            List<OrderRefundNumModel> refundTotalNumList = this.drpRefundGoodsMapper.listOrderRefundNum(orderGoodsIdList);
            if (CollUtil.isEmpty(orderGoodsPayRefundAmountModels) && CollUtil.isEmpty(intoTotalNumList) && CollUtil.isEmpty(refundTotalNumList)) {
                return resultList;
            } else {
                Map<String, BigDecimal> refundTotalNumMap = new HashMap();
                Iterator var9;
                if (CollUtil.isNotEmpty(refundTotalNumList)) {
                    var9 = refundTotalNumList.iterator();

                    while(var9.hasNext()) {
                        OrderRefundNumModel orderRefundNumModel = (OrderRefundNumModel)var9.next();
                        refundTotalNumMap.put(orderRefundNumModel.getOrderGoodsId(), orderRefundNumModel.getRefundTotalNum());
                    }
                }

                var9 = resultList.iterator();

                while(var9.hasNext()) {
                    DrpSupplierComeAndGoPageVO result = (DrpSupplierComeAndGoPageVO)var9.next();
                    if (CharSequenceUtil.isNotEmpty(result.getStallId())) {
                        String[] split = result.getStallId().split(",");
                        result.setStallName(this.drpAllocStallApi.getStallNameByIdSet((Set)Arrays.stream(split).map(Long::valueOf).collect(Collectors.toSet())));
                    }

                    if (CollUtil.isNotEmpty(orderGoodsPayRefundAmountModels)) {
                        List<OrderGoodsPayRefundAmountModel> samePayRefundAmountList = (List)orderGoodsPayRefundAmountModels.stream().filter((s) -> {
                            return s.getOrderGoodsId().equals(result.getOrderGoodsId());
                        }).collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(samePayRefundAmountList)) {
                            Long orderPaidAmount = samePayRefundAmountList.stream().filter((s) -> {
                                return s.getPayRefundType().equals(DrpPayRefundTypeEnum.PAY.key()) && s.getPayStatus().equals(LeLevelEnum.SECOND.getKey());
                            }).mapToLong(OrderGoodsPayRefundAmountModel::getPayAmount).sum();
                            result.setOrderPaidAmount(orderPaidAmount);
                            result.setOrderUnpaidAmount(result.getOrderAmount() - result.getOrderPaidAmount());
                            Long applyPayAmount = samePayRefundAmountList.stream().filter((s) -> {
                                return s.getPayRefundType().equals(DrpPayRefundTypeEnum.PAY.key()) && s.getPayStatus().equals(LeLevelEnum.FIRST.getKey());
                            }).mapToLong(OrderGoodsPayRefundAmountModel::getPayAmount).sum();
                            result.setApplyPayAmount(applyPayAmount);
                            Long applyRefundAmount = samePayRefundAmountList.stream().filter((s) -> {
                                return s.getPayRefundType().equals(DrpPayRefundTypeEnum.REFUND.key()) && s.getPayStatus().equals(LeLevelEnum.FIRST.getKey());
                            }).mapToLong(OrderGoodsPayRefundAmountModel::getPayAmount).sum();
                            result.setApplyRefundAmount(applyRefundAmount);
                            Long refundTotalAmount = samePayRefundAmountList.stream().filter((s) -> {
                                return s.getPayRefundType().equals(DrpPayRefundTypeEnum.REFUND.key()) && s.getPayStatus().equals(LeLevelEnum.SECOND.getKey());
                            }).mapToLong(OrderGoodsPayRefundAmountModel::getPayAmount).sum();
                            result.setRefundTotalAmount(refundTotalAmount);
                        }
                    }

                    if (ObjectUtil.isEmpty(result.getTotalIntoNum())) {
                        result.setTotalIntoNum(BigDecimal.ZERO);
                    }

                    if (ObjectUtil.isEmpty(result.getOrderTotalNum())) {
                        result.setOrderTotalNum(BigDecimal.ZERO);
                    }

                    result.setUnIntoTotalNum(result.getOrderTotalNum().subtract(result.getTotalIntoNum()));
                    result.setRefundTotalNum(new BigDecimal("0"));
                    BigDecimal refundTotalNum = (BigDecimal)refundTotalNumMap.get(result.getOrderGoodsId());
                    if (ObjectUtil.isNotEmpty(refundTotalNum)) {
                        result.setRefundTotalNum(refundTotalNum);
                    }

                    DrpOrderGoodsPayStyleVO payStyleVO = this.drpOrderGoodsPayStyleMapper.getPayStyleById(result.getOrderGoodsId());
                    result.setPayStyleVO(payStyleVO);
                }

                return resultList;
            }
        }
    }

    public void applyPay(DrpComeAndGoApplyPayDTO content) {
        DrpOrderGoodsPay drpOrderGoodsPay = new DrpOrderGoodsPay();
        BeanUtil.copyProperties(content, drpOrderGoodsPay, new String[0]);
        drpOrderGoodsPay.setPayId(Id.next());
        drpOrderGoodsPay.setType(DrpOrderGoodsPayAndRefundTypeEnum.APPLY.key());
        this.drpOrderGoodsPayMapper.insert(drpOrderGoodsPay);
    }


    public void commitPay(DrpComeAndGoCommitPayDTO content) {
        DrpOrderGoodsPay drpOrderGoodsPay = new DrpOrderGoodsPay();
        BeanUtil.copyProperties(content, drpOrderGoodsPay, new String[0]);
        drpOrderGoodsPay.setPayId(Id.next());
        drpOrderGoodsPay.setType(DrpOrderGoodsPayAndRefundTypeEnum.PAY_OR_REFUND.key());
        this.drpOrderGoodsPayMapper.insert(drpOrderGoodsPay);
    }

    public void applyRefund(DrpComeAndGoCommitRefundApplyDTO content) {
        DrpOrderGoodsRefund drpOrderGoodsRefund = new DrpOrderGoodsRefund();
        BeanUtil.copyProperties(content, drpOrderGoodsRefund, new String[0]);
        drpOrderGoodsRefund.setRefundMoneyId(Id.next());
        drpOrderGoodsRefund.setType(DrpOrderGoodsPayAndRefundTypeEnum.APPLY.key());
        this.drpOrderGoodsRefundMapper.insert(drpOrderGoodsRefund);
    }

    public void commitRefund(DrpComeAndGoCommitRefundDTO content) {
        DrpOrderGoodsRefund drpOrderGoodsRefund = new DrpOrderGoodsRefund();
        BeanUtil.copyProperties(content, drpOrderGoodsRefund, new String[0]);
        drpOrderGoodsRefund.setRefundMoneyId(Id.next());
        drpOrderGoodsRefund.setType(DrpOrderGoodsPayAndRefundTypeEnum.PAY_OR_REFUND.key());
        this.drpOrderGoodsRefundMapper.insert(drpOrderGoodsRefund);
    }


}
