package com.gxwebsoft.apps.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.apps.entity.Hualala;
import com.gxwebsoft.apps.entity.HualalaFoodCategory;
import com.gxwebsoft.apps.entity.HualalaShop;
import com.gxwebsoft.apps.mapper.HualalaMapper;
import com.gxwebsoft.apps.param.HualalaShopParam;
import com.gxwebsoft.apps.service.HualalaService;
import com.gxwebsoft.shop.entity.Merchant;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.entity.OrderGoods;
import com.gxwebsoft.shop.mapper.OrderGoodsMapper;
import com.gxwebsoft.shop.param.MerchantParam;
import com.gxwebsoft.shop.service.OrderGoodsService;
import lombok.SneakyThrows;
import lombok.val;
import org.apache.commons.codec.binary.Base64;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;
import java.util.stream.Collectors;

import static com.gxwebsoft.apps.constants.HualalaConstants.*;
import static com.gxwebsoft.apps.constants.SfExpressConstants.*;
import static com.gxwebsoft.common.core.constants.RedisConstants.MERCHANT_GEO_KEY;

/**
 * 哗啦啦Service实现
 *
 * @author 科技小王子
 * @since 2022-11-25 12:55:33
 */
@Service
public class HualalaServiceImpl extends ServiceImpl<HualalaMapper, Hualala> implements HualalaService {
  @Resource
  private OrderGoodsMapper orderGoodsMapper;

  @Override
  public JSONObject doPost(String url, Map<String, Object> requestBody) {
    // 当前时间戳
    Long timestamp = System.currentTimeMillis();
    // 店铺ID
    String shopId = null;
    if(requestBody.get("shopId") != null){
      shopId = requestBody.get("shopId").toString();
    }
    HashMap<String,Object> map = new HashMap<>();
    map.put("timestamp",timestamp);
    map.put("appKey",APP_KEY);
    map.put("signature",getSignature(timestamp,requestBody));
    map.put("version",VERSION);
    map.put("requestBody", JSON.toJSONString(requestBody));
    System.out.println("map = " + map);
    // 执行post请求
    String result = HttpRequest.post(API_URL.concat(url))
      .header("traceID", UUID.randomUUID().toString())
      .header("groupID", GROUP_ID)
      .header("shopId",shopId)
      .form(map)
      .timeout(20000)
      .execute()
      .body();
//    System.out.println("result0 = " + result);

    // 返回数据
    return JSON.parseObject(result);
  }

    @Override
    public JSONObject doExpress(Order orderInfo) {
      List<OrderGoods> orderGoods = orderGoodsMapper.selectByOrderId(orderInfo.getOrderId());

      JSONObject json = new JSONObject();
      json.put("dev_id",DEV_ID);      // 同城开发者ID
      json.put("shop_id",SHOP_ID);    // 店铺ID
      json.put("shop_order_id", orderInfo.getOrderNo());    // 商家订单号 不允许重复(使用相同商家订单号会幂等返回)
      json.put("order_source","微信小程序");       // 订单接入来源 1：美团；2：饿了么；3：饿了么零售；4：口碑； 其他请直接填写中文字符串值
      long timestamp = new Date().getTime();
      System.out.println("timestamp = " + timestamp);
      json.put("order_time",timestamp/1000);      // 用户下单时间
      json.put("push_time",timestamp/1000);       // 推单时间
      json.put("version",19);     // 版本号 19

      // 收货人信息
      JSONObject receive = new JSONObject();
      receive.put("user_name","顺丰同城");     // 用户姓名
      receive.put("user_phone","18978189563");// 用户电话
      receive.put("user_address","北京市海淀区学清嘉创大厦A座15层");    // 用户地址
      receive.put("user_lng","116.354787");   // 用户经度
      receive.put("user_lat","40.030613");    // 用户纬度
      json.put("receive",receive);

      // 物品详情
      ArrayList<Object> productDetail = new ArrayList<>();
      orderGoods.forEach(goods -> {
        JSONObject item = new JSONObject();
        item.put("product_name",goods.getGoodsName());
        item.put("product_id",goods.getGoodsId());
        item.put("product_num",goods.getTotalNum());
        item.put("product_price",goods.getTotalPrice());
        item.put("product_unit","份");
        item.put("item_detail","");
        productDetail.add(item);
      });

      // 订单详情
      JSONObject orderDetail = new JSONObject();
      orderDetail.put("total_price",orderInfo.getTotalPrice());   // 用户订单商品总金额（单位：分）
      orderDetail.put("product_type",21);   // 物品类型 21:中餐
      orderDetail.put("weight_gram",0);   // 物品重量（单位：克）
      orderDetail.put("product_num",1);     // 物品个数
      orderDetail.put("product_type_num",1);// 物品种类个数
      orderDetail.put("product_detail",productDetail);  // 物品详情
      json.put("order_detail",orderDetail);
      String postData = json.toString();

      System.out.println("postData = " + postData);

      String url = SERVER_HOST.concat("/open/api/external/createorder?sign=").concat(generateOpenSign(postData));
      String result = HttpUtil.post(url, postData);
      JSONObject jsonObject = JSON.parseObject(result);
      return JSON.parseObject(jsonObject.getString("result"));
    }

    // 生成签名(哗啦啦)
  private String getSignature(Long timestamp,Map<String, Object> params) {
    // 拼接字符串
    String sign = "";
    params.put("groupID",GROUP_ID);
    String concat = sign.concat(APP_KEY).concat(APP_SECRET).concat(timestamp.toString()).concat(JSON.toJSONString(params));
//    System.out.println("签名加密前字符串为 = " + concat);
    // md5加密
    String md5 = DigestUtil.md5Hex(concat);
//    System.out.println("md5加密后获得签名 = " + md5);
    return md5;
  }

  // 生成签名(顺丰速递)
  @SneakyThrows
  private static String generateOpenSign(String postData) {
    StringBuilder sb =  new StringBuilder();
    sb.append(postData);
    sb.append("&" + DEV_ID + "&" + DEV_KEY);
    System.out.println("sb = " + sb);
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] md5 = md.digest(sb.toString().getBytes(StandardCharsets.UTF_8));
    int i;
    StringBuffer buf = new StringBuffer("");
    for (int offset = 0; offset < md5.length; offset++) {
      i = md5[offset];
      if (i < 0) {
        i += 256;
      }
      if (i < 16) {
        buf.append("0");
      }
      buf.append(Integer.toHexString(i));
    }

    return Base64.encodeBase64String(buf.toString().getBytes(StandardCharsets.UTF_8));
  }
}
