import {
  addWeeks,
  addDays,
  addMinutes,
  eachDayOfInterval,
  format,
  isFriday,
  isMonday,
  isSaturday,
  isSunday,
  isThursday,
  isTuesday,
  isWednesday,
  nextFriday,
  nextMonday,
  nextSaturday,
  nextSunday,
  nextThursday,
  nextTuesday,
  nextWednesday,
  startOfWeek,
  subWeeks,
} from "date-fns";

export { addDays, addMinutes };

import { fr } from "date-fns/locale";

export const euroDateFormat = "dd/MM/yyyy";
export const jourLabelFormat = "EEEE, d MMMM";

export const jourDateAnneeFormat = "EEEE, d MMMM yyyy";

export const jours = [
  "Dimanche",
  "Lundi",
  "Mardi",
  "Mercredi",
  "Jeudi",
  "Vendredi",
  "Samedi",
];

export const euroDate = (date: string | Date | null = null) => {
  if (date === null) {
    return null;
  } else {
    return date
      ? format(new Date(date), euroDateFormat)
      : format(new Date(), euroDateFormat);
  }
};

export const euroDateAndTime = (date: string | null = null) => {
  if (date === null) {
    return null;
  } else {
    return date
      ? format(new Date(date), euroDateFormat + " HH:mm")
      : format(new Date(), euroDateFormat + " HH:mm");
  }
};

export const jourLabelDate = (date: string | Date | null = null) => {
  if (date === null) {
    return null;
  } else {
    return date
      ? format(new Date(date), jourLabelFormat, { locale: fr })
      : format(new Date(), jourLabelFormat, { locale: fr });
  }
};

export const jourDateAnnee = (date: string | Date | null = null) => {
  if (date === null) {
    return null;
  } else {
    return date
      ? format(new Date(date), jourDateAnneeFormat, { locale: fr })
      : format(new Date(), jourDateAnneeFormat, { locale: fr });
  }
};

export const euroTime = (date: string | Date | null = null) => {
  if (date === null) {
    return null;
  } else {
    return date
      ? format(new Date(date), "HH:mm").replace(":", "h")
      : format(new Date(), "HH:mm").replace(":", "h");
  }
};

export function dateEgales(_date1: Date, _date2: Date): boolean {
  const date1 = new Date(_date1);
  const date2 = new Date(_date2);

  return date1.getTime() === date2.getTime();
}

//time au format hh:mm:ss

export const joursChiffres = [0, 1, 2, 3, 4, 5, 6];

export const nextDays = {
  0: (date: Date) => (isSunday(date) ? date : nextSunday(date)),
  1: (date: Date) => (isMonday(date) ? date : nextMonday(date)),
  2: (date: Date) => (isTuesday(date) ? date : nextTuesday(date)),
  3: (date: Date) => (isWednesday(date) ? date : nextWednesday(date)),
  4: (date: Date) => (isThursday(date) ? date : nextThursday(date)),
  5: (date: Date) => (isFriday(date) ? date : nextFriday(date)),
  6: (date: Date) => (isSaturday(date) ? date : nextSaturday(date)),
};

export const isDayOfWeek = (date: string, dayOfWeek: number) => {
  return new Date(date).getDay() === dayOfWeek;
};

export const getLastToNextDay = (dayIndex: 0 | 1 | 2 | 3 | 4 | 5 | 6) => {
  // définir la date actuelle
  let today: Date = new Date();

  // vérifier si aujourd'hui est le jour spécifié
  if (!(today.getDay() === dayIndex)) {
    // si ce n'est pas le cas, récupérer le dernier jour spécifié
    today = subWeeks(startOfWeek(today, { weekStartsOn: dayIndex }), 1);
  }

  // récupérer le même jour de la semaine prochaine
  let nextWeekDay: Date = addWeeks(today, 1);

  // vérifier l'intervalle de date
  let interval: Date[] = eachDayOfInterval({
    start: today,
    end: nextWeekDay,
  });

  return interval;
};

export const getNextDay = (dayIndex: 0 | 1 | 2 | 3 | 4 | 5 | 6) => {
  const todayDayIndex = new Date().getDay();

  if (todayDayIndex === dayIndex) {
    return new Date();
  }

  switch (dayIndex) {
    case 0:
      return nextSunday(new Date());
    case 1:
      return nextMonday(new Date());
    case 2:
      return nextTuesday(new Date());
    case 3:
      return nextWednesday(new Date());
    case 4:
      return nextThursday(new Date());
    case 5:
      return nextFriday(new Date());
    case 6:
      return nextSaturday(new Date());
    default:
      return new Date();
  }
};
