package cn.wisenergy.common.utils;

import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 工具类
 *
 * @author lut
 */
@Slf4j
public class BaseUtil {

    /**
     * 下载文件header头
     */
    private static final String FileHeader = "attachment;filename=\"%1$s\";filename*=utf-8''%1$s";

    /**
     * 无参数url转换成有参url
     *
     * @param url
     * @param params
     * @return
     */
    public static String getParamsUrl(String url, Map<String, Object> params) {
        if (!params.isEmpty()) {
            return Joiner.on("?").join(url, Joiner.on("&").join(params.keySet().stream()
                    .map(o -> String.format("%1$s={%1$s}", o)).collect(Collectors.toList())));
        }
        return url;
    }

    /**
     * 设置下载文件名称（解决编码问题）
     *
     * @param response
     * @param fileName
     */
    public static void setDownloadFileHeader(HttpServletResponse response, String fileName) {
        // IE8兼容
        response.setHeader("Cache-Control", "must-revalidate");
        response.setHeader("Cache-Control", "post-check=0");
        response.setHeader("Cache-Control", "pre-check=0");
        // 文件名称
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition", String.format(FileHeader, getEncodeFileName(fileName)));
    }

    /**
     * 获取编码文件名称
     *
     * @param fileName
     * @return
     */
    private static String getEncodeFileName(String fileName) {
        try {
            return URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20");
        } catch (Exception e) {
            log.error("文件名转码失败：{}", e);
        }
        return fileName;
    }


    /**
     * 按日历日期增加
     */
    public static Date addMonth(Date d1, int month) {
        // 创建实例
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d1);
        //日期
        calendar.add(Calendar.MONTH, month);
        // 一个月后的日期（Date类型）
        Date date = calendar.getTime();
        return date;
    }


    /**
     * 按日历日期增加
     */
    public static Date addDay(Date d1, int day) {
        // 创建实例
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d1);
        // 一个月后的日期
        calendar.add(Calendar.DAY_OF_YEAR, day);
        // 一个月后的日期（Date类型）
        Date date = calendar.getTime();
        return date;
    }

    /**
     * 日期添加
     *
     * @param date
     * @param day
     * @return
     */
    public static Date addDate(Date date, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, day);
        date = cal.getTime();
        return date;
    }

    /**
     * 说明：日期增加一个月，获得一个月后的日期
     *
     * @param str1
     * @return Date
     */
    public static Date add1Month(String str1) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            return addMonth(sdf.parse(str1), 1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 说明：日期增加三个月，获得三个月后的日期
     *
     * @param str1
     * @return Date
     */
    public static Date add3Month(String str1) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            return addMonth(sdf.parse(str1), 3);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 说明：日期增加十二个月，获得一年后的日期
     */
    public static Date add1Year(String str1) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            return addMonth(sdf.parse(str1), 12);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过出生日期获取年龄
     *
     * @param birth
     * @param deadDate
     * @return
     */
    public static int getAgeByBirth(Date birth, Date deadDate) {
        // 判定出生日期是否存在
        if (birth != null) {
            return birth.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
                    .until(deadDate != null ? deadDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() : LocalDate.now())
                    .getYears();
        }
        return 0;
    }
}
