package com.liquidnet.service.platform.controller.basicServices;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 阿里云上传
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-07-09
 */
@Api(tags = "basicServices")
@RestController
@RequestMapping("basicServices/wechatShareSign")
public class WechatShareController {

    @Value("${liquidnet.zhengzai-wechat.appid}")
    private String zhengzaiAppid;
    @Value("${liquidnet.zhengzai-wechat.secret}")
    private String zhengzaiSecret;

    @Value("${liquidnet.modernsky-wechat.appid}")
    private String modernskyAppid;
    @Value("${liquidnet.modernsky-wechat.secret}")
    private String modernskySecret;

    @Autowired
    private RedisUtil redisUtil;

    @GetMapping("/zhengzai")
    @ApiOperation("正在微信分享sign")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "query", dataType = "String", name = "url", value = "url地址 注意 URL 一定要动态获取，不能 hardcode", required = true),
    })
    public Map<String, String> zhengzai(@RequestParam String url) {
        String accessToken = accessToken(zhengzaiAppid, zhengzaiSecret);
        String jsapiTicket = jsapiTicket(zhengzaiAppid, accessToken);

        Map<String, String> ret = sign(jsapiTicket, url);
        return ret;
    }

    @GetMapping("/modernsky")
    @ApiOperation("摩登微信分享sign")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "query", dataType = "String", name = "url", value = "url地址 注意 URL 一定要动态获取，不能 hardcode", required = true),
    })
    public Map<String, String> modernsky(@RequestParam String url) {
        String accessToken = accessToken(modernskyAppid, modernskySecret);
        String jsapiTicket = jsapiTicket(modernskyAppid, accessToken);

        Map<String, String> ret = sign(jsapiTicket, url);
        return ret;
    }

    public static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
//        System.out.println(string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        ret.put("url", url);
//        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    private String accessToken(String appid, String secret) {
        String accessTokenRedisKey = KylinRedisConst.WECHAT_SHARE_ACCESSTOKEN.concat(appid);
        String accessToken = "";
        if (!redisUtil.hasKey(accessTokenRedisKey)) {
            // 请求微信获取 access_token
            String accessTokenUrl = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, secret);
            JsonObject object = null;
            try {
                CloseableHttpClient client = HttpClients.createDefault();
                HttpGet httpGet = new HttpGet(accessTokenUrl);
                HttpResponse httpResponse = client.execute(httpGet);
                HttpEntity httpEntity = httpResponse.getEntity();
                String tokens = EntityUtils.toString(httpEntity, "utf-8");
                Gson token_gson = new Gson();
                object = token_gson.fromJson(tokens, JsonObject.class);
                accessToken = object.get("access_token").toString().replaceAll("\"", "");
                redisUtil.set(accessTokenRedisKey, accessToken, 7200);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            accessToken = (String) redisUtil.get(accessTokenRedisKey);
        }
        return accessToken;
    }

    private String jsapiTicket(String appid, String accessToken) {
        String jsapiTicketRedisKey = KylinRedisConst.WECHAT_SHARE_JSAPI_TICKET.concat(appid);
        String jsapiTicket = "";
        if (!redisUtil.hasKey(jsapiTicketRedisKey)) {
            // 获取 jsapi_ticket
            String ticketUrl = String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi", accessToken);
            JsonObject object = null;
            try {
                CloseableHttpClient client = HttpClients.createDefault();
                HttpGet httpGet = new HttpGet(ticketUrl);
                HttpResponse httpResponse = client.execute(httpGet);
                HttpEntity httpEntity = httpResponse.getEntity();
                String tokens = EntityUtils.toString(httpEntity, "utf-8");
                Gson token_gson = new Gson();
                object = token_gson.fromJson(tokens, JsonObject.class);
                jsapiTicket = object.get("ticket").toString().replaceAll("\"", "");
                redisUtil.set(jsapiTicketRedisKey, jsapiTicket, 7200);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            jsapiTicket = (String) redisUtil.get(jsapiTicketRedisKey);
        }
        return jsapiTicket;
    }

}
