package com.fs.erp.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.db.sql.Order;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.fs.erp.converter.ErpWdtToErpOrderMapper;
import com.fs.erp.domain.ErpOrder;
import com.fs.erp.domain.ErpRefundOrder;
import com.fs.erp.dto.*;
import com.fs.erp.dto.sdk.wangdian.api.WdtClient;
import com.fs.erp.dto.sdk.wangdian.enums.*;
import com.fs.erp.dto.wdt.*;
import com.fs.erp.service.IErpOrderService;
import com.fs.store.domain.FsStoreOrder;
import com.fs.store.domain.FsStoreProduct;
import com.fs.store.service.IFsStoreOrderItemService;
import com.fs.store.service.IFsStoreOrderService;
import com.fs.store.service.IFsStoreProductService;
import com.fs.store.vo.FsStoreOrderItemVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.http.client.utils.DateUtils;
import org.apache.http.util.Asserts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;
import java.util.HashMap;

@Slf4j
@Service
@Primary
public class WdtErpOrderServiceImpl implements IErpOrderService {

    @Autowired
    private IFsStoreOrderService fsStoreOrderService;

    @Autowired
    private IFsStoreOrderItemService fsStoreOrderItemService;

    @Autowired
    private IFsStoreProductService fsStoreProductService;

    @Value("${fsConfig.erpWdShopCode}")
    private String shopCode;

    /**
     * 普通推送
     */
    private static final Integer NORMAL_TYPE = 1;
    /**
     * 退款推送
     */
    private static final Integer REFUND_TYPE = 2;
    @Override
    public ErpOrderResponse addOrder(ErpOrder order) {
        return getErpOrderResponse(order,NORMAL_TYPE);
    }

