package com.gxwebsoft.apps.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.gxwebsoft.apps.entity.HualalaFood;
import com.gxwebsoft.apps.entity.HualalaShop;
import com.gxwebsoft.apps.entity.ItemVo;
import com.gxwebsoft.apps.result.*;
import com.gxwebsoft.apps.service.HualalaFoodService;
import com.gxwebsoft.apps.service.HualalaService;
import com.gxwebsoft.apps.service.HualalaShopService;
import com.gxwebsoft.common.core.utils.CacheClient;
import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.entity.OrderGoods;
import com.gxwebsoft.shop.param.OrderParam;
import com.gxwebsoft.shop.service.OrderGoodsService;
import com.gxwebsoft.shop.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.val;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.gxwebsoft.common.core.constants.OrderConstants.PAY_STATUS_SUCCESS;
import static com.gxwebsoft.common.core.constants.RedisConstants.*;

/**
 * 哗啦啦-购物车
 * 教程参考 https://blog.csdn.net/qq_34383510/article/details/127824628
 * @author 科技小王子
 * @since 2022-11-25 12:55:33
 */
@Api(tags = "哗啦啦-购物车")
@RestController
@RequestMapping("/api/apps/hualala-cart")
public class HualalaCart extends BaseController {

  @Resource
  private StringRedisTemplate stringRedisTemplate;
  @Resource
  private CacheClient cacheClient;
  @Resource
  private HualalaService hualalaService;
  @Resource
  private HualalaFoodService hualalaFoodService;
  @Resource
  private OrderService orderService;
  @Resource
  private OrderGoodsService orderGoodsService;
  @Resource
  private HualalaShopService hualalaShopService;

  @ApiOperation("我的购物车")
  @GetMapping()
  public ApiResult<?> cart(ItemVo param) {
    String key = getKey(param.getShopId());

    return success("查询成功",showCart(key));
  }

  @ApiOperation("添加购物车")
  @PostMapping("/addCart")
  public ApiResult<?> addCart(@RequestBody ItemVo param) {
    String key = getKey(param.getShopId());
    cacheClient.hPut(key,param.getFoodId().toString(),JSONUtil.toJSONString(param));

    return success("添加成功",showCart(key));
  }

  @ApiOperation("生成订单并清空购物车")
  @PostMapping("/createOrder")
  public ApiResult<?> createOrder(@RequestBody Order order){
    String key = getKey(order.getShopId().toString());
    // 记录当前登录用户id、租户id
    User loginUser = getLoginUser();
    if (loginUser != null) {
      order.setUserId(loginUser.getUserId());
    }
    order.setMerchantCode(order.getShopId().toString());
    order.setPayMethod("通联支付");
    if (orderService.save(order)) {
      // 添加订单商品
      List<Object> hValues = cacheClient.hValues(key);
      hValues.forEach(d -> {
        JSONObject json = JSONObject.parseObject(d.toString());
        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setOrderId(order.getOrderId());
        orderGoods.setGoodsName(json.getString("foodName"));
        orderGoods.setImageUrl(json.getString("imge"));
        orderGoods.setTotalNum(Integer.valueOf(json.getString("num")));
        orderGoods.setGoodsId(Integer.valueOf(json.getString("foodId")));
        orderGoods.setGoodsSkuId(json.getString("foodUnitID"));
        orderGoods.setUserId(getLoginUserId());
        BigDecimal totalPrice = new BigDecimal(json.getString("price"));
        orderGoods.setTotalPrice(totalPrice);
        orderGoods.setTenantId(getTenantId());
        orderGoodsService.save(orderGoods);
      });

      // 清空购物车
      cacheClient.delete(key);
      return success("订单创建成功",order);
    }
    return fail("订单创建失败");
  }

