package com.tax.file.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tax.file.constants.FileConstants;
import com.tax.file.model.*;
import com.yxcheng.token.common.cache.RedisService;
import com.yxcheng.token.constants.RedisContants;
import com.yxcheng.token.utils.*;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.lang.StringUtils;
import org.apache.http.*;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class NationUtil {

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

    static String  url = FileConstants.nationUrl;

    public static String defaultPwd = "Doc25CwQ";

    public static String unzipSuffix = "-extract";

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

    static String testUrl = "http://39.106.193.77:8880/fpcxService/QxrzServlet.do";

    public static JSONObject fileDownApply(String uuidFlag, TkFile tkFile) throws IOException {
        String param = "rtype=0601&data=";
        JSONObject data = new JSONObject();
        data.put("cert",tkFile.getTaxno());
        data.put("token",tkFile.getToken());
        data.put("jymm",tkFile.getDecPwd());
        data.put("sjlxs",tkFile.getInvSpec());
        data.put("fplxs",tkFile.getInvType());
        data.put("dqdm",tkFile.getZoneCode());
        data.put("kprq_q",DateUtils.date2Str(tkFile.getInvDateStart(), DateUtils.date_sdf));
        data.put("kprq_z",DateUtils.date2Str(tkFile.getInvDateEnd(),DateUtils.date_sdf));
        param += data.toString();

        String result = requestNation(tkFile,param);

        logger.info(uuidFlag + " request 0601 interface, the param is " + param + ", the result is " + result);
        return JSON.parseObject(fixSimpleJson(result));
    }

    public static String requestNation(TkFile tkFile,String param) throws IOException {
        String result = post(getZoneUrl(tkFile.getZoneCode()), param, false);
        return result;
    }

    public static String requestNation(String zoneCode,String param) throws IOException {
        String result = post(getZoneUrl(zoneCode), param, false);
        return result;
    }


    public static JSONObject fileDown(String uuidFlag, TkFile tkFile) throws IOException {
        String param = "rtype=0602&data=";
        JSONObject data = new JSONObject();
        data.put("cert",tkFile.getTaxno());
        data.put("token",tkFile.getToken());
        data.put("wjm",tkFile.getFileName());
        data.put("dqdm",tkFile.getZoneCode());
        param += data.toString();
        String result = requestNation(tkFile,param);
        logger.info(uuidFlag + " taxno is " + tkFile.getTaxno() + " request 0602 interface, the param is " + param + ", the result is " + StringUtil.getShortLog(result, 300));
        return JSON.parseObject(result);
    }

    public static JSONObject fileDownQuery(String uuidFlag, TkFile tkFile, PageModel page) throws IOException {
        String param = "rtype=0603&data=";
        SimpleDateFormat date_sdf = new SimpleDateFormat(
                "yyyy-MM-dd");
        JSONObject data = new JSONObject();
        data.put("cert",tkFile.getTaxno());
        data.put("token",tkFile.getToken());
        data.put("dqdm",tkFile.getZoneCode());
        data.put("rq_q",DateUtils.date2Str(tkFile.getInvDateStart(),date_sdf));
        data.put("rq_z",DateUtils.date2Str(tkFile.getInvDateEnd(),date_sdf));
        if(page!=null){
            data.put("sEcho",String.valueOf(page.getsEcho()));
            data.put("iDisplayStart",String.valueOf(page.getiDisplayStart()));
            data.put("iDisplayLength",String.valueOf(page.getiDisplayLength()));
        }
        param += data.toString();
        String result =  requestNation(tkFile,param);

        logger.info(uuidFlag + " request 0603 interface, the param is " + param + ", the result is " + StringUtil.getShortLog(result, 300));
        return JSON.parseObject(result);
    }


    private static String getZoneUrl(String zoneCode){
        String url = NationUtil.url;
        RedisService redisService = SpringUtil.getBean(RedisService.class);
        if(redisService.exists(RedisContants.ZONE_CODE + zoneCode)) {
            FinZoneInfo finZoneInfo =JSON.parseObject(redisService.get(RedisContants.ZONE_CODE + zoneCode),  FinZoneInfo.class);
            url = finZoneInfo.getZoneUrl();
        }
        return url;
    }


    public static JSONObject incomeFileUpload(FIncomeInvoice entity) throws IOException {
        JSONObject map = new JSONObject();
        map.put("cert",entity.getTaxno());
        map.put("token",entity.getToken());
        map.put("dqdm",entity.getZoneCode());
        Map data = new HashMap();
        data.put("rtype","0818");
        data.put("data",map.toJSONString());



        String result = upload(getZoneUrl(entity.getZoneCode()),entity.getFilePath(),data);
        return JSON.parseObject(result);
    }

    /**
     * ["12", "2020-04-24", "6", "6", "处理成功", "2020-04-24", "<a onclick=xzrzmx('171ab0b33a6testnode10898'); href='javascript:void(0);'><font color=red>下载</a>"],
     * @param entity
     * @return
     * @throws IOException
     */
    public static JSONObject incomeResultQuery(FIncomeInvoice entity) throws IOException {
        String param = "rtype=0819&data=";
        SimpleDateFormat date_sdf = new SimpleDateFormat(
                "yyyy-MM-dd");
        JSONObject data = new JSONObject();
        data.put("cert",entity.getTaxno());
        data.put("token",entity.getToken());
        data.put("dqdm",entity.getZoneCode());
        data.put("rq_q",DateUtils.date2Str(entity.getApplyDateBegin(),date_sdf));
        data.put("rq_z",DateUtils.date2Str(entity.getApplyDateEnd(),date_sdf));

        param += data.toString();
        System.out.println(param);
        String result = null;
//        if(FileConstants.isDebug()){
//            result = "{\"key1\":\"01\",\"key2\":{\"iTotalDisplayRecords\":2,\"iTotalRecords\":2,\"aaData\":[[\"1\",\"2020-04-01 01:00:27\",\"增值税专用发票\",\"2020-03-14\",\"2020-03-24\",\"销项票\",\"处理完成\",\"不存在符合条件的发票\"],[\"2\",\"2020-04-01 01:00:27\",\"机动车销售统一发票\",\"2020-03-14\",\"2020-03-24\",\"销项票\",\"处理完成\",\"不存在符合条件的发票\"]],\"sEcho\":2}}";
//        }else{
        result = post(getZoneUrl(entity.getZoneCode()),param,false);
        //       }

        return JSON.parseObject(result);
    }


    /**
     * {"key1":"01","key2":"12344","file":"0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAOwADAP7/"}
     * @param entity
     * @return
     * @throws IOException
     */
    public static JSONObject incomeFileDown(FIncomeInvoice entity) throws IOException {
        String param = "rtype=0820&data=";
        JSONObject data = new JSONObject();
        data.put("cert",entity.getTaxno());
        data.put("token",entity.getToken());
        data.put("dqdm",entity.getZoneCode());
        data.put("rzlsh",entity.getFileId());

        param += data.toString();

        System.out.println(param);
        String result = null;
//        if(FileConstants.isDebug()){
//            result = "{\"key1\":\"01\",\"key2\":{\"iTotalDisplayRecords\":2,\"iTotalRecords\":2,\"aaData\":[[\"1\",\"2020-04-01 01:00:27\",\"增值税专用发票\",\"2020-03-14\",\"2020-03-24\",\"销项票\",\"处理完成\",\"不存在符合条件的发票\"],[\"2\",\"2020-04-01 01:00:27\",\"机动车销售统一发票\",\"2020-03-14\",\"2020-03-24\",\"销项票\",\"处理完成\",\"不存在符合条件的发票\"]],\"sEcho\":2}}";
//        }else{
        result = post(getZoneUrl(entity.getZoneCode()),param,false);
        //       }

        return JSON.parseObject(result);
    }



    public static JSONObject incomeSingleQuery(FIncomeInvoice entity) throws IOException {
        String param = "rtype=0821&data=";
        SimpleDateFormat date_sdf = new SimpleDateFormat(
                "yyyy-MM-dd");
        JSONObject data = new JSONObject();
        data.put("cert",entity.getTaxno());
        data.put("token",entity.getToken());
        data.put("dqdm",entity.getZoneCode());
        data.put("fpdm",entity.getInvKind());
        data.put("fphm",entity.getInvNum());

        param += data.toString();
        System.out.println(param);
        String result = null;
//        if(FileConstants.isDebug()){
//            result = "{\"key1\":\"01\",\"key2\":{\"iTotalDisplayRecords\":2,\"iTotalRecords\":2,\"aaData\":[[\"1\",\"2020-04-01 01:00:27\",\"增值税专用发票\",\"2020-03-14\",\"2020-03-24\",\"销项票\",\"处理完成\",\"不存在符合条件的发票\"],[\"2\",\"2020-04-01 01:00:27\",\"机动车销售统一发票\",\"2020-03-14\",\"2020-03-24\",\"销项票\",\"处理完成\",\"不存在符合条件的发票\"]],\"sEcho\":2}}";
//        }else{
        result = post(getZoneUrl(entity.getZoneCode()),param,false);
        //       }

        return JSON.parseObject(result);
    }

    public static JSONObject incomeMonthQuery(String uuidFlag, TkTaxUser taxUser, String token) throws IOException {
        String param = "rtype=0302&data=";
        JSONObject data = new JSONObject();
        data.put("cert",taxUser.getTaxno());
        data.put("token",token);
        data.put("dqdm",taxUser.getZoneCode());
        data.put("rznf","");
        param += data.toString();

        String result = post(getZoneUrl(taxUser.getZoneCode()),param,false);
        logger.info(uuidFlag + " request 0302 interface, the param is " + param + ", the result is " + result);
        return JSON.parseObject(result);
    }

    private static String fixSimpleJson(String str){
        if(StringUtils.isBlank(str)) {
            return null;
        }
        String result = "{";
        str = str.replaceAll("\"","");
        str = str.substring(1,str.length()-1);
        for(String s : str.split(",")){
            String[] entry = s.split(":");
            result += ("\"" + entry[0] +"\"");
            result += (":\"" + entry[1] +"\",");
        }
        result = result.substring(0,result.length()-1);
        result+="}";
        return result;
    }


    public static String downFile(JSONObject jsonObject, FIncomeInvoice entity) throws Exception {
        String fileDPath = FileUtils.filePath(FileConstants.nationFilePath, entity.getZoneCode(), entity.getUserName(), entity.getTaxno());
        String fileFullName = fileDPath + UUID.randomUUID().toString() + ".xls";
        return defaultDownToNative(jsonObject,fileDPath,fileFullName);
    }

    public static String getPath(TkFile tkFile){
        return File.separator + tkFile.getTaxno() +"_" + tkFile.getInvSpec() + "_" + tkFile.getInvType() +"_" + UUID.randomUUID().toString().replaceAll("-","");
    }
    public static String downToNative(JSONObject jsonObject, TkFile tkFile,String fileDPath, String suffix) throws Exception {
        String fileName = tkFile.getFileName();
        if(isWindows()){
            fileName = fileName.replaceAll("/","\\\\");
            System.out.println("downToNative fileName  windows: " +fileName);
        }
        String fileFullName = fileDPath + ZipDecompress.getOriginName(fileName) + unzipSuffix + "." + suffix;
        return defaultDownToNative(jsonObject,fileDPath,fileFullName);
    }

    public static String downToNative2(JSONObject jsonObject,String fileDPath, String fileFullName) throws Exception {
        String fileName = fileDPath + File.separator + fileFullName;
        return defaultDownToNative(jsonObject,fileDPath,fileName);
    }

    public static String defaultDownToNative(JSONObject jsonObject, String fileDPath, String fileFullName) throws Exception {
        String fileStr = jsonObject.getString("file");
        FileUtils.createDirectory(fileDPath);
        byte[]bytes = Base64Util.decode(fileStr);
        File file = new File(fileFullName);
        if(file.exists()){
            file.delete();
        }
        FileUtils.writeByteArrayToFile(file,bytes);
        return fileFullName;
    }


    public static boolean isWindows(){
        return  System.getProperty("os.name").toLowerCase().indexOf("windows")>=0;
    }


    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;
            }
        }finally {
            try {
                if (out != null){
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }


    private static String upload(String url,String filePath,Map<String,String> params){
        String response = null;
        File targetFile = new File(filePath);
        PostMethod postMethod = new PostMethod(url);

        try {
            Part[] parts = new Part[params.size()+1];
            parts[0] = new FilePart(targetFile.getName(), targetFile);
            if(params!=null && params.size()>0){
                int i=1;
                for(String key : params.keySet()){
                    parts[i] = new StringPart(key,params.get(key));
                    i++;
                }
            }

            postMethod.setRequestEntity(new MultipartRequestEntity(parts,postMethod.getParams()));
            HttpClient client = new HttpClient();
            client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
            int status = client.executeMethod(postMethod);
            if(status ==  HttpStatus.SC_OK) {
                response = new String(postMethod.getResponseBodyAsString().getBytes("utf-8"));
            }
            System.out.println(params + "11111111111======"+response);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            postMethod.releaseConnection();
        }

        return response;
    }


    public static String download(String url, Map<String,String> params,String filepath) {
        InputStream is = null;
        FileOutputStream fileout = null;
        org.apache.http.client.HttpClient client = null;
        try {
            client = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-type","application/json; charset=utf-8");
            httpPost.setHeader("Accept", "application/json");
            StringEntity entity = new StringEntity(JSONObject.toJSONString(params),Charset.forName("UTF-8"));
            httpPost.setEntity(entity);
            HttpResponse response = client.execute(httpPost);

            HttpEntity he = response.getEntity();
            is = entity.getContent();
            if (filepath == null){
                filepath = getFilePath(response);
            }

            File file = new File(filepath);
            file.getParentFile().mkdirs();
            fileout = new FileOutputStream(file);
            /**
             * 根据实际运行效果 设置缓冲区大小
             */
            byte[] buffer = new byte[1024];
            int ch = 0;
            while ((ch = is.read(buffer)) != -1) {
                fileout.write(buffer, 0, ch);
            }
            fileout.flush();
            return EntityUtils.toString(he,"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(is!=null)is.close();
                if(fileout!=null)fileout.close();
                client.getConnectionManager().shutdown();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    public static String getFilePath(HttpResponse response) {
        String filepath = null;//root + splash;
        String filename = getFileName(response);

        if (filename != null) {
            filepath += filename;
        } else {
            filepath += getRandomFileName();
        }
        return filepath;
    }


    public static String getFileName(HttpResponse response) {
        Header contentHeader = response.getFirstHeader("Content-Disposition");
        String filename = null;
        if (contentHeader != null) {
            HeaderElement[] values = contentHeader.getElements();
            if (values.length == 1) {
                NameValuePair param = values[0].getParameterByName("filename");
                if (param != null) {
                    try {
                        //filename = new String(param.getValue().toString().getBytes(), "utf-8");
                        //filename=URLDecoder.decode(param.getValue(),"utf-8");
                        filename = param.getValue();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return filename;
    }

    /**
     * 获取随机文件名
     *
     * @return
     */
    public static String getRandomFileName() {
        return String.valueOf(System.currentTimeMillis());
    }


    public static JSONObject fileDownloadQuery(String uuidFlag, PageModel page, DownFileReqModel downFileReqModel) throws IOException {
        String param = "rtype=0603&data=";
        JSONObject data = new JSONObject();
        data.put("cert", downFileReqModel.getCert());
        data.put("token", downFileReqModel.getToken());
        data.put("dqdm", downFileReqModel.getDqdm());
        data.put("rq_q", downFileReqModel.getApplyDateStart());
        data.put("rq_z", downFileReqModel.getApplyDateEnd());
        data.put("fplx", downFileReqModel.getFileInvType());
        data.put("sjlx", downFileReqModel.getFileInvSpec());

        if(page!=null){
            data.put("sEcho",String.valueOf(page.getsEcho()));
            data.put("iDisplayStart",String.valueOf(page.getiDisplayStart()));
            data.put("iDisplayLength",String.valueOf(page.getiDisplayLength()));
        }
        param += data.toString();
        String result = requestNation(downFileReqModel.getDqdm(), param);
        logger.info(uuidFlag + ",taxno is " + downFileReqModel.getCert() + " request 0603 interface, the param is " + param + ", the result is " + StringUtil.getShortLog(result, 300));
        return JSON.parseObject(result);
    }

}
