package com.tax.token.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tax.token.constants.TokenConstants;
import com.tax.token.model.TkToken;
import com.yxcheng.token.utils.HttpConnectionManager;
import com.yxcheng.token.utils.Security;
import com.yxcheng.token.utils.UUIDGenerator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class NationUtil {

    private static Logger logger = (Logger) LoggerFactory.getLogger(NationUtil.class);

    static String  url = TokenConstants.NATION_URL;

    private static String suffixUrl = "NSbsqWW/login.do";

    private static String signUrl = "https://token.invservice.cn/signService/getLoginSign";
    //private static String xmUrl = "http://192.168.142.184:8880/TokenManage/step";
    //private static String xmUrl = "http://60.205.224.101:8182/token/step";
    private static String xmUrl = TokenConstants.TOKEN_CORE_URL;
            //"http://172.16.4.156:8180/token/step";

    static String accessKeyID = "yxclient";
    static String accessKeySecret = "Lkks#wfv3k!";

    public static JSONObject tokenValidCheck(TkToken tkToken) throws IOException {
        String param = "rtype=0301&data=";
        JSONObject data = new JSONObject();
        data.put("cert",tkToken.getTaxno());
        data.put("token",tkToken.getToken());
        data.put("dqdm",tkToken.getZoneCode());
        param += data.toString();

        String result = null;
        if(TokenConstants.isDebug()){
            result = "{\"key1\":\"01\"}";
        }else{
           result = post(url,param,false);
        }
        return JSON.parseObject(result);
    }

    public static boolean isValid(TkToken tkToken){
        boolean flag = false;
        try {
            JSONObject jsonObject = tokenValidCheck(tkToken);
            if("01".equals(jsonObject.get("key1"))){
                flag = true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }

    private static String post(String urls,String param,boolean isJson) throws IOException {
        String result="";
        PrintWriter out=null;
        BufferedReader in = null;
        try {
            URL url = new URL(urls);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 设置通用属性  Content-Type:
            connection.setRequestProperty("Accept","*/*");
            connection.setRequestProperty("Connection","Keep-Alive");
            if (isJson) {
                connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            }else{
                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            }
            connection.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            out = new PrintWriter(connection.getOutputStream());
            out.write(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
            String line;

            while ((line=in.readLine())!=null){
                result += line;
            }
            System.out.println(param + "11111111111======"+result);
        }finally {
            try {
                if (out != null){
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static void setUrl(String url) {
        NationUtil.url = url;
    }


    public static JSONObject serverAuth(String url,String clientHello,String version) {
        url += suffixUrl;

        HttpClient httpClient = HttpConnectionManager.httpsTrustClient();
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).build();
        List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
        params.add(new BasicNameValuePair("type", "CLIENT-HELLO"));
        params.add(new BasicNameValuePair("clientHello", clientHello));
        params.add(new BasicNameValuePair("ymbb", version));
        logger.info("serverAuth param:{}", params);


        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        HttpResponse response = null;
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            int times = 0;
            while (times<3){
                response = httpClient.execute(httpPost);
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String content = EntityUtils.toString(entity);
                    content = content.substring(content.indexOf("{"),content.lastIndexOf("}") + 1);
                    logger.info("serverAuth result:{}", content);
                    JSONObject jsonObject = JSONObject.parseObject(content);
                    if("01".equals(jsonObject.get("key1"))){
                        return jsonObject;
                    }
                }
                times++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(httpPost!=null){
                httpPost.releaseConnection();
                httpPost.abort();
            }
        }
        return null;
    }


    public static String getToken(String url,String taxno,String clientAuth,String key3,String version,String sign,String ts){
        url += suffixUrl;
        HttpClient httpClient = HttpConnectionManager.httpsTrustClient();
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).build();
        List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
        params.add(new BasicNameValuePair("type", "CLIENT-AUTH"));
        params.add(new BasicNameValuePair("password", ""));
        params.add(new BasicNameValuePair("cert", taxno));
        params.add(new BasicNameValuePair("clientAuthCode", clientAuth));
        params.add(new BasicNameValuePair("serverRandom", key3));//serverRandom
        params.add(new BasicNameValuePair("ymbb", version));
        params.add(new BasicNameValuePair("publickey", sign));
        params.add(new BasicNameValuePair("ts", ts));
        params.add(new BasicNameValuePair("alg", "0"));
        params.add(new BasicNameValuePair("currdate", String.valueOf(new Date().getTime())));

        logger.info("getToken param:{}", params);
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        HttpResponse response = null;
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String content = EntityUtils.toString(entity);
                content = content.substring(content.indexOf("{"),content.lastIndexOf("}") + 1);
                JSONObject json = JSONObject.parseObject(content);

                logger.info("getToken result:{}", content);

                if("03".equals(json.get("key1"))){
                    logger.info("第二次 登录成功：token:{}",json.getString("key2"));
                    return json.getString("key2");
                }

                logger.info("第二次 登录失败{}",taxno);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(httpPost!=null){
                httpPost.releaseConnection();
                httpPost.abort();
            }
        }
        return null;
    }



    public static JSONObject firstLogin(String uuidFlag, String taxno,String clientHello,String zoneCode){

        HttpClient httpClient = HttpConnectionManager.httpsTrustClient();

        String param = "type=1&cert=%s&clientHello=%s&dqdm=%s";
        param = String.format(param,taxno,clientHello,zoneCode);

        logger.info(uuidFlag + " taxno is " + taxno + ",url is " + xmUrl +  " firstLogin param:{}", param);
        HttpGet httpGet = new HttpGet(xmUrl + "?" + param);

        HttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                String content = EntityUtils.toString(entity);
                logger.info(uuidFlag + " taxno is " + taxno + " firstLogin return:{}", content);
                JSONObject json = JSONObject.parseObject(content);
                if("01".equals(json.get("key1"))){
                    logger.info(uuidFlag + " taxno is " + taxno + " 第一次 登录成功：token:{}",json.getString("key2"));
                    return json;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(httpGet!=null){
                httpGet.releaseConnection();
                httpGet.abort();
            }
        }
        return null;
    }


    public static String secondLogin(String uuidFlag, String taxno,String clientAuthCode,String zoneCode,String serverRandom,String secert){

        HttpClient httpClient = HttpConnectionManager.httpsTrustClient();
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).build();
        List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
        params.add(new BasicNameValuePair("type", "2"));
        params.add(new BasicNameValuePair("cert", taxno));
        params.add(new BasicNameValuePair("clientAuthCode", clientAuthCode));
        params.add(new BasicNameValuePair("serverRandom", serverRandom));
        params.add(new BasicNameValuePair("secert", secert));
        params.add(new BasicNameValuePair("dqdm", zoneCode));

        String param = "type=2&cert=%s&clientAuthCode=%s&serverRandom=%s&secert=%s&dqdm=%s";
        param = String.format(param,taxno,clientAuthCode,serverRandom,secert,zoneCode);

        logger.info(uuidFlag + " taxno is " + taxno + ",secondLogin is " + xmUrl + "?" + param);

        HttpGet httpGet = new HttpGet(xmUrl + "?" + param);
        HttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String content = EntityUtils.toString(entity);
//                content = content.substring(content.indexOf("{"),content.lastIndexOf("}") + 1);
                JSONObject json = JSONObject.parseObject(content);

                logger.info(uuidFlag + " taxno is " + taxno + ",secondLogin result is " + content.toString());
                if("0".equals(json.get("code"))){
                    logger.info(taxno + " 第二次 登录成功：token:{}",json.getString("token"));
                    return json.getString("token");
                }

                logger.info(taxno + " 第二次 登录失败{}",taxno);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(httpGet!=null){
                httpGet.releaseConnection();
                httpGet.abort();
            }
        }
        return null;
    }


    public static JSONObject sign(String taxno,String areaCode,String serverRandom){
        String url = signUrl;

        HttpClient httpClient = HttpConnectionManager.httpsTrustClient();

        String signStr = "accessKeyID=%s&signatureNonce=%s&timeStamp=%s&version=1.0";

        String signatureNonce = UUIDGenerator.generate();
        SimpleDateFormat sdf = new SimpleDateFormat(
                "yyyy-MM-dd'T'HH:mm:ss'Z'");
        String timeStamp = sdf.format(new Date());

        signStr = String.format(signStr,accessKeyID,signatureNonce, timeStamp);
        url += "?" + signStr + ("&signature=" + getSign(signStr));
        url += "&taxno="+taxno+"&dqdm="+areaCode+"&serverRandom=" + serverRandom;
        logger.info("sign param:{}",url);

        HttpGet httpget = new HttpGet(url);
        HttpResponse response = null;
        try {
            response = httpClient.execute(httpget);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String content = EntityUtils.toString(entity);
                JSONObject jsonObject = JSONObject.parseObject(content);
                if("0".equals(jsonObject.get("errorCode"))){
                    return jsonObject.getJSONObject("data");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(httpget!=null){
                httpget.releaseConnection();
                httpget.abort();
            }
        }
        return null;
    }


    public static String getSign(String data){
        try {
            return Security.getSignature(data.getBytes("UTF-8"),accessKeySecret.getBytes("UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) throws IOException {
        NationUtil.setUrl("http://39.106.216.105:8880/fpcxService/QxrzServlet.do");
        TkToken tkToken = new TkToken();
        tkToken.setTaxno("91320214MA1MJ0PK54");
        tkToken.setToken("2~0~0~~1~0~0~0~0~0~1~b4ed7512-e38d-47d2-8a7b-c38cbdcc15dc");
        tkToken.setZoneCode("3200");
        System.out.println(NationUtil.tokenValidCheck(tkToken));
    }



}
