package com.zfire.jiasm.syncdata.utils;



import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

@Slf4j
public class CommonUtils {

    private static final int  BUFFER_SIZE = 2 * 1024;



    public static List<String> initList(List<String> list,int size){
        int listSize = list.size();
        if(listSize < size){
            for(int i = listSize;i < size;i++){
                list.add("");
            }
        }
        return list;
    }

    public static List<Object> initList2(List<Object> list,int size){
        int listSize = list.size();
        if(listSize < size){
            for(int i = listSize;i < size;i++){
                list.add("");
            }
        }
        return list;
    }



    public static String getFormatUrl(String url) {
        if (url.startsWith("http:")) {
            url = StringUtils.replace(url, "http", "https");
        }

        return url;
    }

    public static String getUserCode(){
        HttpServletRequest request = ApplicationContextUtils.getHttpServletRequest();
        if (StringUtils.isEmpty(request)){
            return null;
        }
        return getUserCode(request);
    }

    public static String getUserCode(HttpServletRequest request){
        String token = getToken(request);
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        if(StringUtils.isEmpty(token)){
            return null;
        }
        try {
            String userId = JwtUtils.validateJWT(token).getClaims().getSubject();
            return userId;
        }catch(Exception e){
            return null;
        }
    }

    public static String getUserId(){
        HttpServletRequest request = ApplicationContextUtils.getHttpServletRequest();
        if (StringUtils.isEmpty(request)) {
            return null;
        }
        return getUserId(request);
    }

    public static String getUserId(HttpServletRequest request){
        String token = getToken(request);
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        if(StringUtils.isEmpty(token)){
            return null;
        }
        try {
            String userId = JwtUtils.validateJWT(token).getClaims().getId();
            return userId;
        }catch(Exception e){
            return null;
        }
    }

    public static String getUsername(){
        HttpServletRequest request = ApplicationContextUtils.getHttpServletRequest();
        if (request == null) {
            return null;
        }
        return getUsername(request);
    }

    public static String getUsername(HttpServletRequest request){
        try {
            String token = getToken(request);
            if (StringUtils.isEmpty(token)) {
                return null;
            }
            return JwtUtils.validateJWT(token).getClaims().getAudience();
        }catch(Exception e){
            return "";
        }
    }

    /**
     * 获取token
     */
    public static String getToken(HttpServletRequest request){
        String token = request.getHeader("x-token");
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        return token;
    }



    public static void downloadFile(String fileName, HttpServletResponse response) throws IOException {
        InputStream inputStream  = CommonUtils.class.getResourceAsStream("/template/" + fileName);
        response.setContentType("content-type:octet-stream");
        response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream outputStream = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, len);
        }
        inputStream.close();
        outputStream.close();
    }

    public static void downloadFile(InputStream inputStream,String fileName, HttpServletResponse response) throws IOException {
        response.setContentType("content-type:octet-stream");
        response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream outputStream = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, len);
        }
        inputStream.close();
        outputStream.close();
    }



    /**
     * 检查下标对应的值不能为空
     * @param row
     * @param index
     * @return
     */
    public static Integer checkRowEmpty(List<String> row, int[] index){
        for(int i : index){
            if(StringUtils.isEmpty(row.get(i))){
                return i;
            }
        }
        return null;
    }



    /**
     * 压缩成ZIP
     *
     * @param srcFiles 需要压缩的文件列表
     * @param out      压缩文件输出流
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {
        long start = System.currentTimeMillis();
        java.util.zip.ZipOutputStream zos = null;
        try {
            zos = new java.util.zip.ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[BUFFER_SIZE];
                zos.putNextEntry(new java.util.zip.ZipEntry(srcFile.getName()));
                int len;
                if (srcFile.exists()) {
                    FileInputStream in = new FileInputStream(srcFile);
                    while ((len = in.read(buf)) != -1) {
                        zos.write(buf, 0, len);
                    }
                    zos.closeEntry();
                    in.close();
                }
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) + " ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void zipFile(List<Map> paths, String zippath) throws Exception {
        List<File> fileList = new ArrayList<>();
        for (Map<String, String> photoUrl : paths) {
            File dest = new File(photoUrl.get("path"));
            fileList.add(dest);
        }
        //将filelist进行压缩
        FileOutputStream fos2 = new FileOutputStream(new File(zippath));
        toZip(fileList, fos2);
        //压缩后删除源文件
        for (int i = 0; i < fileList.size(); i++) {
            File myFilePath = new File(fileList.get(i).getPath());
            myFilePath.delete();
        }
    }

    /***
     * 将文件下载到本地
     */
    public static String download(String fileKey, String filename, String path) throws Exception {
        URL url = new URL(fileKey);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();
        return wirteFile(conn, filename, path);
    }

    static String wirteFile(HttpURLConnection conn, String filename, String path) throws IOException {
        String filePath = path + filename;
        RandomAccessFile file = new RandomAccessFile(filePath, "rw");
        InputStream stream = conn.getInputStream();
        byte buffer[] = new byte[1024];
        while (true) {
            int len = stream.read(buffer);
            if (len == -1) {
                break;
            }
            file.write(buffer, 0, len);
        }
        System.out.println("文件名称:" + filename + "    ,文件大小:" + file.length() / 1024 + "MB");
        if (file != null) {
            file.close();
        }
        if (stream != null) {
            stream.close();
        }
        return filePath;
    }

    public static String fmtAmount(Object value) {
        if(null == value){
            return "";
        }
        if(value.toString().equals("0.00")){
            return  "0.00";
        }
        DecimalFormat df = new DecimalFormat("#,###.00");
        return df.format(new BigDecimal(value.toString()));
    }

    // 去重predict方法
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor){
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }


    /*
     * 加密
     * id: ID
     * pas: 明文
     * @return: 密文
     **/
    public static String addPass( String id, String pas)
    {
        long k = 123456789;

        for( int i=0; i < id.length(); i++){
            long  a = ( (int)id.charAt(i) ) % 13 + 1;
            k = ( k * a ) % 9999999 + 1;
        }

        k = k % 98989898 + 99;
        for(int i=0; i<  pas.length(); i++){
            long  a = ( (int)pas.charAt(i) ) % 17 + 1;
            k = ( k % 9876543 + 1 ) * a;
        }

        DecimalFormat df = new DecimalFormat( "00000000" );
        return df.format( k % 100000000 );
    }

}
