package com.zfire.mall.manager.utils;


import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zfire.mall.manager.bean.wallet.CustomerWalletBean;
import com.zfire.mall.manager.enums.PickStatusEnum;
import com.zfire.mall.manager.enums.WalletTypeEnum;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.plus.entity.WalletRebateSaleType;
import org.springframework.beans.BeanUtils;
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.text.SimpleDateFormat;
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;
import java.util.stream.Collectors;

public class CommonUtils {

    private static final int  BUFFER_SIZE = 2 * 1024;




    /**
     * 根据销售类型获取返利比例
     */
    public static BigDecimal getRebateRate(CustomerWalletBean rebateCustomerWallet, String saleTypeId){
        if(rebateCustomerWallet != null) {
            List<WalletRebateSaleType> walletRebateSaleTypes = rebateCustomerWallet.getWalletRaleTypes().stream()
                    .filter(v -> v.getSaleTypeId().equals(saleTypeId)).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(walletRebateSaleTypes)){
                throw new RemoteServiceException("返利钱包不符合销售类型");
            }
            return walletRebateSaleTypes.get(0).getRebateRate();
        }
        return BigDecimal.valueOf(0);
    }

    /**
     *  根据销售类型组装 返利比例
     */
    public static List<CustomerWalletBean>  findRebateRate(List<CustomerWalletBean> customerWalletBeans,String saleTypeId){
        if(CollectionUtils.isEmpty(customerWalletBeans)){
            return new ArrayList<>();
        }
        List<CustomerWalletBean> rebateWallets = customerWalletBeans.stream()
                .filter(v -> v.getType().equals(WalletTypeEnum.REBATE.getKey()) && v.getSaleTypeIds().contains(saleTypeId))
                .collect(Collectors.toList());

        for(CustomerWalletBean wallet : rebateWallets){
            wallet.setRebateRate(getRebateRate(wallet,saleTypeId));
        }

        //深拷贝
        List<CustomerWalletBean> newList = rebateWallets.stream().map(e -> {
            CustomerWalletBean newBean = new CustomerWalletBean();
            BeanUtils.copyProperties(e, newBean);
            return newBean;
        }).collect(Collectors.toList());

        return newList;
    }


    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 getStatusNameOfStudentExam(int status){
        if(status == 1){
            return "未完成";
        }else if(status == 2){
            return "已完成";
        }else if(status == 0){
            return "作废";
        }
        return "";
    }

    //(1.未考试 2.已及格,3.未及格)
    public static String getExamStatusNameOfStudentExam(int examStatus){
        if(examStatus == 1){
            return "未考试";
        }else if(examStatus == 2){
            return "已及格";
        }else{
            return "未及格";
        }
    }

    public static String getSourceName(int source){
        if(source == 1){
            return "后台新增";
        }else{
            return "线上报名";
        }
    }

    public static Boolean checkNotEmpty(Object... str){
        for(Object s : str){
            if(s instanceof String) {
                String value = (String)s;
                if (StringUtils.isEmpty(value)) {
                    return false;
                }
            }else if(s == null) {
                return false;
            }
        }
        return true;
    }

    public static Boolean checkDate(String dateStr,String dateFormat){
        if(StringUtils.isEmpty(dateStr)){
            return true;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        try{
            sdf.parse(dateStr);
        }catch(Exception e){
            return false;
        }
        return true;
    }

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

        return url;
    }

    public static String getUserId(){
        HttpServletRequest request = ApplicationContextUtils.getHttpServletRequest();
        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 getNickName(){
        HttpServletRequest request = ApplicationContextUtils.getHttpServletRequest();
        if (request == null)
            return null;
        return getNickName(request);
    }

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


    public static String getNickName(HttpServletRequest request){
        try{
            String token = getToken(request);
            if(StringUtils.isEmpty(token))
                return null;
            return JwtUtils.validateJWT(token).getClaims().getSubject();
        }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;
    }

    /**
     * 获取性别code
     * @param gender
     * @return
     */
    public static String getGenderCode(String gender){
        if(org.apache.commons.lang3.StringUtils.equals(gender,"男")){
            return "1";
        }else if(org.apache.commons.lang3.StringUtils.equals(gender,"女")){
            return "2";
        }
        //未知
        return "0";
    }


    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;
    }


    public static String getPickStatusMsg(Integer code) {
        PickStatusEnum[] values = PickStatusEnum.values();
        for (int i = 0; i < values.length; i++) {
            if (code.equals(values[i].getCode())) {
                return values[i].getMsg();
            }
        }
        return "";
    }

    /**
     * 压缩成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;
    }

}
