import { DateTime } from "luxon";
export const Datetime = () => ({
  luxonDateTime: DateTime.invalid("Uninitialized"),
  fromString: function(dateTime, formatDate, locale = "EN") {
    if (!dateTime) return this.setDateTime(DateTime.invalid("No datetime string provided"), locale);
    let inputDate = void 0;
    if (formatDate) inputDate = DateTime.fromFormat(dateTime, formatDate, { locale });
    if (!inputDate?.isValid) inputDate = DateTime.fromISO(dateTime, { locale });
    if (!inputDate?.isValid) {
      const formats = [
        "ddMMyyyy",
        "ddMMyy",
        "dd/MM/yyyy",
        "yyyyMMdd",
        "dd/MM/yyyy",
        "dd/M/yyyy",
        "d/MM/yyyy",
        "d/M/yyyy",
        "dd MMM yyyy",
        "d MMM yyyy",
        "yyyy-MM-dd HH:mm",
        "yyyy-MM-dd HH:mm:ss"
      ];
      for (let i = 0; i < formats.length; ++i) {
        inputDate = DateTime.fromFormat(dateTime, formats[i], { locale });
        if (inputDate.isValid) break;
      }
    }
    return this.setDateTime(inputDate, locale);
  },
  fromStringTime: function(time, formatTime, locale = "EN") {
    if (!time) return this.setDateTime(DateTime.invalid("No datetime string provided"), locale);
    let inputTime = void 0;
    if (formatTime) inputTime = DateTime.fromFormat(time, formatTime, { locale });
    if (!inputTime?.isValid) {
      const formats = [
        "HHmm",
        "Hmm",
        "HHmmss",
        "HH:mm",
        "H:mm",
        "HH:mm:ss"
      ];
      for (let i = 0; i < formats.length; ++i) {
        inputTime = DateTime.fromFormat(time, formats[i], { locale });
        if (inputTime.isValid) break;
      }
    }
    if (!inputTime?.isValid) inputTime = DateTime.fromISO(time, { locale });
    return this.setDateTime(inputTime, locale);
  },
  fromISO: function(dateTime, locale = "EN") {
    const inputDate = DateTime.fromISO(dateTime, { locale });
    return this.setDateTime(inputDate, locale);
  },
  fromObject: function(dateTime, locale = "EN") {
    const inputDate = DateTime.fromObject(dateTime, { locale });
    return this.setDateTime(inputDate, locale);
  },
  setDateTime: function(inputDate, locale = "EN") {
    if (inputDate.isValid) {
      if (inputDate.year - DateTime.now().year > 300) inputDate = inputDate.set({ year: inputDate.year - 543 });
    }
    this.luxonDateTime = inputDate;
    if (locale == "TH") this.luxonDateTime = this.luxonDateTime.setLocale(locale).reconfigure({ outputCalendar: "buddhist" });
    else this.luxonDateTime = this.luxonDateTime.setLocale(locale).reconfigure({ outputCalendar: "gregory" });
    return this;
  },
  toFormat: function(format, locale = "EN") {
    if (format == "tinyDate") return this.toTinyDate(locale);
    if (format == "monthShortDate") return this.toMonthShortDate(locale);
    if (format == "shortDate") return this.toShortDate(locale);
    if (format == "longDate") return this.toLongDate(locale);
    if (format == "tinyDateTime") return this.toTinyDateTime(locale);
    if (format == "shortDateTime") return this.toShortDateTime(locale);
    if (format == "longDateTime") return this.toLongDateTime(locale);
    if (locale == "TH") this.luxonDateTime = this.luxonDateTime.setLocale(locale).reconfigure({ outputCalendar: "buddhist" });
    else this.luxonDateTime = this.luxonDateTime.setLocale(locale).reconfigure({ outputCalendar: "gregory" });
    return this.luxonDateTime.toFormat(format);
  },
  toISO: function() {
    return this.luxonDateTime.toISO();
  },
  toLocaleFormat: function(locale, format) {
    if (locale == "TH") this.luxonDateTime = this.luxonDateTime.setLocale(locale).reconfigure({ outputCalendar: "buddhist" });
    else this.luxonDateTime = this.luxonDateTime.setLocale(locale).reconfigure({ outputCalendar: "gregory" });
    return this.luxonDateTime.setLocale(locale).toLocaleString(format);
  },
  toTinyDate: function(locale = "EN") {
    return this.toLocaleFormat(locale, DateTime.DATE_SHORT);
  },
  toMonthShortDate: function(locale = "EN") {
    return this.toLocaleFormat(locale, DateTime.DATE_MED);
  },
  toShortDate: function(locale = "EN") {
    return this.toLocaleFormat(locale, DateTime.DATE_FULL);
  },
  toLongDate: function(locale = "EN") {
    return this.toLocaleFormat(locale, DateTime.DATE_HUGE);
  },
  toTinyDateTime: function(locale = "EN") {
    return this.toLocaleFormat(locale, DateTime.DATETIME_SHORT);
  },
  toShortDateTime: function(locale = "EN") {
    return this.toLocaleFormat(locale, DateTime.DATETIME_MED);
  },
  toLongDateTime: function(locale = "EN") {
    return this.toLocaleFormat(locale, DateTime.DATETIME_HUGE);
  },
  isAfter: function(compareDate) {
    return this.luxonDateTime > Datetime().fromString(compareDate).luxonDateTime;
  },
  isBefore: function(compareDate) {
    return this.luxonDateTime < Datetime().fromString(compareDate).luxonDateTime;
  },
  isEqual: function(compareDate) {
    return this.luxonDateTime == Datetime().fromString(compareDate).luxonDateTime;
  },
  isFuture: function() {
    return this.luxonDateTime > Datetime().now().luxonDateTime;
  },
  isFutureDate: function() {
    return this.luxonDateTime > Datetime().now().luxonDateTime.endOf("day");
  },
  isHappen: function() {
    return this.luxonDateTime < Datetime().now().luxonDateTime;
  },
  isHappenDate: function() {
    return this.luxonDateTime < Datetime().now().luxonDateTime.endOf("day");
  },
  now: function() {
    this.luxonDateTime = DateTime.now();
    return this;
  }
});
export function verifyDateFormat(date) {
  const dateFormatRegex = /^(\d{4}|0{4})-(\d{2}|0{2})-(\d{2}|0{2})$/;
  const match = date.match(dateFormatRegex);
  if (match) {
    const year = match[1];
    const month = match[2];
    const day = match[3];
    const formatYear = Number.parseInt(year) > 0 ? "yyyy" : "";
    const fotmatMonth = Number.parseInt(month) > 0 && Number.parseInt(month) <= 12 ? "MM" : "";
    const formatDay = Number.parseInt(day) > 0 && Number.parseInt(day) <= 31 ? "dd" : "";
    return `${formatYear}${fotmatMonth}${formatDay}`;
  } else {
    return null;
  }
}
export function returnVerifyDate(date) {
  const dateFormatRegex = /^(\d{4}|0{4})-(\d{2}|0{2})-(\d{2}|0{2})$/;
  const match = date.match(dateFormatRegex);
  if (match) {
    const year = match[1];
    const month = match[2];
    const day = match[3];
    const fullMonth = Number.parseInt(month) == 0 || Number.parseInt(month) >= 13 ? "01" : month;
    const fullDay = Number.parseInt(day) == 0 || Number.parseInt(day) >= 32 ? "01" : day;
    return `${year}-${fullMonth}-${fullDay}`;
  } else {
    return null;
  }
}
