package com.zzsn.knowbase.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TimeUtil {
    static SimpleDateFormat format;

    private static Pattern patDate0 = Pattern.compile("\\d+-\\d{1,2}-\\d+");
    private static Pattern patDate1 = Pattern.compile("\\d+[-\\s/年月日]\\d{1,2}-\\d+", Pattern.CASE_INSENSITIVE);
    private static Pattern patDate2 = Pattern.compile("\\d+\\s+[A-Z][a-z]+\\s+\\d+");
    private static Pattern patDate3 = Pattern.compile("[A-Z][a-z.]+\\s+\\d{1,2},\\s+\\d+");
    private static Pattern patDate4 = Pattern.compile("\\d+年\\d+月\\d+日");
    private static Pattern patDate4_1 = Pattern.compile("\\d+年\\d+月\\d+号");
    private static Pattern patDate5 = Pattern.compile("\\d+/\\d{1,2}/\\d+");
    private static Pattern patDate6 = Pattern.compile("\\d+\\.\\d+\\.\\d+");
    private static Date thresholdDate = null;
    private static SimpleDateFormat formatter0 = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat formatter0_1 = new SimpleDateFormat("yy-MM-dd");
    private static SimpleDateFormat formatter2 = new SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH);
    private static SimpleDateFormat formatter3_1 = new SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH);
    private static SimpleDateFormat formatter3_2 = new SimpleDateFormat("MMM. dd, yyyy", Locale.ENGLISH);
    private static SimpleDateFormat formatter4 = new SimpleDateFormat("yyyy年MM月dd");
    private static SimpleDateFormat formatter5_1 = new SimpleDateFormat("yyyy/MM/dd");
    private static SimpleDateFormat formatter5_2 = new SimpleDateFormat("dd/MM/yyyy");
    private static SimpleDateFormat formatter5_4 = new SimpleDateFormat("yy/MM/dd");
    private static SimpleDateFormat formatter5_3 = new SimpleDateFormat("dd/MM/yy");
    private static SimpleDateFormat formatter6 = new SimpleDateFormat("yyyy.MM.dd");
    private static SimpleDateFormat formatter6_1 = new SimpleDateFormat("dd.MM.yyyy");


    public static String dateToString(Date date) {
        format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return TimeUtil.format.format(date);
    }

    public static String getPublishDate(String raw) {
        if (raw == null) {
            return null;
        }
        Date date = transDate(raw);
        if (date != null) {
            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai"));
            c.setTime(date);
            Pattern p = Pattern.compile("(\\d{1,2})[:|：](\\d{1,2})([:|：]\\d{1,2}){0,1}");
            Matcher m = p.matcher(raw);
            while (m.find()) {
                String hour = m.group(1);
                if (hour != null) {
                    c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour));
                }
                String minute = m.group(2);
                if (minute != null) {
                    c.set(Calendar.MINUTE, Integer.parseInt(minute));
                }
                String second = m.group(3);
                if (second != null) {
                    c.set(Calendar.SECOND, Integer.parseInt(second.replaceAll("[:：]", "")));
                }
            }
            return format(c.getTime(), "yyyy-MM-dd");
        } else {
            return null;
        }
    }

    private static String format(Date d, String format) {
        if (d == null)
            return "";
        SimpleDateFormat myFormatter = new SimpleDateFormat(format);
        return myFormatter.format(d);
    }

    private static Date transDate(String content) {
        try {
            Matcher dateMatcher = null;
            Date date = null;
            if (((dateMatcher = patDate0.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 0)) != null))
                    || ((dateMatcher = patDate1.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 1)) != null))
                    || ((dateMatcher = patDate2.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 2)) != null))
                    || ((dateMatcher = patDate3.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 3)) != null))
                    || ((dateMatcher = patDate4.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 4)) != null))
                    || ((dateMatcher = patDate4_1.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 4)) != null))
                    || ((dateMatcher = patDate5.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 5)) != null))
                    || ((dateMatcher = patDate6.matcher(content)).find() && ((date = transDate(dateMatcher.group(), 6)) != null))
                    ) {
                return date;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static Date transDate(String source, int type) {
        try {

            if (thresholdDate == null) {
                thresholdDate = formatter0.parse("1970-01-01");
            }
            Date date = null;
            switch (type) {
                case 0:
                    date = formatter0.parse(source);

                    if (date.before(thresholdDate)) {
                        date = formatter0_1.parse(source);
                        if (date.before(thresholdDate)) {
                            return null;
                        }
                    }

                    break;
                case 1:
                    //date = formatter1.parse(source);
                    break;
                case 2:
                    date = formatter2.parse(source);
                    break;
                case 3:
                    try {
                        date = formatter3_1.parse(source);
                    } catch (Exception e) {
                        date = null;
                    }
                    if (date == null) {
                        date = formatter3_2.parse(source);
                    }
                    break;
                case 4:
                    date = formatter4.parse(source);
                    break;
                case 5:
                    try {
                        date = formatter5_1.parse(source);
                    } catch (Exception e) {
                        date = null;
                    }
                    if ((date == null) || (date.before(thresholdDate))) {
                        date = formatter5_2.parse(source);
                    }
                    if ((date == null) || (date.before(thresholdDate))) {
                        date = formatter5_3.parse(source);
                    }
                    if ((date == null) || (date.before(thresholdDate))) {
                        date = formatter5_4.parse(source);
                    }
                    break;
                case 6:
                    try {
                        date = formatter6.parse(source);
                    } catch (ParseException e) {
                        date = null;
                    }
                    if ((date == null) || (date.before(thresholdDate))) {
                        date = formatter6_1.parse(source);
                    }
                    break;
            }

            if ((date != null) && (date.before(thresholdDate))) {
                return null;
            }

            return date;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取前7天的时间
     * @param date
     * @return
     */
    public static String beforeWeek(Date date){
        format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        //设置为指定日期
        c.setTime(date);
        c.add(Calendar.DATE,-7);
        Date time = c.getTime();
        return format.format(time);
    }

    /**
     * 获取前30天的时间
     * @param date
     * @return
     */
    public static String beforeMonth(Date date){
        format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        //设置为指定日期
        c.setTime(date);
        c.add(Calendar.DATE,-30);
        return format.format(c.getTime()) + " 00:00:00";
    }

    public static String getDateString(Date date) {
        format = new SimpleDateFormat("yyyy-MM-dd");
        return TimeUtil.format.format(date);
    }

    public static Date StringToDate(String dateString) throws ParseException {
        format = new SimpleDateFormat("yyyy-MM-dd");
        return format.parse(dateString);
    }

    public static String dateConvert(String dateString) throws ParseException {
        format = new SimpleDateFormat("MM/dd/yyyy");
        Date parse = format.parse(dateString);
        return getDateString(parse);
    }

    /**
     * 获取指定某一天的开始时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public static Long getDailyStartTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取指定某一天的结束时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @param timeZone  如 GMT+8:00
     * @return
     */
    public static Long getDailyEndTime(Long timeStamp, String timeZone) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(timeStamp);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTimeInMillis();
    }

    /**
     * 判断两个时间是否为同一天
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDay(final Date date1, final Date date2) {
        if(date1 == null || date2 == null) {
            return false;
        }
        final Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        final Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return isSame(cal1, cal2);
    }

    private static boolean isSame(final Calendar cal1, final Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            return false;
        }
        return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
    }
}
