"use client";

export const HOLIDAY_SOURCE_LABELS = {
  CALENDAR: "Holiday Calendar",
  LEGACY_PUBLIC_HOLIDAY: "Legacy import",
  CALENDAR_AND_LEGACY: "Holiday Calendar + legacy",
} as const;

export type VacationExplainabilityEntry = {
  startDate: Date | string;
  endDate: Date | string;
  isHalfDay?: boolean | null;
  deductedDays?: number | null;
  holidayCountryCode?: string | null;
  holidayCountryName?: string | null;
  holidayFederalState?: string | null;
  holidayMetroCityName?: string | null;
  holidayCalendarDates?: unknown;
  holidayLegacyPublicHolidayDates?: unknown;
};

function toSortedDateList(value: unknown): string[] {
  return Array.isArray(value) && value.every((entry) => typeof entry === "string")
    ? [...value].sort()
    : [];
}

export function getRequestedDays(vacation: Pick<VacationExplainabilityEntry, "startDate" | "endDate" | "isHalfDay">): number {
  if (vacation.isHalfDay) {
    return 0.5;
  }

  const start = new Date(vacation.startDate);
  const end = new Date(vacation.endDate);
  return Math.round((end.getTime() - start.getTime()) / 86_400_000) + 1;
}

export function getHolidayBasis(vacation: VacationExplainabilityEntry): string[] {
  return [
    vacation.holidayCountryName ?? vacation.holidayCountryCode ?? null,
    vacation.holidayFederalState ?? null,
    vacation.holidayMetroCityName ?? null,
  ].filter((value): value is string => Boolean(value));
}

export function getHolidayBreakdown(vacation: VacationExplainabilityEntry): Array<{ date: string; source: string }> {
  const calendarDates = toSortedDateList(vacation.holidayCalendarDates);
  const legacyDates = toSortedDateList(vacation.holidayLegacyPublicHolidayDates);
  const uniqueDates = [...new Set([...calendarDates, ...legacyDates])].sort();

  return uniqueDates.map((date) => ({
    date,
    source:
      calendarDates.includes(date) && legacyDates.includes(date)
        ? HOLIDAY_SOURCE_LABELS.CALENDAR_AND_LEGACY
        : calendarDates.includes(date)
          ? HOLIDAY_SOURCE_LABELS.CALENDAR
          : HOLIDAY_SOURCE_LABELS.LEGACY_PUBLIC_HOLIDAY,
  }));
}

export function buildVacationExplainabilityTooltip(
  vacation: VacationExplainabilityEntry & { type?: string | null },
): string | null {
  const requestedDays = getRequestedDays(vacation);
  const deductedDays = typeof vacation.deductedDays === "number" ? vacation.deductedDays : null;
  const holidayBasis = getHolidayBasis(vacation);
  const holidayBreakdown = getHolidayBreakdown(vacation);
  const lines = [`Requested: ${requestedDays}d`];

  if (deductedDays !== null) {
    lines.push(`Deducted: ${deductedDays}d`);
  }

  if (holidayBasis.length > 0) {
    lines.push(`Holiday basis: ${holidayBasis.join(" / ")}`);
  }

  if (holidayBreakdown.length > 0) {
    lines.push(`Excluded holidays: ${holidayBreakdown.map((holiday) => `${holiday.date} (${holiday.source})`).join(", ")}`);
  }

  if ((vacation.type === "SICK" || vacation.type === "PUBLIC_HOLIDAY") && deductedDays === 0) {
    lines.push("Does not reduce annual vacation entitlement.");
  }

  return lines.length > 0 ? lines.join("\n") : null;
}
