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);
	}

}
