package com.yutou.nas.utils;

import com.alibaba.fastjson.JSONArray;
import com.yutou.nas.Controllers.UpdateIp;
import com.yutou.nas.interfaces.DownloadInterface;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Random;

public class Tools {
    /**
     * 设置Cookie
     *
     * @param response
     * @param key
     * @param value
     * @param time
     */
    public static void setCookie(HttpServletResponse response, String key, String value, int time) {
        Cookie cookie = new Cookie(key, value);
        if (time != -1) {
            cookie.setMaxAge(time);
        }
        cookie.setPath("/");
        response.addCookie(cookie);

    }

    /**
     * 获取Cookie
     *
     * @param request
     * @param key
     * @return
     */
    public static Cookie getCookie(HttpServletRequest request, String key) {
        Cookie[] cookies = request.getCookies();
        try {
            for (Cookie cookie : cookies) {
                if (key != null && cookie.getName().equals(key)) {
                    return cookie;
                }
            }
        } catch (Exception ignored) {

        }

        return null;
    }

    /**
     * 删除Cookie
     *
     * @param request
     * @param response
     * @param key
     * @return
     */
    public static String deleteCookie(HttpServletRequest request, HttpServletResponse response, String key) {
        for (Cookie cookie : request.getCookies()) {
            if (cookie.getName().equals(key)) {
                com.yutou.nas.utils.Log.i("删除key=" + key);
                cookie.setMaxAge(0);
                cookie.setPath("/");
                cookie.setValue(null);
                response.addCookie(cookie);
            }
        }
        return "ok";
    }

