package org.jeecg.ctop.finance.utils;

import org.jeecg.ctop.finance.policy.utils.Check;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * zian Y
 * 2021/8/3
 **/
public class SettlementUtil {


    public static String getFileNameNoEx(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length()))) {
                return filename.substring(0, dot);
            }
        }
        return filename;
    }

    /**
     * 格式：123456-1
     * 截取 账户 id
     *
     * @param str
     * @return
     */
    public static String subAccountName(String str) {
        str.replaceAll(" ","");
        if (!Check.isNull(str)) {
            if (str.contains("-")) {
                return str.substring(0, str.indexOf("-"));
            }
        }
        return getFileNameNoEx(str);


    }

    /**
     * @Description: 忽略null值/只拷贝非null属性
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }


    /**
     * 获取网络图片转成字节流
     *
     * @param strUrl 完整图片地址
     * @return 图片资源数组
     */
    public static byte[] getByteImgByUrl(String strUrl) {
        try {
            URL url = new URL(strUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(2 * 1000);
            // 通过输入流获取图片数据
            InputStream inStream = conn.getInputStream();
            // 得到图片的二进制数据
            byte[] btImg = readInputStream(inStream);
            return btImg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 从输入流中获取字节流数据
     *
     * @param inStream 输入流
     * @return 图片流
     */
    private static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        // 设置每次读取缓存区大小
        byte[] buffer = new byte[1024 * 10];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        inStream.close();
        return outStream.toByteArray();
    }

    /**
     * 获取日期的年月
     *
     * @param strDate
     * @return
     */
    public static int getYearMonth(String strDate) throws Exception {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse(strDate);

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);//设置时间
        int year = cal.get(Calendar.YEAR);//获取年份
        int month = cal.get(Calendar.MONTH);//获取月份
        return year * 100 + month;//返回年份乘以100加上月份的值，因为月份最多2位数，所以年份乘以100可以获取一个唯一的年月数值
    }


    /**
     * 判断当前时间是否在[startTime, endTime]区间
     * 年-月   2021-08
     *
     * @param nowStrTime   当前时间
     * @param startStrTime 开始时间
     * @param endStrTime   结束时间
     * @return
     * @author zian Y
     */
    public static boolean isEffectiveDate(String nowStrTime, String startStrTime, String endStrTime) throws Exception {
        // SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        Date nowTime = simpleDateFormat.parse(nowStrTime);
        Date startTime = simpleDateFormat.parse(startStrTime);
        Date endTime = simpleDateFormat.parse(endStrTime);

        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }


    public static long DateCompare(String s1, String s2) {
        try {

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date d1 = simpleDateFormat.parse(s1);
            Date d2 = simpleDateFormat.parse(s2);
            // LocalDateTime d1 = LocalDateTime.parse(s1, DateTimeFormatter.ISO_LOCAL_DATE);
            //LocalDateTime d2 = LocalDateTime.parse(s2, DateTimeFormatter.ISO_LOCAL_DATE);
            //排序规则
            return ((d1.getTime()) - (d2.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static List<String> sortlistTest(List<String> list) {
        //去重
        List<String> newlist = new ArrayList<String>();
        for (int i = 0; i < list.size(); i++) {
            if (!newlist.contains(list.get(i))) {
                newlist.add(list.get(i));
            }
        }
        String tmp;
        for (int i = 1; i < newlist.size(); i++) {
            tmp = newlist.get(i);
            int j = i - 1;
            for (; j >= 0 && (DateCompare(tmp, newlist.get(j)) < 0); j--) {
                newlist.set(j + 1, newlist.get(j));
            }
            newlist.set(j + 1, tmp);
        }
        return newlist;
    }


    /**
     * 获取 两个日期之间的所有 日期
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getAllDatesOfTwoTimes(String startDate, String endDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dateList = new ArrayList<String>();
        try {
            Date dateOne = sdf.parse(startDate);
            Date dateTwo = sdf.parse(endDate);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateOne);

            dateList.add(startDate);
            while (calendar.getTime().before(dateTwo)) { //倒序时间,顺序after改before其他相应的改动。
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                dateList.add(sdf.format(calendar.getTime()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dateList;
    }


    public static List<Map<String, String>> getTime( List<String> list) {
        //初始化list,且该list中的日期是升序的。
        //List<String> list = Arrays.asList("2020-11-19","2020-11-20","2020-11-21","2021-07-20");
       /* List<String> list = Arrays.asList("2021-07-02", "2021-07-03", "2021-07-04", "2021-07-06",
                "2021-07-07", "2021-07-08", "2021-07-09", "2021-07-11", "2021-07-12",
                "2021-07-13", "2021-07-14", "2021-07-16", "2021-07-17", "2021-07-18",
                "2021-07-19", "2021-07-20", "2021-07-21", "2021-07-22", "2021-07-23",
                "2021-07-24", "2021-07-25", "2021-07-26", "2021-07-27", "2021-07-28",
                "2021-07-29", "2021-07-30");
        */
        List<Map<String, String>> arrayList = new ArrayList<>();
        int num = 0;
        for (int i = 0; i < list.size(); i = num) {
            String start = list.get(i);
            String end = "";
            if (i == list.size() - 1) {
                end = start;
            }
            int n = 0;
            for (int j = i + 1; j < list.size(); j++) {
                //判断当前日期的后一天与list中该元素的下一个元素是否相等
                if (getSpecifiedDayAfter(list.get(j - 1)).equals(list.get(j))) {
                    end = list.get(j);
                    n++;
                    num++;
                    continue;
                } else {
                    //list中该元素不是连续的
                    if (n == 0) {
                        end = list.get(j - 1);
                    }
                    break;
                }
            }
            num = num + 1;
            HashMap<String, String> map = new HashMap<>();
            map.put("startDate", start);
            map.put("endDate", end);
            arrayList.add(map);
        }

        return arrayList;
}

    /**
     * 获取当前日期的后一天
     * @param specifiedDay
     * @return
     */
    public static String getSpecifiedDayAfter(String specifiedDay) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day + 1);
        String dayAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        return dayAfter;
    }


    /**
     * 获取当前日期 年-月 的 第一天和最后一天
     */
    public static Map<String,String> getFirstAndLastDayOfMonth(String yearMonth){
        Map<String,String> map = new HashMap<>();
        String[] year = yearMonth.split("-");
        Integer y = Integer.valueOf(year[0]);
        Integer m = Integer.valueOf(year[1]);
        String firstDay = getFirstDayOfMonth(y,m);
        String lastDay = getLastDayOfMonth(y,m);
        map.put("startTime",firstDay);
        map.put("endTime",lastDay);
        return map;
    }





    /**
     * 获取指定年月的第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH,firstDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }


    /**
     * 获取指定年月的最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }


    public static void main(String[] args) {
        System.out.println(getFirstAndLastDayOfMonth("2021-02").get("startTime"));;
        System.out.println(getFirstAndLastDayOfMonth("2021-02").get("endTime"));;
    }


}