// frontend/lib/calendar/time.ts — cal.jsx 의 toMin/fmt/topOf 이식
export const HSTART = 7;
export const PXH = 52;
export const HOURS = Array.from({ length: 16 }, (_, i) => 7 + i); // 7..22

export const toMin = (t: string): number => {
  const [h, m] = t.split(":").map(Number);
  return h * 60 + m;
};

// 분 → "HH:MM"(자정~23:59 캡). 드래그 이동/리사이즈 결과 계산용.
export const fromMin = (total: number): string => {
  const t = Math.max(0, Math.min(total, 23 * 60 + 59));
  const h = Math.floor(t / 60);
  const m = t % 60;
  return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
};

export const GRID_END_MIN = (HSTART + HOURS.length) * 60; // 23:00 (그리드 하단)

export const fmt = (t: string): string => {
  const [h, m] = t.split(":").map(Number);
  const ap = h < 12 ? "오전" : "오후";
  const hh = h % 12 === 0 ? 12 : h % 12;
  return `${ap} ${hh}:${String(m).padStart(2, "0")}`;
};

export const topOf = (t: string): number => ((toMin(t) - HSTART * 60) / 60) * PXH;

// 그리드 내부 Y 픽셀 → "HH:MM"(30분 단위 반올림). 슬롯 클릭 생성용.
export const timeOfPx = (y: number): string => {
  const totalMin = HSTART * 60 + (y / PXH) * 60;
  const lastMin = (HSTART + HOURS.length) * 60; // 22:00
  const snapped = Math.round(totalMin / 30) * 30;
  const clamped = Math.max(HSTART * 60, Math.min(snapped, lastMin - 60));
  const h = Math.floor(clamped / 60);
  const m = clamped % 60;
  return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
};

// "HH:MM" + n시간 → "HH:MM"(24시 캡). 생성 시 종료시각 계산용.
export const addHour = (t: string, n: number): string => {
  const total = Math.min(toMin(t) + n * 60, 23 * 60 + 59);
  const h = Math.floor(total / 60);
  const m = total % 60;
  return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
};

// ── 실제 날짜(ISO "YYYY-MM-DD") 유틸 ──────────────────────────────
export const parseISO = (iso: string): Date => {
  const [y, m, d] = iso.split("-").map(Number);
  return new Date(y, (m || 1) - 1, d || 1);
};
export const isoOf = (d: Date): string =>
  `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
export const addDays = (iso: string, n: number): string => {
  const d = parseISO(iso);
  d.setDate(d.getDate() + n);
  return isoOf(d);
};
export const addMonths = (iso: string, n: number): string => {
  const d = parseISO(iso);
  d.setDate(1);
  d.setMonth(d.getMonth() + n);
  return isoOf(d);
};
export const startOfWeek = (iso: string): string => {
  const d = parseISO(iso);
  d.setDate(d.getDate() - d.getDay()); // 일요일 시작
  return isoOf(d);
};
export const weekDatesOf = (iso: string): string[] => {
  const s = startOfWeek(iso);
  return Array.from({ length: 7 }, (_, i) => addDays(s, i));
};
export const dayNum = (iso: string): number => parseISO(iso).getDate();
export const monthNum = (iso: string): number => parseISO(iso).getMonth() + 1;
export const yearNum = (iso: string): number => parseISO(iso).getFullYear();
// 월 그리드(42칸): 해당 월 1일이 포함된 주(일요일)부터 6주.
export const monthCells = (iso: string): { date: string; inMonth: boolean }[] => {
  const ref = parseISO(iso);
  const first = new Date(ref.getFullYear(), ref.getMonth(), 1);
  const startIso = startOfWeek(isoOf(first));
  return Array.from({ length: 42 }, (_, i) => {
    const date = addDays(startIso, i);
    return { date, inMonth: monthNum(date) === ref.getMonth() + 1 };
  });
};
