package com.jsowell.thirdparty.lutongyunting.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.sign.MD5Util;
import com.jsowell.pile.dto.lutongyunting.BindCouponDTO;
import com.jsowell.pile.dto.lutongyunting.GetTokenDTO;
import com.jsowell.thirdparty.lutongyunting.common.LTYTCommonParams;
import com.jsowell.thirdparty.lutongyunting.service.LTYTService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * TODO
 *
 * @author Lemon
 * @Date 2023/8/23 11:19
 */
@Service
public class LTYTServiceImpl implements LTYTService {

    @Autowired
    private RedisCache redisCache;

    // private static final String APP_ID = "I2qa3hdr116100dc"; // I2qa3hdr116100dc    I2qa3jfnd96f267c

    // private static final String SECRET_KEY = "2qa3hdr13754a8e"; // 2qa3hdr13754a8e   2qa3jfndb37926d

    private static final String BASE_URL = "https://entry-openapi.sn6.co/api/";

    private static final Logger log = LoggerFactory.getLogger(LTYTServiceImpl.class);

    /**
     * 路通云停系统获取令牌
     * @param dto
     * @return
     */
    @Override
    public String getToken(GetTokenDTO dto) {
        // 检查缓存中是否有token
        String key = CacheConstants.LTYT_TOKEN_BY_APPID + dto.getAppId();
        String token = redisCache.getCacheObject(key);
        if (StringUtils.isNotBlank(token)) {
            return token;
        }
        // String appId = "I2qa3hdr116100dc";
        String accTime = DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS);

        String url = BASE_URL + "getApiToken";

        // 封装参数
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", dto.getAppId());
        jsonObject.put("accTime", accTime);
        jsonObject.put("version", "1.0");

        // 获取sign签名
        String sign = getSign(jsonObject, dto.getSecretKey());
        jsonObject.put("sign", sign);

        // 发送请求
        String result = HttpUtil.post(url, JSON.toJSONString(jsonObject));
        log.info("路通云停系统获取令牌 result:{}", result);
        JSONObject resultJson = JSONObject.parseObject(result);
        Integer code = resultJson.getInteger("code");
        if (code == 200) {
            token = resultJson.getJSONObject("data").getString("token");
            Integer expiredTime = resultJson.getJSONObject("data").getInteger("expiry");
            // 存入缓存
            redisCache.setCacheObject(key, token, expiredTime, TimeUnit.HOURS);
            return redisCache.getCacheObject(key);
        }else {
            return null;
        }
    }

    /**
     * 给指定车辆绑定优惠券
     * @param dto
     * @return
     */
    @Override
    public String bindCoupon(BindCouponDTO dto) throws UnsupportedEncodingException {
        // 获取令牌
        GetTokenDTO tokenDTO = new GetTokenDTO();
        tokenDTO.setAppId(dto.getAppId());
        tokenDTO.setSecretKey(dto.getSecretKey());
        String token = getToken(tokenDTO);
        if (StringUtils.isBlank(token)) {
            throw new BusinessException("", "路通云停系统 给指定车辆绑定优惠券 方法获取令牌失败");
        }

        String url = BASE_URL + "bindCoupon";
        JSONObject jsonObject = new JSONObject();
        // 公共参数
        jsonObject.put("appId", dto.getAppId());
        jsonObject.put("token", token);
        jsonObject.put("accTime", DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS));
        jsonObject.put("version", "1.0");
        // 业务参数
        jsonObject.put("merchantId", dto.getMerchantId());
        jsonObject.put("couponId", dto.getCouponId());
        jsonObject.put("plateNumber", dto.getPlateNumber());
        jsonObject.put("plateColor", dto.getPlateColor());

        String encodeData = URLEncoder.encode(JSON.toJSONString(jsonObject), "UTF-8");
        jsonObject.put("data", encodeData);

        // 发送请求
        String result = HttpUtil.post(url, JSON.toJSONString(jsonObject));
        log.info("给指定车辆绑定优惠券 params:{}, result:{}", JSON.toJSONString(jsonObject), result);
        JSONObject resultJson = JSONObject.parseObject(result);

        return resultJson.getString("msg");
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("merchantId", "merchantId");
        jsonObject.put("couponId", "couponId");
        jsonObject.put("plateNumber", "plateNumber");
        jsonObject.put("plateColor", 2);

        String encodeData = URLEncoder.encode(JSON.toJSONString(jsonObject), "UTF-8");
        System.out.println(encodeData);
        // String accTime = DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS);
        // Map<String, Object> map = new LinkedMap<>();
        // map.put("appId", "appId");
        // map.put("accTime", accTime);
        // map.put("version", "version");
        // System.out.println(map);
        // // 排序
        // TreeMap<String, Object> params = new TreeMap<String, Object>(map);
        //
        // StringBuilder sb = new StringBuilder();
        // for (String key : params.keySet()) {
        //     sb.append(key).append("=").append(params.get(key)).append("&");
        // }
        // sb.deleteCharAt(sb.length() - 1);
        //
        // String dataStr = sb + "secretKey";
        // String sign = MD5Util.MD5Encode(dataStr).toLowerCase(Locale.ROOT);
        // System.out.println(sign);
    }

    private static String getSign(JSONObject jsonObject, String secretKey) {
        // String secretKey = "";
        TreeMap<String, Object> params = new TreeMap<>(jsonObject);

        StringBuilder sb = new StringBuilder();
        for (String key : params.keySet()) {
            sb.append(key).append("=").append(params.get(key)).append("&");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append(secretKey);
        return MD5Util.MD5Encode(sb.toString()).toLowerCase(Locale.ROOT);
    }
}