    /**
     *
     * @param order 订单参数
     * @param type 1正常 2退款
     * @return
     */
    private ErpOrderResponse getErpOrderResponse(ErpOrder order,Integer type) {
        WdtClient client = WdtClient.getInstance();
        //测试环境sid、appkey、密钥请到旺店通开放平台-自助对接-申请测试环境内查看，测试环境url=https://sandbox.wangdian.cn/openapi2/
        //调用正式环境时请将sid、appkey、appsecret切换为实际参数，参数在旺店通开放平台-自助对接-应用管理内应用状态为已上线的应用中查看，调用正式环境注意切换正式环境url=https://api.wangdian.cn/openapi2/

        ErpWdtBusinessRequestParams erpWdtBusinessRequestParams = new ErpWdtBusinessRequestParams();
        erpWdtBusinessRequestParams.setShopNo(shopCode);
        erpWdtBusinessRequestParams.setSwitchMode(0);
        ErpWdtTrade erpWdtTrade = new ErpWdtTrade();

        // 订单id
        erpWdtTrade.setTid(order.getPlatform_code());
        // 平台状态
        if(Objects.equals(type, NORMAL_TYPE)){
            erpWdtTrade.setTradeStatus(TradeStatus.PAID_WAITING_FOR_SHIPMENT.getValue());
        }else if(Objects.equals(type, REFUND_TYPE)){
            erpWdtTrade.setTradeStatus(TradeStatus.REFUNDED.getValue());
        }

        // 支付状态
        erpWdtTrade.setPayStatus(PaymentStatus.FULLY_PAID.getValue());
        // 发货条件
        erpWdtTrade.setDeliveryTerm(DeliveryTerm.PAYMENT_BEFORE_DELIVERY.getValue());
        // 下单时间
        erpWdtTrade.setTradeTime(order.getDeal_datetime());
        // 支付时间
        erpWdtTrade.setPayTime(order.getDeal_datetime());
        // 分销类别
        erpWdtTrade.setFenxiaoType(FenxiaoType.JINGXIAO.getValue());
        // 客户网名
        erpWdtTrade.setBuyerNick(order.getReceiver_name());
        // 收件人姓名
        erpWdtTrade.setReceiverName(order.getReceiver_name());
        // 省份
        erpWdtTrade.setReceiverProvince(order.getReceiver_province());
        // 市
        erpWdtTrade.setReceiverCity(order.getReceiver_city());
        // 区
        erpWdtTrade.setReceiverDistrict(order.getReceiver_district());
        // 详细地址
        erpWdtTrade.setReceiverAddress(order.getReceiver_address());
        // 手机
        erpWdtTrade.setReceiverMobile(order.getReceiver_mobile());
        // 固定电话
        erpWdtTrade.setReceiverTelno(order.getReceiver_mobile());
        // 买家备注
        erpWdtTrade.setBuyerMessage(order.getBuyer_memo());
        // 卖家备注
        erpWdtTrade.setSellerMemo(order.getSeller_memo());
        erpWdtTrade.setWarehouseNo(order.getWarehouse_code());

        // 已付金额
        FsStoreOrder fsStoreOrder = fsStoreOrderService.selectFsStoreOrderByOrderCode(order.getPlatform_code());
        // 运费金额
        erpWdtTrade.setPostAmount(fsStoreOrder.getFreightPrice());
        if(ObjectUtils.isNotNull(fsStoreOrder)){
            erpWdtTrade.setPaid(fsStoreOrder.getPayMoney());
        }

        List<FsStoreOrderItemVO> fsStoreOrderItemVOS = fsStoreOrderItemService.selectFsStoreOrderItemListByOrderId(fsStoreOrder.getId());
        List<ErpWdtOrder> erpWdtOrderList = new ArrayList<>();


        // 优惠券金额
        BigDecimal couponPrice = fsStoreOrder.getCouponPrice();
        // 商品总价
        BigDecimal totalPrice = fsStoreOrder.getTotalPrice();
        for (FsStoreOrderItemVO fsStoreOrderItem : fsStoreOrderItemVOS) {
            ErpWdtOrder erpWdtOrder = new ErpWdtOrder();
            //平台订单货品表主键
            erpWdtOrder.setOid(String.format("%s%s",fsStoreOrderItem.getOrderCode(),fsStoreOrderItem.getItemId()));
            erpWdtOrder.setNum(BigDecimal.valueOf(fsStoreOrderItem.getNum()));
            FsStoreProduct fsStoreProduct = fsStoreProductService.selectFsStoreProductById(fsStoreOrderItem.getProductId());
            Asserts.check(ObjectUtils.isNotNull(fsStoreProduct),"该产品不存在! 产品id: {} ",fsStoreOrderItem.getProductId());
            // 单价
            erpWdtOrder.setPrice(fsStoreProduct.getPrice());
            // 状态
            if(Objects.equals(type, NORMAL_TYPE)){
                erpWdtOrder.setStatus(TradeStatus.SHIPPED.getValue());
                // 退款状态
                erpWdtOrder.setRefundStatus(RefundStatus.NO_REFUND.getValue());
            } else {
                erpWdtOrder.setStatus(TradeStatus.REFUNDED.getValue());
                // 退款状态
                erpWdtOrder.setRefundStatus(RefundStatus.REFUND_SUCCESSFUL.getValue());
            }

            // 平台货品ID
            erpWdtOrder.setGoodsId(String.valueOf(fsStoreProduct.getProductId()));
            JSONObject jsonObject = JSON.parseObject(fsStoreOrderItem.getJsonInfo());
            erpWdtOrder.setSpecId(jsonObject.getString("sku"));
            erpWdtOrder.setGoodsNo(jsonObject.getString("barCode"));
            erpWdtOrder.setSpecNo(jsonObject.getString("sku"));
            // 货品名称
            erpWdtOrder.setGoodsName(fsStoreProduct.getProductName());
            // 调整
            erpWdtOrder.setAdjustAmount(BigDecimal.ZERO);
            // 优惠
            erpWdtOrder.setDiscount(BigDecimal.ZERO);
            // 分摊优惠
            // 分摊比例
            BigDecimal divide = fsStoreProduct.getPrice().divide(totalPrice, RoundingMode.HALF_UP);
            erpWdtOrder.setShareDiscount(divide.multiply(couponPrice));

            erpWdtOrderList.add(erpWdtOrder);
        }

        // 最后一个商品的分摊优惠等于总优惠减去前面分摊优惠之和
        Asserts.check(CollectionUtils.isNotEmpty(erpWdtOrderList),"订单 {} 商品不能为空!", order.getPlatform_code());
        long size = erpWdtOrderList.size();
        if(size > 1) {
            ErpWdtOrder erpWdtOrder = erpWdtOrderList.get(erpWdtOrderList.size() - 1);
            erpWdtOrder.setShareDiscount(couponPrice.subtract(erpWdtOrderList.stream()
                            .limit(size - 1L)
                    .map(item -> Optional.ofNullable(item.getShareDiscount()).orElse(BigDecimal.ZERO))
                    .reduce(BigDecimal.ZERO, BigDecimal::add)));
        }

        erpWdtTrade.setOrderList(erpWdtOrderList);
        erpWdtBusinessRequestParams.setTradeList(new ArrayList<>(Arrays.asList(erpWdtTrade)));

        Map<String,String> map = new HashMap<>();
        map.put("shop_no",erpWdtBusinessRequestParams.getShopNo());
        map.put("switch_mode", String.valueOf(erpWdtBusinessRequestParams.getSwitchMode()));
        map.put("trade_list", convertToSnakeCase(erpWdtBusinessRequestParams.getTradeList()));


        try {
            String response = client.execute("trade_push.php", map);
            ParserConfig config = new ParserConfig();
            config.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
            ErpWdtApiResponse erpWdtApiResponse = JSON.parseObject(response, ErpWdtApiResponse.class,config);
            if(ObjectUtil.equal(0,erpWdtApiResponse.getCode())){
                log.info("订单推送成功: {}", response);
                ErpOrderResponse erpOrderResponse = new ErpOrderResponse();
                erpOrderResponse.setCode(order.getPlatform_code());
                return erpOrderResponse;
            } else {
                throw new RuntimeException(String.format("订单推送失败,原因: %s",erpWdtApiResponse.getMessage()));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ErpOrderResponse();
    }

    @Override
    public ErpOrderResponse refundOrder(ErpRefundOrder order) {
        return null;
    }

    @Override
    public ErpDeliverysResponse getDeliver(ErpDeliverysRequest param) {
        return null;
    }

    @Override
    public ErpOrderQueryResponse getOrder(ErpOrderQueryRequert param) {
        WdtClient client = WdtClient.getInstance();
        Map<String,String> map = new HashMap<>();
        map.put("src_tid",param.getCode());
        try {
            String execute = client.execute("sales_trade_query.php", map);
            ParserConfig config = new ParserConfig();
            config.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
            ErpWdtTradeQueryResponse tradeQueryResponseDTO = JSON.parseObject(execute, ErpWdtTradeQueryResponse.class);
            if(ObjectUtil.equal(0,tradeQueryResponseDTO.getCode())){
                ErpOrderQueryResponse erpOrderQueryResponse = ErpWdtToErpOrderMapper.INSTANCE.toErpOrderQueryResponse(tradeQueryResponseDTO);
                log.info("查询订单成功: {}", erpOrderQueryResponse);
                return erpOrderQueryResponse;
            } else {
                throw new RuntimeException(String.format("查询订单失败, 原因: %s", tradeQueryResponseDTO.getMessage()));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public BaseResponse refundUpdate(ErpRefundUpdateRequest param) {
        log.info("退款单更新: {}", param);
        FsStoreOrder fsStoreOrder = fsStoreOrderService.selectFsStoreOrderByOrderCode(param.getTid());

        // 待发货状态，售前退款
        if(ObjectUtil.equal(1, fsStoreOrder.getStatus())){
            log.info("售前退款 参数: {}",param);
            try {
                ErpOrder order = fsStoreOrderService.getErpOrder(fsStoreOrder);

                Asserts.check(ObjectUtils.isNotNull(order),"该订单不存在!");

                return getErpOrderResponse(order,REFUND_TYPE);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        //--------------售后退款------------
        log.info("售后退款 参数: {}", param);
        WdtClient client = WdtClient.getInstance();
        Map<String,String> map = new HashMap<>();


        Asserts.check(ObjectUtils.isNotNull(fsStoreOrder), "该订单不存在! 订单id: {} ", param.getTid());

        List<FsStoreOrderItemVO> fsStoreOrderItemVOS = fsStoreOrderItemService.selectFsStoreOrderItemListByOrderId(fsStoreOrder.getId());
        List<ErpWdtRefundOrder> refundOrders = new ArrayList<>();

        for (FsStoreOrderItemVO item : fsStoreOrderItemVOS) {
            refundOrders.add(ErpWdtRefundOrder.builder()
                    .oid(String.format("%s%s",item.getOrderCode(),item.getItemId()))
                    .num(BigDecimal.ONE)
                    .build());
        }
        List<ErpWdtApiRefund> erpWdtApiRefunds = Collections.singletonList(ErpWdtApiRefund.builder()
                .platformId(127)
                .shopNo(shopCode)
                .tid(param.getTid())
                .refundNo(param.getTid())
                .type(RefundTypeEnum.REFUND_BEFORE_SHIPPING.getCode())
                .status(AfterSaleStatusEnum.SUCCESS.getCode())
                .refundTime(DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"))
                .orderList(refundOrders)
                .build());


        map.put("api_refund_list",convertToSnakeCase(erpWdtApiRefunds));
        try {
            String execute = client.execute("sales_refund_push.php", map);
            ParserConfig config = new ParserConfig();
            config.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
            ErpWdtApiResponse erpWdtApiResponse = JSON.parseObject(execute, ErpWdtApiResponse.class,config);
            if(ObjectUtil.equal(0, erpWdtApiResponse.getCode())){
                log.info("退款单更新成功: {}", erpWdtApiResponse);
                return new BaseResponse();
            } else {
                log.info("退款单更新失败: {}", erpWdtApiResponse);
                throw new RuntimeException(String.format("退款单更新失败, 原因: %s", erpWdtApiResponse.getMessage()));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static String convertToSnakeCase(Object obj) {
        SerializeConfig config = new SerializeConfig();
        config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
        return JSON.toJSONString(obj, config);
    }

}
