import type { Reminder, ReminderRecurrenceRule, ReminderStatus } from "@/types";

export const REMINDER_STATUS_LABELS: Record<ReminderStatus, string> = {
  scheduled: "Scheduled",
  triggered: "Due now",
  snoozed: "Snoozed",
  done: "Done",
  cancelled: "Cancelled",
};

export const REMINDER_RECURRENCE_LABELS: Record<ReminderRecurrenceRule, string> = {
  none: "Does not repeat",
  daily: "Daily",
  weekly: "Weekly",
  monthly: "Monthly",
  weekdays: "Selected weekdays",
};

export const REMINDER_WEEKDAY_OPTIONS = [
  { label: "Mo", longLabel: "Monday", value: 1 },
  { label: "Tu", longLabel: "Tuesday", value: 2 },
  { label: "We", longLabel: "Wednesday", value: 3 },
  { label: "Th", longLabel: "Thursday", value: 4 },
  { label: "Fr", longLabel: "Friday", value: 5 },
  { label: "Sa", longLabel: "Saturday", value: 6 },
  { label: "Su", longLabel: "Sunday", value: 0 },
] as const;

export function getReminderDueAt(reminder: Pick<Reminder, "remind_at" | "snoozed_until">) {
  return reminder.snoozed_until || reminder.remind_at;
}

export function isReminderClosed(reminder: Pick<Reminder, "status">) {
  return reminder.status === "done" || reminder.status === "cancelled";
}

export function isReminderDue(reminder: Pick<Reminder, "remind_at" | "snoozed_until" | "status">) {
  if (isReminderClosed(reminder)) return false;
  if (reminder.status === "triggered") return true;
  return new Date(getReminderDueAt(reminder)).getTime() <= Date.now();
}

export function toDatetimeLocalValue(value: Date | string) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "";
  const offset = date.getTimezoneOffset();
  const local = new Date(date.getTime() - offset * 60_000);
  return local.toISOString().slice(0, 16);
}

export function fromDatetimeLocalValue(value: string) {
  const date = new Date(value);
  return Number.isNaN(date.getTime()) ? new Date().toISOString() : date.toISOString();
}

export function getDefaultReminderTime() {
  const date = new Date();
  date.setHours(date.getHours() + 1, 0, 0, 0);
  return date;
}

export function getNextReminderOccurrence(
  reminder: Pick<Reminder, "remind_at" | "snoozed_until" | "recurrence_days" | "recurrence_rule">,
) {
  if (reminder.recurrence_rule === "none") return null;

  const now = Date.now();
  const next = new Date(getReminderDueAt(reminder));
  if (Number.isNaN(next.getTime())) return null;

  if (reminder.recurrence_rule === "weekdays") {
    const selectedDays = new Set((reminder.recurrence_days || []).filter((day) => day >= 0 && day <= 6));
    if (selectedDays.size === 0) return null;

    for (let offset = 0; offset < 14; offset += 1) {
      if (next.getTime() > now && selectedDays.has(next.getDay())) {
        return next.toISOString();
      }
      next.setDate(next.getDate() + 1);
    }

    return null;
  }

  while (next.getTime() <= now) {
    if (reminder.recurrence_rule === "daily") {
      next.setDate(next.getDate() + 1);
    } else if (reminder.recurrence_rule === "weekly") {
      next.setDate(next.getDate() + 7);
    } else if (reminder.recurrence_rule === "monthly") {
      next.setMonth(next.getMonth() + 1);
    }
  }

  return next.toISOString();
}