  @ApiOperation("通联支付")
  @PostMapping("/allinPay")
  public ApiResult<?> allinPay(@RequestBody Order order){
    Order orderInfo = orderService.getById(order.getOrderId());
    System.out.println("orderInfo = " + orderInfo);
    final HualalaShop shop = hualalaShopService.getByIdRel(orderInfo.getShopId());
    final String payMerchantNo = shop.getPayMerchantNo();
    final String paySecret = shop.getPaySecret();
    System.out.println("payMerchantNo = " + payMerchantNo);
    System.out.println("paySecret = " + paySecret);

    // 正式接口
    String url = "https://interface.allinpaygx.com/api/access/payInterface/unifiedPay";
    // 测试接口
//    String url = "https://interfacetest.allinpaygx.com/api/access/payInterface/unifiedPay";
//    System.out.println("接口地址 = " + url);
    // map传参数
    Map<String, Object> map = new HashMap<>();
    // 计算金额
    final BigDecimal orderPrice = orderInfo.getOrderPrice().multiply(new BigDecimal(100));
    final int amount = Integer.parseInt(orderPrice.stripTrailingZeros().toPlainString());
    map.put("merchantNo", payMerchantNo); // 正式商户
//    map.put("merchantNo", "113201120053"); // 测试商户：113201120053
    map.put("merchantOrderNo", orderInfo.getOrderNo());
    map.put("amount",String.valueOf(amount));
    map.put("notifyUrl","https://open.gxwebsoft.com/api/apps/hualala-cart/payNotify");
    map.put("payType","W06S");
    // 附加签名
    String sign = getSign(map,paySecret);
    System.out.println("sign = " + sign);
    map.put("sign",sign);
    System.out.println("请求参数 = " + map);
    String result = HttpUtil.post(url,map);
    System.out.println("result = " + result);
    JSONObject resultObj = JSON.parseObject(result);
    JSONObject payinfo = JSON.parseObject(resultObj.getString("payinfo"));
    System.out.println("payinfo = " + payinfo);
    return success("支付参数",payinfo);
  }

  public static String getSign(Map<String, Object> treeMap, String paySecret) {
//    String secret = paySecret;  // 正式秘钥
//    String secret = "aceb62c896d849c89d1c8b9a4416d1a7";  // 测试秘钥
    TreeMap<String, String> tMap = new TreeMap<>();
    for (Map.Entry<String, Object> entry : treeMap.entrySet()) {
      if (!StrUtil.isEmpty(entry.getValue().toString()) && !entry.getKey().equals("sign")) {
        tMap.put(entry.getKey(), entry.getValue().toString());
      }
    }
    StringBuffer buf = new StringBuffer();
    for (String key : tMap.keySet()) {
      buf.append(key).append(treeMap.get(key));
    }
    buf.append(paySecret);
    System.out.println("buf = " + buf);
    return DigestUtil.md5Hex(buf.toString()).toUpperCase();
  }

  @ApiOperation("通联支付")
  @PostMapping("/payNotify")
  public String payNotify(@RequestParam Map<String, String> params){
    // 支付成功
    if (orderService.allinPay(params)) {
      return "success";
    }
    return "error";

  }

  @ApiOperation("交易查询")
  @PostMapping("/findOrderInfo")
  public ApiResult<?> findOrderInfo(@RequestBody Order order){
    final Order data = orderService.getByOutTradeNo(order.getOrderNo().toString());
    return success("查询结果",data);
  }


  // 获取Key
  private String getKey(String shopId) {
    return HLL_CART_FOOD_KEY.concat(shopId).concat(":").concat(getLoginUserId().toString());
  }

  private OperateVo showCart(String key){
    // 获取购物车数据
    List<Object> values = cacheClient.hValues(key);
//    System.out.println("values = " + values);
    List<ItemVo> collect = values.stream().map(item -> JSONUtil.parseObject(JSONUtil.toJSONString(item), ItemVo.class)).collect(Collectors.toList());
//    System.out.println("collect = " + collect);

    // 封装数据结果
    OperateVo operateVo = new OperateVo();
    operateVo.setTotalNum(0);
    operateVo.setTotalPrice(BigDecimal.valueOf(0));
    operateVo.setItems(collect);
    collect.forEach(d -> {
//      System.out.println("operateVo.getTotalNum() + d.getNum() = " + operateVo.getTotalNum() + d.getNum());
      operateVo.setTotalNum(operateVo.getTotalNum()+d.getNum());
      operateVo.setTotalPrice(operateVo.getTotalPrice().add(d.getPrice().multiply(BigDecimal.valueOf(d.getNum()))));
    });
//    System.out.println("operateVo = " + operateVo);
    return operateVo;
  }


  @ApiOperation("通联支付2")
  @PostMapping("/test")
  public ApiResult<?> test(){
    final Order order = orderService.getByOutTradeNo("2023030149684157");
    order.setPayStatus(PAY_STATUS_SUCCESS);
    order.setPayPrice(order.getTotalPrice());
    orderService.updateById(order);
    return success("成功",order);
  }
}
