/**
 * 달력 유틸리티 함수
 */

// 한국 공휴일 데이터 (2025년 기준)
export interface Holiday {
  date: string; // 'MM-DD' 형식
  name: string;
  isRecurring: boolean;
}

export const KOREAN_HOLIDAYS: Holiday[] = [
  { date: "01-01", name: "신정", isRecurring: true },
  { date: "01-28", name: "설날 연휴", isRecurring: false },
  { date: "01-29", name: "설날", isRecurring: false },
  { date: "01-30", name: "설날 연휴", isRecurring: false },
  { date: "03-01", name: "삼일절", isRecurring: true },
  { date: "05-05", name: "어린이날", isRecurring: true },
  { date: "06-06", name: "현충일", isRecurring: true },
  { date: "08-15", name: "광복절", isRecurring: true },
  { date: "10-03", name: "개천절", isRecurring: true },
  { date: "10-09", name: "한글날", isRecurring: true },
  { date: "12-25", name: "크리스마스", isRecurring: true },
];

/**
 * 특정 월의 첫 날 Date 객체 반환
 */
export function getFirstDayOfMonth(year: number, month: number): Date {
  return new Date(year, month, 1);
}

/**
 * 특정 월의 마지막 날짜 반환
 */
export function getLastDateOfMonth(year: number, month: number): number {
  return new Date(year, month + 1, 0).getDate();
}

/**
 * 특정 월의 첫 날의 요일 반환 (0=일요일, 1=월요일, ...)
 */
export function getFirstDayOfWeek(year: number, month: number): number {
  return new Date(year, month, 1).getDay();
}

/**
 * 달력 그리드에 표시할 날짜 배열 생성
 * @param year 년도
 * @param month 월 (0-11)
 * @param startWeekOn 주 시작 요일 ('monday' | 'sunday')
 * @returns 6주 * 7일 = 42개의 날짜 정보 배열
 */
export interface CalendarDay {
  date: Date;
  day: number;
  isCurrentMonth: boolean;
  isToday: boolean;
  isWeekend: boolean;
  isHoliday: boolean;
  holidayName?: string;
}

export function generateCalendarDays(
  year: number,
  month: number,
  startWeekOn: "monday" | "sunday" = "sunday",
): CalendarDay[] {
  const days: CalendarDay[] = [];
  const firstDay = getFirstDayOfWeek(year, month);
  const lastDate = getLastDateOfMonth(year, month);
  const today = new Date();
  today.setHours(0, 0, 0, 0);

  // 시작 오프셋 계산
  let startOffset = firstDay;
  if (startWeekOn === "monday") {
    startOffset = firstDay === 0 ? 6 : firstDay - 1;
  }

  // 이전 달 날짜들
  const prevMonthLastDate = getLastDateOfMonth(year, month - 1);
  for (let i = startOffset - 1; i >= 0; i--) {
    const date = new Date(year, month - 1, prevMonthLastDate - i);
    days.push(createCalendarDay(date, false, today));
  }

  // 현재 달 날짜들
  for (let day = 1; day <= lastDate; day++) {
    const date = new Date(year, month, day);
    days.push(createCalendarDay(date, true, today));
  }

  // 다음 달 날짜들 (42개 채우기)
  const remainingDays = 42 - days.length;
  for (let day = 1; day <= remainingDays; day++) {
    const date = new Date(year, month + 1, day);
    days.push(createCalendarDay(date, false, today));
  }

  return days;
}

/**
 * CalendarDay 객체 생성
 */
function createCalendarDay(date: Date, isCurrentMonth: boolean, today: Date): CalendarDay {
  const dayOfWeek = date.getDay();
  const isToday = date.getTime() === today.getTime();
  const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;

  // 공휴일 체크
  const monthStr = String(date.getMonth() + 1).padStart(2, "0");
  const dayStr = String(date.getDate()).padStart(2, "0");
  const dateKey = `${monthStr}-${dayStr}`;
  const holiday = KOREAN_HOLIDAYS.find((h) => h.date === dateKey);

  return {
    date,
    day: date.getDate(),
    isCurrentMonth,
    isToday,
    isWeekend,
    isHoliday: !!holiday,
    holidayName: holiday?.name,
  };
}

/**
 * 요일 이름 배열 반환
 */
export function getWeekDayNames(startWeekOn: "monday" | "sunday" = "sunday"): string[] {
  const sundayFirst = ["일", "월", "화", "수", "목", "금", "토"];
  const mondayFirst = ["월", "화", "수", "목", "금", "토", "일"];
  return startWeekOn === "monday" ? mondayFirst : sundayFirst;
}

/**
 * 월 이름 반환
 */
export function getMonthName(month: number): string {
  const months = ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"];
  return months[month];
}

/**
 * 이전/다음 월로 이동
 */
export function navigateMonth(year: number, month: number, direction: "prev" | "next"): { year: number; month: number } {
  if (direction === "prev") {
    if (month === 0) {
      return { year: year - 1, month: 11 };
    }
    return { year, month: month - 1 };
  } else {
    if (month === 11) {
      return { year: year + 1, month: 0 };
    }
    return { year, month: month + 1 };
  }
}

