package com.prime.sony.ecommerce.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class DateHelper {

	private static final Logger log = LoggerFactory.getLogger(DateHelper.class);
	
	static final DateFormat dateFormat;
    static DateFormat customDateFormat;
    static SimpleDateFormat cstTZFormat;
    static Calendar calendar;
    static DateFormat simpleDateFormat;
    
    static TimeZone gmtTZ1 = TimeZone.getTimeZone("GMT");
    static TimeZone cstTZ2 = TimeZone.getTimeZone("America/Chicago");
     
    static {
        dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        cstTZFormat = new SimpleDateFormat("YYYY-MM-DD hh:mm:ss");
        cstTZFormat.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
        simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy");
        customDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        calendar = Calendar.getInstance();
        gmtTZ1 = TimeZone.getTimeZone("GMT");
        cstTZ2 = TimeZone.getTimeZone("America/Chicago");
    }

    public static Date getDateFromString(String dateString) {
        try {
            return cstTZFormat.parse(dateString);
        } catch (Exception e) {
            log.debug("getDateFromString-->"+e);
        }
        return getCurrentDate();
    }

    public static Date getCurrentDate() {
        return Calendar.getInstance().getTime();
    }

    public static Calendar getCurrentCalendar() {
        return Calendar.getInstance(TimeZone.getDefault());
    }

    public static int getCurrentYear() {
        return Calendar.getInstance(TimeZone.getDefault()).get(Calendar.YEAR);
    }

    public static int getCurrentMonth() {
        return Calendar.getInstance(TimeZone.getDefault()).get(Calendar.MONTH);
    }

    public static int getDayOfMonth() {
        return Calendar.getInstance(TimeZone.getDefault()).get(Calendar.DAY_OF_MONTH);
    }

    public static int getDayOfYear() {
        return Calendar.getInstance(TimeZone.getDefault()).get(Calendar.DAY_OF_YEAR);
    }

    public static String getFormattedDate() {
        return dateFormat.format(getCurrentDate());
    }

    public static String getFormattedDate(Date dateToFormat) {
        return dateFormat.format(dateToFormat);
    }

    public static Date getNextYearDate() {
        calendar.setTime(new Date());
        calendar.add(Calendar.YEAR, 1);
        return calendar.getTime();
    }

    public static Date getMaxValidityDate() {
        calendar.setTime(new Date());
        calendar.add(Calendar.YEAR, 150);
        return calendar.getTime();
    }

    public static Date getDaysBefore(int days) {
        return Date.from(LocalDate.now().minusDays(days).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date getDaysAfter(int days) {
        return Date.from(LocalDate.now().plusDays(days).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date addDay(Date dateToAdjust) {
        calendar.setTime(dateToAdjust);
        calendar.add(Calendar.DATE, 1);
        return calendar.getTime();
    }

    public static Date addMonth(Date dateToAdjust) {
        calendar.setTime(dateToAdjust);
        calendar.add(Calendar.MONTH, 1);
        return calendar.getTime();
    }

    public static Date ReduceMonth(Date dateToAdjust) {
        calendar.setTime(dateToAdjust);
        calendar.add(Calendar.MONTH, -1);
        return calendar.getTime();
    }

    public static Date getFirstDateOfMonth(Date date) {
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    public static Date getFirstDateOfMonth() {
        return getFirstDateOfMonth(new java.util.Date());
    }

    public static Date getFirstDateOfPreviousMonth() {
        Date currDate = new java.util.Date();
        Date previousMonth = ReduceMonth(currDate);
        return getFirstDateOfMonth(previousMonth);
    }

    public static Date getLastDateOfMonth(Date date) {
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    public static Date getLastDateOfPreviousMonth() {
        Date currDate = new java.util.Date();
        Date previousMonth = ReduceMonth(currDate);
        return getLastDateOfMonth(previousMonth);
    }

    public static Date getLastDateOfMonth() {
        return getFirstDateOfMonth(new java.util.Date());
    }

    public static String getFormattedDateString() {
        customDateFormat = new SimpleDateFormat("MM/dd/yyyy");
        return customDateFormat.format(new Date());
    }

    public static String getFormattedDateTimeString() {
        customDateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
        return customDateFormat.format(new Date());
    }

    public static String getFormattedDateTime(Date date) {
        customDateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
        return customDateFormat.format(date);
    }

    public static String getFormattedDateValue(Date date) {
        customDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");
        return customDateFormat.format(date);
    }

    public static long getRawOffset(){
        return gmtTZ1.getRawOffset() - cstTZ2.getRawOffset() + gmtTZ1.getDSTSavings() - cstTZ2.getDSTSavings();
    }
    
    public static long getOffset(Date date){
        return gmtTZ1.getOffset(date.getTime()) - cstTZ2.getOffset(date.getTime());
    }
    
    public static String getTZUpdatedDate(String dateValue) {
        dateValue = dateValue.endsWith("Z") ? dateValue.concat("") : dateValue.concat("Z");
        Date dateVal = Date.from(Instant.parse(dateValue));
        return Instant.parse(dateValue).plusMillis(getOffset(dateVal)).toString();
    }
    
    public static String getSimpleDateFormat(String dateValue) {
        dateValue = dateValue.endsWith("Z") ? dateValue.concat("") : dateValue.concat("Z");
        Date dateVal = Date.from(Instant.parse(dateValue));
        return simpleDateFormat.format(dateVal);
    }
    
}