    public static void sendServer(String title, String msg) {
        try {
            com.yutou.nas.utils.Log.i("title=" + title + " msg=" + msg);
            HttpTools.post("https://sctapi.ftqq.com/SCT2619Tpqu93OYtQCrK4LOZYEfr2irm.send",
                    ("title="+URLEncoder.encode(title, "UTF-8") + "&desp=" + URLEncoder.encode(msg, "UTF-8")).getBytes(StandardCharsets.UTF_8),
                    null);
            if (ConfigTools.load(ConfigTools.CONFIG, "model").equals("nas")) {
                String img = null;
                msg = msg.replace("<br/>", "\n");
                if (msg.contains("![logo]")) {
                    try {
                        img = msg.split("!\\[logo\\]\\(")[1].split("\\)")[0];
                        msg = msg.replace("![logo](" + img + ")", "");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (img == null) {
                    QQBotManager.getInstance().sendMessage(title + "\n" + msg);
                } else {
                    String finalMsg = msg;
                    String finalImg = img;
                    if (QQBotManager.getInstance().isLogin()) {
                        download(img, new DownloadInterface() {
                            @Override
                            public void onDownload(File file) {
                                super.onDownload(file);
                                QQBotManager.getInstance().sendMessage(file, title + "\n" + finalMsg);
                            }

                            @Override
                            public void onError(Exception e) {
                                super.onError(e);
                                QQBotManager.getInstance().sendMessage(title + "\n" + finalMsg + "\n" + finalImg);
                            }
                        });
                    }
                }
            } else if (!StringUtils.isEmpty(UpdateIp.nas_ip)) {
                String img = null;
                msg = msg.replace("<br/>", "\n");
                if (msg.contains("![logo]")) {
                    try {
                        img = msg.split("!\\[logo\\]\\(")[1].split("\\)")[0];
                        msg = msg.replace("![logo](" + img + ")", "");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                String url;
                if (img == null) {
                    url = "http://" + UpdateIp.nas_ip + ":8000/qq/bot/send.do?msg=" + URLEncoder.encode((title + "\n" + msg), "UTF-8") + "&token=zIrsh9TUZP2lfRW753PannG49E7VJvor";
                } else {
                    url = "http://" + UpdateIp.nas_ip + ":8000/qq/bot/send.do?msg=" + URLEncoder.encode((title + "\n" + msg), "UTF-8")
                            + "&imgUrl=" + img
                            + "&token=zIrsh9TUZP2lfRW753PannG49E7VJvor";
                }
                com.yutou.nas.utils.Log.i(url);
                HttpTools.get(url);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取项目路径
     *
     * @param request
     * @return
     */
    public static String getPath(HttpServletRequest request) {
        return request.getServletContext().getRealPath("/") + "/";
    }

    /**
     * 获取客户端IP
     *
     * @param request
     * @return
     */
    public static String getRemoteAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * N以内的不重复随机数
     *
     * @param min 最小值
     * @param max 最大值
     * @param n
     * @return
     */
    public static int[] randomCommon(int min, int max, int n) {
        int len = max - min + 1;
        if (max < min || n > len) {
            return new int[0];
        }
        // 初始化给定范围的待选数组
        int[] source = new int[len];
        for (int i = min; i < min + len; i++) {
            source[i - min] = i;
        }
        int[] result = new int[n];
        Random rd = new Random();
        int index = 0;
        for (int i = 0; i < result.length; i++) {
            // 待选数组0到(len-2)随机一个下标
            index = Math.abs(rd.nextInt() % len--);
            // 将随机到的数放入结果集
            result[i] = source[index];
            // 将待选数组中被随机到的数，用待选数组(len-1)下标对应的数替换
            source[index] = source[len];
        }
        return result;
    }

    public static int checkWebLogin(HttpServletRequest request) {
        JSONArray array = new JSONArray();
        if (RedisTools.get("bean") != null) {
            array = JSONArray.parseArray(RedisTools.get("bean"));
        }
        if (array.contains(Tools.getRemoteAddress(request))) {
            com.yutou.nas.utils.Log.i("IP已被封禁");
            return -100;
        }
        Cookie cookie = Tools.getCookie(request, "user");
        if (cookie == null) {
            return -1;
        }
        if (RedisTools.get(cookie.getValue()).equals("ok")) {
            return 1;
        }
        return 0;
    }

    /**
     * 保存上传的文件
     *
     * @param path 路径
     * @param file 文件
     * @return
     * @throws Exception
     */
    public static String createFile(String path, MultipartFile file, String newFileName) throws Exception {
        String savePath = new File("").getAbsolutePath() + File.separator + "html" + File.separator + path;
        File servicePath = new File(savePath);
        if (!servicePath.exists()) {
            servicePath.mkdirs();
        }
        String fileName = file.getOriginalFilename();
        if (newFileName != null) {
            fileName = newFileName;
        }
        File saveFile = new File(savePath + "/" + fileName);
        if (saveFile.exists()) {
            if (!saveFile.delete()) {
                saveFile = new File(savePath + "/" + fileName.replace(".", "_" + new Date().getTime() + "."));
            }
        }
        file.transferTo(saveFile);
        fileName = URLEncoder.encode(fileName, "UTF-8");
        com.yutou.nas.utils.Log.i("上传文件保存路径：" + saveFile.getAbsolutePath());
        return path + fileName;
    }

    public static void download(String url, DownloadInterface downloadInterface) {
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36");
            connection.disconnect();
            new File("tmp").mkdirs();
            File file = new File("tmp" + File.separator + url.trim().split("/")[url.trim().split("/").length - 1]);
            if (file.exists()) {
                file.delete();
            }
            FileOutputStream outputStream = new FileOutputStream(file);
            InputStream inputStream = connection.getInputStream();
            byte[] bytes = new byte[4096];
            int len;
            while ((len = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
                outputStream.flush();
            }
            outputStream.close();
            inputStream.close();
            downloadInterface.onDownload(file);
        } catch (IOException e) {
            e.printStackTrace();
            downloadInterface.onError(e);
        }
    }

    /**
     * 构造给前端的文件
     *
     * @param file 文件路径
     * @return 前端获取的文件
     */
    public static ResponseEntity<FileSystemResource> getFile(File file) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        try {
            headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        }
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
    }

    public static String getFileMD5(File file) {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream in = null;
        byte buffer[] = new byte[1024];
        int len;
        try {
            digest = MessageDigest.getInstance("MD5");
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return bytesToHexString(digest.digest());
    }

    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte aSrc : src) {
            int v = aSrc & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static String base64ToString(String base) {
        base = base.replace(" ", "+");
        try {
            base = new String(Base64.getDecoder().decode(base.replace("\r\n", "").getBytes()));
        } catch (Exception e) {
            try {
                base = URLDecoder.decode(base, "UTF-8");
                base = base.replace(" ", "+");
                base = new String(Base64.getDecoder().decode(base.replace("\r\n", "").getBytes()));
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        return base;
    }

    /**
     * 异常输出
     *
     * @param e 异常
     * @return
     */
    public static String getExceptionString(Exception e) {
        StringWriter writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        e.printStackTrace(printWriter);
        printWriter.close();
        return writer.toString();
    }

    public static String getToDayTime() {
        return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    }
}
