package com.yinet.wx.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.yinet.common.config.Global;
import com.yinet.common.utils.http.HttpUtils;
import com.yinet.wx.domain.WxCache;
import com.yinet.wx.mapper.WxCacheMapper;
import com.yinet.wx.service.WxService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * 网上预约列表Service业务层处理
 *
 * @author yinet
 * @date 2019-09-02
 */
@Service
public class WxServiceImpl implements WxService {
    @Autowired
    WxCacheMapper wxMapper;
    private static String wxAppid = Global.getWxAppid();
    private static String wxAppSecret = Global.getWxAppSecret();

    @Override
    public WxCache getWxCache() {
        return wxMapper.getAccessToken();
    }

    @Override
    public int updateWxCache(WxCache accessToken) {
        WxCache wxCache = getWxCache();
        if (wxCache == null) {
            return wxMapper.insertWxCache(accessToken);
        } else {
            accessToken.setWxCacheId(wxCache.getWxCacheId());
            return wxMapper.updateWxCache(accessToken);
        }
    }

    @Override
    public WxCache getToken() throws IOException {
        //https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
        WxCache wxCache = getWxCache();
        if (wxCache != null && wxCache.getAccessToken() != null && !isTimeOut(wxCache.getTokenTime())) {
            return wxCache;
        } else {
            wxCache = new WxCache();
            String s = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/token", "grant_type=client_credential&appid=" + wxAppid + "&secret=" + wxAppSecret);
            JSONObject jsonObject = JSONObject.parseObject(s);
            wxCache.setAccessToken(jsonObject.getString("access_token"));
            wxCache.setTokenTime(new Date());
            int i = updateWxCache(wxCache);
            return wxCache;
        }
    }

    @Override
    public WxCache getJsTicket() throws IOException {
        //http://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=ACCESS_TOKEN
        WxCache wxCache = getWxCache();
        if (wxCache != null && wxCache.getJsapiTicket() != null && !isTimeOut(wxCache.getTicketTime())) {
            return wxCache;
        } else {
            wxCache = getToken();
            String s = HttpUtils.sendGet("http://api.weixin.qq.com/cgi-bin/ticket/getticket", "type=jsapi&access_token=" + wxCache.getAccessToken());
            JSONObject jsonObject = JSONObject.parseObject(s);
            wxCache.setJsapiTicket(jsonObject.getString("ticket"));
            wxCache.setTicketTime(new Date());
            int i = updateWxCache(wxCache);
            return wxCache;
        }
    }

    public static boolean isTimeOut(Date date) {
        long a = new Date().getTime();
        long b = date.getTime();
        int c = (int) ((a - b) / 1000);
        return c > 7000;
    }

    @Override
    public Map<String, String> sign(String url) throws IOException {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";
        WxCache wxCache = getJsTicket();
        //注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + wxCache.getJsapiTicket() +
                "&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", wxCache.getJsapiTicket());
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appid", Global.getWxAppid());
        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);
    }

    @Override
    public JSONObject getOpenIdByCode(String code) {
        //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code //获取微信用户openId
        String s = HttpUtils.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token", "appid=" + wxAppid + "&secret=" + wxAppSecret + "&code=" + code + "&grant_type=authorization_code");
        return JSONObject.parseObject(s);
    }

    public JSONObject getUserInfo(String code) {
        //https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN          //获取微信用户信息
        JSONObject accessTokenByCode = getOpenIdByCode(code);
        String s = HttpUtils.sendGet("https://api.weixin.qq.com/sns/userinfo", "access_token=" + accessTokenByCode.getString("access_token") + "&openid=" + accessTokenByCode.getString("openid") + "&lang=zh_CN");
        return JSONObject.parseObject(s);
    }

}
