package com.gxwebsoft.shop.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.cms.entity.Website;
import com.gxwebsoft.cms.entity.WebsiteField;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.utils.RequestUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.Area;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.service.AreaService;
import com.gxwebsoft.shop.consts.BalanceScene;
import com.gxwebsoft.shop.entity.*;
import com.gxwebsoft.shop.mapper.OrderMapper;
import com.gxwebsoft.shop.param.OrderParam;
import com.gxwebsoft.shop.service.*;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.RSAConfig;
import com.gxwebsoft.common.system.entity.Payment;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.http.*;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.transferbatch.TransferBatchService;
import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest;
import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse;
import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

import static com.gxwebsoft.shop.consts.OrderPayType.PAY_TYPE_FRIEND;
import static com.gxwebsoft.shop.consts.OrderPayType.PAY_TYPE_WECHAT;

/**
 * 订单Service实现
 *
 * @author 科技小王子
 * @since 2024-05-14 13:20:04
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Value("${spring.profiles.active}")
    String active;
    @Resource
    private OrderInfoService orderInfoService;
    @Resource
    private OrderGoodsService orderGoodsService;
    @Resource
    private ConfigProperties config;
    @Resource
    private RequestUtil requestUtil;
    @Resource
    private OrderService orderService;
    @Resource
    private UsersService usersService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private GoodsService goodsService;
    @Resource
    private ExpressService expressService;
    @Resource
    private OrderDeliveryService orderDeliveryService;
    @Resource
    private MerchantService merchantService;
    @Resource
    private GoodsIncomeConfigService goodsIncomeConfigService;
    @Resource
    private UserBalanceLogService userBalanceLogService;
    @Resource
    private DealerCapitalService dealerCapitalService;
    @Resource
    private GoodsSkuService goodsSkuService;
    @Resource
    private AreaService areaService;
    @Resource
    private CommissionRoleService commissionRoleService;
    @Resource
    private UserCommissionRoleService userCommissionRoleService;
    @Resource
    private GoodsRoleCommissionService goodsRoleCommissionService;
    @Resource
    private DealerOrderService dealerOrderService;
    @Resource
    private DealerWithdrawService dealerWithdrawService;

    public static TransferBatchService transferBatchService;


//  public static String privateKeyPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.modules/src/main/resources/cert/apiclient_key.pem";
//  public static String privateCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/apiclient_cert.pem";
//  public static String wechatpayCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.modules/src/main/resources/cert/wechatpay_2DD5A0669263BAE55E52BF3F35BF4A4006A2DAA6.pem";  // 平台证书

    public static String privateKeyPath = "/Users/gxwebsoft/Downloads/ef7f7e0430cb47019d06b93f885bf95f/apiclient_key.pem";
    public static String privateCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/apiclient_cert.pem";
    public static String wechatpayCertPath = "/Users/gxwebsoft/Downloads/ef7f7e0430cb47019d06b93f885bf95f/wechatpay_55729BDEC2502C301BA02CDC28E4CEE4DE4D1DB9.pem";  // 平台证书


    @Override
    public PageResult<Order> pageRel(OrderParam param) {
        PageParam<Order, OrderParam> page = new PageParam<>(param);
//    page.setDefaultOrder("sort_number asc, create_time desc");
        List<Order> list = baseMapper.selectPageRel(page, param);

        if (param.getSceneType() != null) {
            final Set<Integer> orderIds = list.stream().map(Order::getOrderId).collect(Collectors.toSet());
            if (!CollectionUtils.isEmpty(orderIds)) {
                // 查询预定订单信息
                if (param.getSceneType().equals("showOrderInfo")) {
                    final List<OrderInfo> orderInfoList = orderInfoService.list(new LambdaQueryWrapper<OrderInfo>().in(OrderInfo::getOrderId, orderIds));
                    final Map<Integer, List<OrderInfo>> collect = orderInfoList.stream().collect(Collectors.groupingBy(OrderInfo::getOrderId));
                    list.forEach(d -> {
                        final DateTime date = DateUtil.date(d.getExpirationTime());
                        final DateTime now = DateUtil.date();
                        d.setTimestamp(date.getTime() - now.getTime());
                        if (!collect.isEmpty()) {
                            final List<OrderInfo> orderInfos = collect.get(d.getOrderId());
                            if (!CollectionUtils.isEmpty(orderInfos)) {
                                d.setOrderInfo(orderInfos);
                            }
                        }
                    });
                }
                // 查询商品信息
                if (param.getSceneType().equals("showOrderGoods")) {
                    final List<OrderGoods> goodsList = orderGoodsService.list(new LambdaQueryWrapper<OrderGoods>().in(OrderGoods::getOrderId, orderIds));
                    final Map<Integer, List<OrderGoods>> collect = goodsList.stream().collect(Collectors.groupingBy(OrderGoods::getOrderId));
                    list.forEach(d -> {
                        if (d.getType().equals(1)) {
                            Merchant merchant = merchantService.getById(d.getMerchantId());
                            d.setMerchant(merchant);
                        }
                        final DateTime date = DateUtil.date(d.getExpirationTime());
                        final DateTime now = DateUtil.date();
                        d.setTimestamp(date.getTime() - now.getTime());
                        if (!collect.isEmpty()) {
                            final List<OrderGoods> orderGoodsList = collect.get(d.getOrderId());
                            if (!CollectionUtils.isEmpty(orderGoodsList)) {
                                for (OrderGoods orderGoods : orderGoodsList) {
                                    Goods goods = goodsService.getById(orderGoods.getGoodsId());
                                    if (goods != null) {
                                        BigDecimal originPrice = goods.getPrice();
                                        goods.setPrice(goods.getSalePrice());
                                        if (param.getLoginUser() != null) {
                                            User parentUser = requestUtil.getParent(param.getLoginUser().getUserId());
//                                            if (parentUser != null) {
                                            if (goods.getPriceGift()) goods.setShowGift(true);
//                                                goods.setPrice(originPrice);
//                                            }
                                            // 经销商
//                                            if (param.getLoginUser().getGradeId().equals(33)) {
//                                                if (goods.getDealerGift()) goods.setShowGift(true);
//                                            }
                                            // 会员店
//                                            if (param.getLoginUser().getGradeId() > 30 && goods.getBuyingPriceOpen().equals(1)) {
//                                                goods.setPrice(goods.getBuyingPrice());
////                                                if (goods.getPriceGift()) goods.setShowGift(true);
//                                            }
                                        }
                                    }
                                    if (orderGoods.getSpec() != null && !orderGoods.getSpec().isEmpty()) {
                                        String[] specValue = orderGoods.getSpec().split(" ");
                                        String sku = String.join(",", specValue);
                                        GoodsSku goodsSku = goodsSkuService.getBySku(orderGoods.getGoodsId(), sku);
                                        orderGoods.setGoodsSku(goodsSku);
                                    }
                                    orderGoods.setGoods(goods);
                                }
                                d.setGoodsList(orderGoodsList);
                            }
                        }
                    });
                }
            }
        } else {
            if (!list.isEmpty()) {
                Set<Integer> orderIds = list.stream().map(Order::getOrderId).collect(Collectors.toSet());
                Set<Integer> merchantIds = list.stream().filter(d -> d.getType().equals(1) && d.getMerchantId() != null && d.getMerchantId() != 0)
                        .map(Order::getOrderId).collect(Collectors.toSet());
                List<OrderDelivery> orderDeliveryList = orderDeliveryService.listByOrderIds(orderIds.stream().toList());
                List<Merchant> merchantList = new ArrayList<>();
                if (!merchantIds.isEmpty()) {
                    merchantList = merchantService.listByIds(merchantIds.stream().toList());
                }
                for (Order order : list) {
                    if (order.getDeliveryType() != null && order.getDeliveryType().equals(0)) {
                        OrderDelivery orderDelivery = orderDeliveryList.stream()
                                .filter(d -> d.getOrderId().equals(order.getOrderId())).findAny().orElse(null);
                        if (orderDelivery != null) {
                            orderDelivery.setExpress(expressService.getById(orderDelivery.getExpressId()));
                            order.setOrderDelivery(orderDelivery);
                        }
                    }
                    if (order.getType().equals(0)) {
                        if (order.getDeliveryType() != null && order.getDeliveryType().equals(1)) {
                            Merchant merchant = merchantService.getById(order.getSelfTakeMerchantId());
                            order.setSelfTakeMerchant(merchant);
                        }
                    } else if (order.getType().equals(1)) {
                        Merchant merchant = merchantList.stream().filter(d -> d.getMerchantId().equals(order.getMerchantId()))
                                .findAny().orElse(null);
                        order.setMerchant(merchant);
                    }
                }
            }
        }

        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public List<Order> listRel(OrderParam param) {
        List<Order> list = baseMapper.selectListRel(param);
        // 排序
        PageParam<Order, OrderParam> page = new PageParam<>();
        page.setDefaultOrder("sort_number asc, create_time desc");
        for (Order order : list) {
            List<OrderGoods> orderGoodsList = orderGoodsService.listByOrderId(order.getOrderId());
            for (OrderGoods orderGoods : orderGoodsList) {
                if (orderGoods.getSpec() != null && !orderGoods.getSpec().isEmpty()) {
                    String[] specValue = orderGoods.getSpec().split(" ");
                    String sku = String.join(",", specValue);
                    GoodsSku goodsSku = goodsSkuService.getBySku(orderGoods.getGoodsId(), sku);
                    orderGoods.setGoodsSku(goodsSku);
                }
            }
            order.setGoodsList(orderGoodsList);
        }
        return page.sortRecords(list);
    }

    @Override
    public Order getByIdRel(Integer orderId) {
        OrderParam param = new OrderParam();
        param.setOrderId(orderId);
        Order order = param.getOne(baseMapper.selectListRel(param));
        if (order != null) {
            final List<OrderInfo> list = orderInfoService.list(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderId, orderId));

            // 订单信息
            order.setOrderInfo(list);
            if (!CollectionUtils.isEmpty(list)) {
                final OrderInfo orderInfo = list.get(0);
                final int i = orderInfo.getDateTime().compareTo(DateUtil.today());
            }
            // 订单商品
            final List<OrderGoods> orderGoodsList = orderGoodsService.list(new LambdaQueryWrapper<OrderGoods>().eq(OrderGoods::getOrderId, orderId));
            for (OrderGoods orderGoods : orderGoodsList) {
                orderGoods.setGoods(goodsService.getById(orderGoods.getGoodsId()));
            }
            order.setGoodsList(orderGoodsList);
            // 生成订单核销码
//      requestUtil.setTenantId(order.getTenantId().toString());
//      order.setQrcode(requestUtil.getOrderQRCodeUnlimited(order.getOrderNo()));
            return order;
        }
        return null;
    }

    /**
     * 创建微信支付
     *
     * @param order
     * @return
     */
    @Override
    public HashMap<String, String> createWxOrder(Order order) {
        Integer payType = PAY_TYPE_WECHAT;
        final String uploadPath = config.getUploadPath();   // 服务器本地路径
        final HashMap<String, String> orderInfo = new HashMap<>();
        // 微信小程序(微信支付)
        String key = "mp-weixin:".concat(order.getTenantId().toString());
        final String string = redisUtil.get(key);
        final JSONObject mpWx = JSONObject.parseObject(string);
        String key2 = "Payment:1:".concat(order.getTenantId().toString());
        final Payment payment = redisUtil.get(key2, Payment.class);

        // 计算金额
        BigDecimal decimal = order.getTotalPrice();
        final BigDecimal multiply = decimal.multiply(new BigDecimal(100));
        // 将 BigDecimal 转换为 Integer
//        Integer money = multiply.intValue();
        Integer money = 1;
        String privateKey = uploadPath.concat("/file").concat(payment.getApiclientKey());    // 秘钥证书
        String apiclientCert = uploadPath.concat("/file").concat(payment.getApiclientCert());
        // 开发环境配置
//        if (active.equals("dev")) {
//            privateKey = privateKeyPath;
//            apiclientCert = wechatpayCertPath;
//        }
//        Config config =
//                new RSAConfig.Builder()
//                        .merchantId(payment.getMchId())
//                        .privateKeyFromPath(privateKey)
//                        .merchantSerialNumber(payment.getMerchantSerialNumber())
//                        .wechatPayCertificatesFromPath(apiclientCert)
//                        .build();

        Config config = new RSAAutoCertificateConfig.Builder()
                .apiV3Key(payment.getApiKey())
                .merchantId(payment.getMchId())
                .privateKeyFromPath(privateKey)
                .merchantSerialNumber(payment.getMerchantSerialNumber())
                .build();
        // 构建service
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        // 跟之前下单示例一样，填充预下单参数
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(money);
        amount.setCurrency("CNY");
        request.setAmount(amount);
        request.setAppid(mpWx.getString("appId"));
        request.setMchid(payment.getMchId());
        request.setDescription(order.getComments());
        request.setOutTradeNo(order.getOrderNo());
        request.setAttach(order.getTenantId().toString());
        final Payer payer = new Payer();
        payer.setOpenid(order.getOpenid());
        request.setPayer(payer);
        // 测试环境
        amount.setTotal(money);
        request.setAmount(amount);
        if (order.getNotifyUrl() == null)
            request.setNotifyUrl("https://clinic-api.websoft.top/api/shop/wx-pay/notify/10559"); // 默认回调地址
        else
            request.setNotifyUrl(order.getNotifyUrl());
//    if (StrUtil.isNotBlank(payment.getNotifyUrl())) {
        // 后台配置的回调地址
//      request.setNotifyUrl(payment.getNotifyUrl().concat("/").concat(order.getTenantId().toString()));
//    }
        System.out.println("request = " + request);
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
        orderInfo.put("provider", "wxpay");
        orderInfo.put("timeStamp", response.getTimeStamp());
        orderInfo.put("nonceStr", response.getNonceStr());
        orderInfo.put("package", response.getPackageVal());
        orderInfo.put("signType", "RSA");
        orderInfo.put("paySign", response.getPaySign());
        return orderInfo;
    }

    /***
     * 商家转账（旧）
     */
    @Override
    public void trans(DealerWithdraw dealerWithdraw) {
        String key2 = "Payment:".concat(PAY_TYPE_WECHAT.toString()).concat(":").concat("10559");
        final Payment payment = redisUtil.get(key2, Payment.class);
        String key = "mp-weixin:".concat("10559");
        final String string = redisUtil.get(key);
        final JSONObject mpWx = JSONObject.parseObject(string);
        final String uploadPath = config.getUploadPath();
        String privateKeyPath = uploadPath.concat("/file").concat(payment.getApiclientKey());
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(payment.getMchId())
                        .privateKeyFromPath(privateKeyPath)
                        .merchantSerialNumber(payment.getMerchantSerialNumber())
                        .apiV3Key(payment.getApiKey())
                        .build();
        transferBatchService = new TransferBatchService.Builder().config(config).build();
        InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
        request.setAppid(mpWx.getString("appId"));
        request.setOutBatchNo(dealerWithdraw.getOrderNo());
        request.setBatchName(dealerWithdraw.getOrderNo());
        request.setBatchRemark("采购货款");
        Long totalAmount = dealerWithdraw.getMoney().multiply(new BigDecimal(100)).longValue();
        request.setTotalAmount(totalAmount);
        request.setTotalNum(1);
        List<TransferDetailInput> detailInputList = new ArrayList<>();
        TransferDetailInput detailInput = new TransferDetailInput();
        detailInput.setOutDetailNo(dealerWithdraw.getOrderNo());
        detailInput.setTransferAmount(totalAmount);
        detailInput.setTransferRemark("采购货款");
        detailInput.setOpenid(dealerWithdraw.getOpenId());
        detailInputList.add(detailInput);
        request.setTransferDetailList(detailInputList);
        request.setTransferSceneId("1009");
        request.setNotifyUrl("https://ngb-service-api.websoft.top/api/shop/dealer-withdraw/notify");
        InitiateBatchTransferResponse response = transferBatchService.initiateBatchTransfer(request);
        if (response.getBatchStatus().equals("PROCESSING") || response.getBatchStatus().equals("ACCEPTED")) {
            dealerWithdraw.setApplyStatus(20);
            dealerWithdraw.setAuditTime((int) DateUtil.currentSeconds());
            dealerWithdrawService.updateById(dealerWithdraw);
        }
    }

    /**
     * 发起商家转账(2025新)
     */
    @Override
    public JSONObject transferBill(DealerWithdraw dealerWithdraw) {
        OkHttpClient okHttpClient = new OkHttpClient();
        String key2 = "Payment:".concat(PAY_TYPE_WECHAT.toString()).concat(":").concat("10559");
        final Payment payment = redisUtil.get(key2, Payment.class);
        String key = "mp-weixin:".concat("10559");
        final String string = redisUtil.get(key);
        final JSONObject mpWx = JSONObject.parseObject(string);
        final String uploadPath = config.getUploadPath();
        String privateKeyPath = uploadPath.concat("/file").concat(payment.getApiclientKey());
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(payment.getMchId())
                        .privateKeyFromPath(privateKeyPath)
                        .merchantSerialNumber(payment.getMerchantSerialNumber())
                        .apiV3Key(payment.getApiKey())
                        .build();
        HttpClient httpClient = new DefaultHttpClientBuilder()
                .config(config)
                .okHttpClient(okHttpClient)
                .build();
        HttpHeaders headers = new HttpHeaders();
        headers.addHeader("Accept", MediaType.APPLICATION_JSON.getValue());
        headers.addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue());
        headers.addHeader("Wechatpay-Serial", payment.getMerchantSerialNumber()); // 商户证书序列号

        Long totalAmount = dealerWithdraw.getMoney().multiply(new BigDecimal(100)).longValue();
        HashMap<Object, Object> map = new HashMap<>();
        map.put("appid", payment.getAppId()); //小程序 appId
        map.put("out_bill_no", dealerWithdraw.getOrderNo()); // 订单编号
        map.put("transfer_scene_id", "1009"); // 转账场景ID
        map.put("openid", dealerWithdraw.getOpenId());  // openid
        map.put("transfer_amount", totalAmount);  //金额(分)
        map.put("transfer_remark", "结算"); // 转账备注
        map.put("notify_url", "https://ngb-service-api.websoft.top/api/shop/dealer-withdraw/notify");  //回调地址: 商家转账回调地址
        // 转账场景报备信息
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(new JSONObject().fluentPut("info_type", "采购商品名称").fluentPut("info_content", "牛八哥"));
        map.put("transfer_scene_report_infos", jsonArray);

        JsonRequestBody build = new JsonRequestBody.Builder()
                .body(JSONObject.toJSONString(map))
                .build();
        HttpRequest executeSendGetHttpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.POST)
                .url("https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills")
                .headers(headers)
                .body(build)
                .build();
        try {
            HttpResponse<JSONObject> execute = httpClient.execute(executeSendGetHttpRequest, JSONObject.class);
            dealerWithdraw.setApplyStatus(20);
            dealerWithdraw.setAuditTime((int) DateUtil.currentSeconds());
            dealerWithdrawService.updateById(dealerWithdraw);
            return execute.getServiceResponse();
        } catch (ServiceException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Order getByOutTradeNo(String outTradeNo) {
        OrderParam param = new OrderParam();
        param.setOrderNo(outTradeNo);
        baseMapper.getByOutTradeNo(param);
        return param.getOne(baseMapper.getByOutTradeNo(param));
    }

    @Override
    public Boolean updateByOutTradeNo(Order order) {
        baseMapper.updateByOutTradeNo(order);
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean payByBalance(Order order) {
        final User loginUser = order.getLoginUser();

        if (loginUser.getBalance().compareTo(order.getTotalPrice()) < 0) {
            throw new BusinessException("余额不足");
        }

        // 发起网络请求(更新余额接口)
        requestUtil.setAccessToken(order.getAccessToken());
        requestUtil.setTenantId(order.getTenantId().toString());
        String api = "/system/user/updateUserBalance";  // 更新余额接口
        final BigDecimal subtract = loginUser.getBalance().subtract(order.getTotalPrice());

        loginUser.setBalance(subtract);
        // 累加会员积分
        String key = "SiteInfo:" + order.getTenantId();
        final String siteInfo = redisUtil.get(key);
        // 从缓存读取信息
        if (StrUtil.isNotBlank(siteInfo)) {
            final Website website = JSONObject.parseObject(siteInfo, Website.class);
            final List<WebsiteField> fields = website.getFields();
            if (!CollectionUtils.isEmpty(fields)) {
                fields.forEach(d -> {
                    if (d.getName().equals("integral_enabled") && d.getValue().equals("1")) {
                        loginUser.setPoints(loginUser.getPoints() + order.getPayPrice().intValue());
                    }
                });
            }
        }
        final ApiResult<?> apiResult = requestUtil.updateUserBalance(api, loginUser);
        if (apiResult.getCode().equals(0)) {
            // 修改订单状态
            order.setPayStatus(1);
            order.setPayTime(DateUtil.date());
            order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 10));
            orderService.updateById(order);
            orderInfoService.update(new LambdaUpdateWrapper<OrderInfo>().eq(OrderInfo::getOrderId, order.getOrderId()).set(OrderInfo::getPayStatus, 1));
            // 发放积分
            usersService.addIntegral(order);
            return true;
        }
        return true;
    }

    @Override
    public void settle(Order order) {
        settle(null, "10559", order);
    }

    /***
     * 结算
     * @param order
     */
    @Override
    public void settle(String token, String tenantId, Order order) {
        System.out.println("here settle");
        List<OrderGoods> orderGoodsList = orderGoodsService.listByOrderId(order.getOrderId());
        if (token != null) requestUtil.setAccessToken(token);
        requestUtil.setTenantId(tenantId);
//        System.out.println(parentRes);
        if (order.getType().equals(0) || order.getType().equals(1)) {
            if (order.getShareUserId() != null) {
                User shareUser = requestUtil.getByUserIdWithoutLogin(order.getShareUserId());
                List<Goods> goodsList = goodsService.listByIds(orderGoodsList.stream().map(OrderGoods::getGoodsId).toList());
                BigDecimal shareCommissionTotal = BigDecimal.ZERO;
                for (OrderGoods orderGoods : orderGoodsList) {
                    Goods goods = goodsList.stream().filter(d -> d.getGoodsId().equals(orderGoods.getGoodsId())).findFirst().orElse(null);
                    if (orderGoods.getSpec() != null && !orderGoods.getSpec().isEmpty()) {
                        String[] specValue = orderGoods.getSpec().split(" ");
                        String sku = String.join(",", specValue);
                        GoodsSku goodsSku = goodsSkuService.getBySku(orderGoods.getGoodsId(), sku);
                        shareCommissionTotal = shareCommissionTotal.add(goodsSku.getShareIncome().multiply(BigDecimal.valueOf(orderGoods.getTotalNum())));
                    } else {
                        if (goods != null && goods.getShareIncome() != null && goods.getShareIncome().compareTo(BigDecimal.ZERO) > 0) {
                            shareCommissionTotal = shareCommissionTotal.add(goods.getShareIncome().multiply(BigDecimal.valueOf(orderGoods.getTotalNum())));
                        }
                    }
                }
                if (shareCommissionTotal.compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal finalShareCommissionTotal = shareCommissionTotal;
                    BigDecimal newBalance = shareUser.getBalance().add(shareCommissionTotal);
                    userBalanceLogService.save(new UserBalanceLog() {{
                        setUserId(order.getShareUserId());
                        setScene(BalanceScene.BALANCE_SCENE_SHARE_INCOME);
                        setMoney(finalShareCommissionTotal);
                        setBalance(newBalance);
                        setOrderId(order.getOrderId());
                        setTenantId(getTenantId());
                    }});
                    dealerCapitalService.save(new DealerCapital() {{
                        setUserId(shareUser.getUserId());
                        setFlowType(10);
                        setMoney(finalShareCommissionTotal);
                        setOrderId(order.getOrderId());
                        setDescribe("商品分享收益");
                        setTenantId(getTenantId());
                    }});
                }
            }
        }
        if (order.getType().equals(0)) {
            User parentUser = requestUtil.getParent(order.getUserId());

            // 上级收入
            System.out.println("parentUser = " + (parentUser != null));
            if (parentUser != null) {
//            User parentUser = requestUtil.getUserByPhone(parentRes);
                Merchant parentMerchant = merchantService.getByUserId(parentUser.getUserId());
//                System.out.println("parentMerchant = " + (parentMerchant != null));
                if (parentMerchant != null) {
                    BigDecimal parentCommissionTotal = BigDecimal.ZERO;
                    List<Goods> goodsList = goodsService.listByIds(orderGoodsList.stream().map(OrderGoods::getGoodsId).toList());
                    for (OrderGoods orderGoods : orderGoodsList) {
                        Goods goods = goodsList.stream().filter(d -> d.getGoodsId().equals(orderGoods.getGoodsId())).findFirst().orElse(null);
//                        System.out.println("goods = " + (goods != null));
                        BigDecimal incomeTotal = BigDecimal.ZERO;
                        if (goods != null) {
                            // 有单独设置优先使用
                            BigDecimal parentCommission = goods.getMemberStoreCommission();
                            if (orderGoods.getSpec() != null && !orderGoods.getSpec().isEmpty()) {
                                GoodsSku sku = goodsSkuService.getBySku(goods.getGoodsId(), orderGoods.getSpec());
                                parentCommission = sku.getMemberStoreCommission();
                            }
//                            switch (parentMerchant.getShopType()) {
//                                case "会员店" -> parentCommission = goods.getMemberStoreCommission();
//                                case "供应商" -> parentCommission = goods.getSupplierCommission();
//                                case "合作伙伴" -> parentCommission = goods.getCoopCommission();
//                            }
//                            System.out.println("parentCommission = " + (parentCommission != null));
                            if (parentCommission != null && parentCommission.compareTo(BigDecimal.ZERO) > 0) {
                                incomeTotal = parentCommission.multiply(BigDecimal.valueOf(orderGoods.getTotalNum()));
                                BigDecimal newBalance = parentUser.getBalance().add(incomeTotal);
//                                parentUser.setBalance(newBalance);
//                                requestUtil.updateUserBalanceWithoutLogin(parentUser);
                                BigDecimal finalIncomeTotal = incomeTotal;
                                userBalanceLogService.save(new UserBalanceLog() {{
                                    setUserId(parentUser.getUserId());
                                    setScene(BalanceScene.BALANCE_SCENE_DIRECT_INCOME);
                                    setMoney(finalIncomeTotal);
                                    setBalance(newBalance);
                                    setMerchantId(parentMerchant.getMerchantId());
                                    setMerchantCode(parentMerchant.getMerchantCode());
                                    setOrderId(order.getOrderId());
                                    setTenantId(getTenantId());
                                }});
                                BigDecimal finalIncomeTotal1 = incomeTotal;
                                dealerCapitalService.save(new DealerCapital() {{
                                    setUserId(parentUser.getUserId());
                                    setFlowType(10);
                                    setMoney(finalIncomeTotal1);
                                    setOrderId(order.getOrderId());
                                    setDescribe("发展会员收益");
                                    setTenantId(getTenantId());
                                }});
                            } else {
                                GoodsIncomeConfig goodsIncomeConfig = goodsIncomeConfigService.check(goods.getGoodsId(), orderGoods.getSkuId(), parentMerchant.getShopType());
                                System.out.println("goodsIncomeConfig = " + (goodsIncomeConfig != null));
                                if (goodsIncomeConfig != null) {
                                    BigDecimal rate = goodsIncomeConfig.getRate().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
                                    BigDecimal amountTotal = orderGoods.getPrice().multiply(BigDecimal.valueOf(orderGoods.getTotalNum()));
                                    incomeTotal = amountTotal.multiply(rate).multiply(BigDecimal.valueOf(orderGoods.getTotalNum()));
                                    BigDecimal newBalance = parentUser.getBalance().add(incomeTotal);
//                                    parentUser.setBalance(newBalance);
//                                    requestUtil.updateUserBalanceWithoutLogin(parentUser);
                                    BigDecimal finalIncomeTotal2 = incomeTotal;
                                    userBalanceLogService.save(new UserBalanceLog() {{
                                        setUserId(parentUser.getUserId());
                                        setScene(BalanceScene.BALANCE_SCENE_DIRECT_INCOME);
                                        setMoney(finalIncomeTotal2);
                                        setBalance(newBalance);
                                        setMerchantId(parentMerchant.getMerchantId());
                                        setMerchantCode(parentMerchant.getMerchantCode());
                                        setOrderId(order.getOrderId());
                                        setTenantId(getTenantId());
                                    }});
                                    dealerCapitalService.save(new DealerCapital() {{
                                        setUserId(parentUser.getUserId());
                                        setFlowType(10);
                                        setMoney(finalIncomeTotal2);
                                        setOrderId(order.getOrderId());
                                        setDescribe("发展会员收益");
                                        setTenantId(getTenantId());
                                    }});
                                }
                            }
                            parentCommissionTotal = parentCommissionTotal.add(incomeTotal);
                        }
                    }
                    // 分销订单
                    DealerOrder dealerOrder = new DealerOrder();
                    dealerOrder.setOrderId(order.getOrderId());
                    dealerOrder.setUserId(order.getUserId());
                    dealerOrder.setFirstUserId(parentUser.getUserId());
                    dealerOrder.setOrderPrice(order.getTotalPrice());
                    dealerOrder.setFirstMoney(parentCommissionTotal);
                    dealerOrderService.save(dealerOrder);
                }
            }
            // 供应商收入
            for (OrderGoods orderGoods : orderGoodsList) {
                Goods goods = orderGoods.getGoods();
                if (goods != null) {
                    Merchant supplier = merchantService.getById(goods.getSupplierMerchantId());
                    if (supplier != null) {
                        User supplierUser = requestUtil.getByUserIdWithoutLogin(supplier.getUserId());
                        if (supplierUser != null) {
                            BigDecimal chainStorePrice = goods.getChainStorePrice();
                            if (orderGoods.getSpec() != null && !orderGoods.getSpec().isEmpty()) {
                                GoodsSku sku = goodsSkuService.getBySku(goods.getGoodsId(), orderGoods.getSpec());
                                chainStorePrice = sku.getChainStorePrice();
                            }
                            BigDecimal incomeTotal = chainStorePrice.multiply(BigDecimal.valueOf(orderGoods.getTotalNum()));
                            BigDecimal newBalance = supplierUser.getBalance().add(incomeTotal);
//                            supplierUser.setBalance(newBalance);
//                            requestUtil.updateUserBalanceWithoutLogin(supplierUser);
                            userBalanceLogService.save(new UserBalanceLog() {{
                                setUserId(supplier.getUserId());
                                setScene(BalanceScene.BALANCE_SCENE_SUPPLIER);
                                setMoney(incomeTotal);
                                setBalance(newBalance);
                                setOrderId(order.getOrderId());
                                setMerchantId(supplier.getMerchantId());
                                setMerchantCode(supplier.getMerchantCode());
                                setTenantId(getTenantId());
                            }});
                            dealerCapitalService.save(new DealerCapital() {{
                                setUserId(supplier.getUserId());
                                setFlowType(10);
                                setMoney(incomeTotal);
                                setOrderId(order.getOrderId());
                                setDescribe("供应商收入");
                                setTenantId(getTenantId());
                            }});
                        }
                    }
                }
            }
            // 发货门店/提货门店收入
            Merchant merchant = null;
            if (order.getDeliveryType().equals(0)) merchant = merchantService.getById(order.getExpressMerchantId());
            else merchant = merchantService.getById(order.getSelfTakeMerchantId());
            System.out.println("merchant = " + (merchant != null));

            if (merchant != null) {
//                BigDecimal diffAmountTotal = BigDecimal.ZERO;
                BigDecimal buyAmountTotal = BigDecimal.ZERO;
                User merchantUser = requestUtil.getByUserIdWithoutLogin(merchant.getUserId());
                if (merchantUser != null) {

                    for (OrderGoods orderGoods : orderGoodsList) {
                        Goods goods = orderGoods.getGoods();
                        if (goods != null) {
                            BigDecimal merchantAmount = goods.getSupplierCommission();
                            if (orderGoods.getSpec() != null && !orderGoods.getSpec().isEmpty()) {
                                GoodsSku sku = goodsSkuService.getBySku(goods.getGoodsId(), orderGoods.getSpec());
                                merchantAmount = sku.getSupplierCommission();
                            }
//                        BigDecimal rate = BigDecimal.ZERO;
//                        switch (merchant.getShopType()) {
//                            case "会员店": {
//                                merchantAmount = goods.getMemberStorePrice();
//                                rate = goods.getMemberStoreRate().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
//                            }
//                            break;
//                            case "实体连锁店": {
//                                merchantAmount = goods.getChainStorePrice();
//                                rate = goods.getChainStoreRate().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
//                            }
//                            break;
//                            case "会员超市": {
//                                merchantAmount = goods.getMemberMarketPrice();
//                                rate = goods.getMemberMarketRate().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
//                            }
//                            break;
//                        }
//                        BigDecimal amountDiff = orderGoods.getPrice().subtract(merchantAmount);
//                        buyAmountTotal = buyAmountTotal.add(merchantAmount.multiply(BigDecimal.valueOf(orderGoods.getTotalNum())));
//                        if (amountDiff.compareTo(BigDecimal.ZERO) > 0) {
//                            diffAmountTotal = diffAmountTotal.add(amountDiff.multiply(BigDecimal.valueOf(orderGoods.getTotalNum())));
//                            diffAmountTotal = diffAmountTotal.multiply(rate);
//                        }
                            buyAmountTotal = buyAmountTotal.add(merchantAmount);
                        }
                    }
//                System.out.println("diffAmountTotal = " + diffAmountTotal);
//                System.out.println("buyAmountTotal = " + buyAmountTotal);
                    BigDecimal incomeTotal = buyAmountTotal;
                    if (incomeTotal.compareTo(BigDecimal.ZERO) > 0) {
                        BigDecimal newBalance = merchantUser.getBalance().add(incomeTotal);
//                    merchantUser.setBalance(newBalance);
//                    requestUtil.updateUserBalanceWithoutLogin(merchantUser);
                        Merchant finalMerchant = merchant;
                        userBalanceLogService.save(new UserBalanceLog() {{
                            setUserId(merchantUser.getUserId());
                            setScene(BalanceScene.BALANCE_SCENE_DIFF);
                            setMoney(incomeTotal);
                            setBalance(newBalance);
                            setOrderId(order.getOrderId());
                            setMerchantId(finalMerchant.getMerchantId());
                            setMerchantCode(finalMerchant.getMerchantCode());
                            setTenantId(getTenantId());
                        }});
                        dealerCapitalService.save(new DealerCapital() {{
                            setUserId(merchantUser.getUserId());
                            setFlowType(10);
                            setMoney(incomeTotal);
                            setOrderId(order.getOrderId());
                            setDescribe("仓储管理收益收入");
                            setTenantId(getTenantId());
                        }});
                    }
                }
            }
        } else if (order.getType().equals(1)) {
            // 外卖
            Merchant merchant = merchantService.getById(order.getMerchantId());
            User merchantUser = requestUtil.getByUserIdWithoutLogin(merchant.getUserId());
            if (merchantUser != null) {
                BigDecimal rate = BigDecimal.ONE.subtract(merchant.getCommission().divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP));
                BigDecimal amountTotal = order.getTotalPrice();
                BigDecimal incomeTotal = amountTotal.multiply(rate);
                BigDecimal newBalance = merchantUser.getBalance().add(incomeTotal);
//                merchantUser.setBalance(newBalance);
//                requestUtil.updateUserBalanceWithoutLogin(merchantUser);
                userBalanceLogService.save(new UserBalanceLog() {{
                    setUserId(merchantUser.getUserId());
                    setScene(BalanceScene.BALANCE_SCENE_OUT_TAKE);
                    setMoney(incomeTotal);
                    setBalance(newBalance);
                    setMerchantId(merchant.getMerchantId());
                    setMerchantCode(merchant.getMerchantCode());
                    setOrderId(order.getOrderId());
                    setTenantId(getTenantId());
                }});
                dealerCapitalService.save(new DealerCapital() {{
                    setUserId(merchantUser.getUserId());
                    setFlowType(10);
                    setMoney(incomeTotal);
                    setOrderId(order.getOrderId());
                    setDescribe("门店外卖收入");
                    setTenantId(getTenantId());
                }});
            }
        }
        // 分红
        for (OrderGoods orderGoods : orderGoodsList) {
            Goods goods = orderGoods.getGoods();
            if (goods.getCommissionRole().equals(1)) {
                int provinceId = 0, cityId = 0, regionId = 0;
                if (order.getDeliveryType().equals(0)) {
                    provinceId = order.getProvinceId();
                    cityId = order.getCityId();
                    regionId = order.getRegionId();
                } else {
                    Merchant merchant = merchantService.getById(order.getSelfTakeMerchantId());
                    Area province = areaService.areaInfoByName(merchant.getProvince(), 1);
                    Area city = areaService.areaInfoByName(merchant.getCity(), 2);
                    Area region = areaService.areaInfoByName(merchant.getRegion(), 3);
                    provinceId = province.getId();
                    cityId = city.getId();
                    regionId = region.getId();
                }
                if (provinceId != 0) {
                    List<CommissionRole> commissionRoleList = commissionRoleService.listByProvinceId(provinceId);
                    if (!commissionRoleList.isEmpty()) {
                        for (CommissionRole commissionRole : commissionRoleList) {
                            List<UserCommissionRole> userCommissionRoleList = userCommissionRoleService.listByMap(
                                    new HashMap<>() {{
                                        put("role_id", commissionRole.getId());
                                    }}
                            );
                            BigDecimal avgAmount = BigDecimal.ZERO;
                            GoodsRoleCommission goodsRoleCommission = goodsRoleCommissionService.getByRoleNGoods(commissionRole.getId(), goods.getGoodsId());
                            if (goodsRoleCommission != null) {
                                avgAmount = goodsRoleCommission.getAmount().divide(BigDecimal.valueOf(userCommissionRoleList.size()), RoundingMode.HALF_UP)
                                        .setScale(2, RoundingMode.HALF_UP);
                            }
                            if (avgAmount.compareTo(BigDecimal.ZERO) > 0) {
                                for (UserCommissionRole userCommissionRole : userCommissionRoleList) {
                                    User merchantUser = requestUtil.getByUserIdWithoutLogin(userCommissionRole.getUserId());
                                    BigDecimal newBalance = merchantUser.getBalance().add(avgAmount);
                                    BigDecimal finalAvgAmount = avgAmount;
                                    userBalanceLogService.save(new UserBalanceLog() {{
                                        setUserId(merchantUser.getUserId());
                                        setScene(BalanceScene.BALANCE_SCENE_OUT_TAKE);
                                        setMoney(finalAvgAmount);
                                        setBalance(newBalance);
//                                        setMerchantId(merchantUser.getMerchantId());
//                                        setMerchantCode(merchant.getMerchantCode());
                                        setOrderId(order.getOrderId());
                                        setTenantId(getTenantId());
                                    }});
                                    dealerCapitalService.save(new DealerCapital() {{
                                        setUserId(merchantUser.getUserId());
                                        setFlowType(10);
                                        setMoney(finalAvgAmount);
                                        setOrderId(order.getOrderId());
                                        setDescribe(commissionRole.getTitle() + "分红收入");
                                        setTenantId(getTenantId());
                                    }});
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /***
     * 实际结算
     */
    @Override
    public void doSettle(Integer orderId) {
        List<DealerCapital> dealerCapitalList = dealerCapitalService.unSettleList(orderId);
        List<UserBalanceLog> userBalanceLogList = userBalanceLogService.unSettleList(orderId);
        if (!dealerCapitalList.isEmpty()) {
            requestUtil.setTenantId("10559");
            for (DealerCapital dealerCapital : dealerCapitalList) {
                dealerCapital.setStatus(1);
                User user = requestUtil.getByUserIdWithoutLogin(dealerCapital.getUserId());
                BigDecimal newBalance = user.getBalance().add(dealerCapital.getMoney());
                user.setBalance(newBalance);
                requestUtil.updateUserBalanceWithoutLogin(user);
            }
            dealerCapitalService.updateBatchById(dealerCapitalList);
        }
        if (!userBalanceLogList.isEmpty()) {
            for (UserBalanceLog userBalanceLog : userBalanceLogList) {
                userBalanceLog.setStatus(1);
            }
            userBalanceLogService.updateBatchById(userBalanceLogList);
        }
    }

    @Override
    public int shopUnExpressNum(Integer merchantId) {
        return count(
                new LambdaQueryWrapper<Order>()
                        .eq(Order::getMerchantId, merchantId)
                        .eq(Order::getOrderStatus, 0)
                        .eq(Order::getPayStatus, 1)
//                        .eq(Order::getDeliveryType, 0)
                        .in(Order::getType, 0, 1)
        );
    }

    @Override
    public Order getByOrderNo(String orderNo) {
        return getOne(
                new LambdaQueryWrapper<Order>()
                        .eq(Order::getOrderNo, orderNo)
                        .last("limit 1")
        );
    }

    @Override
    public Order getByOrderNo(String orderNo, Integer tenantId) {
        return getOne(
                new LambdaQueryWrapper<Order>()
                        .eq(Order::getOrderNo, orderNo)
                        .eq(Order::getTenantId, tenantId)
                        .last("limit 1")
        );
    }
}
