package com.microservices.dms.utils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

public class DateUtil {

    public static Date[] getDays(long start, long end) {
        LocalDate today = LocalDate.now();
        LocalDate startOfWeek = today.minusDays(end);
        LocalDate endOfWeek = today.minusDays(start);

        LocalDateTime startDateTime = startOfWeek.atStartOfDay();
        LocalDateTime endDateTime = endOfWeek.atTime(23, 59, 59);

        return new Date[]{
                Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()),
                Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant()),
        };
    }


    public static Date[] getCurrentYear() {
        Year year = Year.now();

        LocalDate startDate = year.atDay(1);
        LocalDate endDate = year.atDay(year.length());

        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(23, 59, 59);

        return new Date[]{
                Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()),
                Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant())
        };
    }

    public static Date[] getLast12Months() {
        LocalDate endDate = LocalDate.now();

        LocalDate startDate = endDate.minusMonths(11);

        LocalDateTime startDateTime = LocalDateTime.of(startDate.getYear(),startDate.getMonth(),1,0,0,0);
        LocalDateTime endDateTime = endDate.atTime(23, 59, 59);

        return new Date[]{
                Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()),
                Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant())
        };
    }

    public static Date[] getCurrentYearEndOf(LocalDate endDate) {
        Year year = Year.now();

        LocalDate startOfWeek = year.atDay(1);

        LocalDateTime startDateTime = startOfWeek.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(23, 59, 59);

        return new Date[]{
                Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()),
                Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant())
        };
    }

    public static List<String> getDateStrMMDD(Date start, Date end) {
        LocalDate s = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalDate();
        LocalDate e = end.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalDate();
        String pattern = "MM-dd";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

        return LongStream.range(0, s.until(e).getDays() + 1)
                .mapToObj(s::plusDays)
                .map(formatter::format)
                .collect(Collectors.toList());
    }


    public static List<String> getDateStrYYYYMM(Date start, Date end) {
        LocalDate s = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalDate();
        LocalDate e = end.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalDate();
        String pattern = "yyyy-MM";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

        return LongStream.range(0, s.until(e).getMonths() + 1)
                .mapToObj(s::plusMonths)
                .map(formatter::format)
                .collect(Collectors.toList());
    }

    public static List<String> getDateStrYYYYMMDD(Date start, Date end) {
        LocalDate s = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalDate();
        LocalDate e = end.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalDate();
        String pattern = "yyyy-MM-dd";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

        return LongStream.range(0, s.until(e).getDays() + 1)
                .mapToObj(s::plusDays)
                .map(formatter::format)
                .collect(Collectors.toList());
    }

    public static Date plusHours(Date date, long plusHours){
        if (date == null) {return null;}
        LocalDateTime s = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        return Date.from(s.plusHours(plusHours).atZone(ZoneId.systemDefault()).toInstant());
    }
}
