export const BOARD_REF_DATE_KEY = 'eene-board-reference-date';
export const BOARD_QUARTER_KEY = 'eene-board-selected-quarter-v2';

export const QUARTER_RANGE_LABELS = ['1.01~3.31', '4.01~6.30', '7.01~9.30', '10.01~12.31'] as const;

export function startOfDay(d: Date): Date {
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}

export function toIsoDate(d: Date): string {
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}

export function parseIsoDate(iso: string): Date | null {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(iso)) return null;
  const [y, m, day] = iso.split('-').map(Number);
  const dt = new Date(y, m - 1, day);
  if (dt.getFullYear() !== y || dt.getMonth() !== m - 1 || dt.getDate() !== day) return null;
  return dt;
}

export function dateToQuarter(d: Date): string {
  const q = Math.floor(d.getMonth() / 3) + 1;
  return `${d.getFullYear()}-Q${q}`;
}

export function quarterToLabel(quarter: string): string {
  return quarter.replace(/^(\d{4})-Q(\d)$/, '$1 $2분기 업무');
}

export function formatQuarterShort(quarter: string): string {
  return quarter.replace(/^(\d{4})-Q(\d)$/, '$1 $2분기');
}

export function formatQuarterRangeLabel(quarter: string): string {
  const m = quarter.match(/^\d{4}-Q([1-4])$/);
  if (!m) return '';
  return QUARTER_RANGE_LABELS[Number(m[1]) - 1];
}

export function formatQuarterPillLabel(quarter: string): string {
  const title = formatQuarterShort(quarter);
  const range = formatQuarterRangeLabel(quarter);
  return range ? `${title} · ${range}` : title;
}

export function weekOfMonthLabel(d: Date): string {
  return `${d.getMonth() + 1}월 ${Math.ceil(d.getDate() / 7)}주차`;
}

export function quarterNumber(d: Date): number {
  return Math.floor(d.getMonth() / 3) + 1;
}

export function endOfWeekSunday(monday: Date): Date {
  const d = startOfDay(monday);
  d.setDate(d.getDate() + 6);
  return d;
}

export function formatReferenceWeekSummary(d: Date): string {
  const monday = startOfWeekMonday(d);
  return `${weekOfMonthLabel(monday)} · ${quarterNumber(monday)}분기`;
}

export function parseQuarterKey(value: string | null | undefined): string | null {
  if (!value || !/^\d{4}-Q[1-4]$/.test(value)) return null;
  return value;
}

export function formatBoardCalendarPill(
  selectedQuarter: string,
  weekLensActive: boolean,
  weekMonday: Date,
): string {
  if (weekLensActive) {
    const anchor = isSameWeek(new Date(), weekMonday) ? startOfDay(new Date()) : startOfWeekMonday(weekMonday);
    return `기준일 ${toIsoDate(anchor)} · ${weekOfMonthLabel(weekMonday)}`;
  }
  return formatQuarterPillLabel(selectedQuarter);
}

export function formatWeekRangeLabel(weekMonday: Date): string {
  const start = startOfWeekMonday(weekMonday);
  const end = endOfWeekSunday(start);
  const fmt = (dt: Date) => `${dt.getMonth() + 1}/${dt.getDate()}`;
  return `${fmt(start)} ~ ${fmt(end)}`;
}

/** @deprecated use formatBoardCalendarPill */
export function formatReferencePill(d: Date): string {
  return formatReferenceWeekSummary(d);
}

export function startOfWeekMonday(d: Date): Date {
  const x = startOfDay(d);
  const dow = x.getDay();
  const offset = dow === 0 ? -6 : 1 - dow;
  x.setDate(x.getDate() + offset);
  return x;
}

export function quarterStartDate(quarter: string): Date {
  const m = quarter.match(/^(\d{4})-Q([1-4])$/);
  if (!m) return startOfDay(new Date());
  return new Date(Number(m[1]), (Number(m[2]) - 1) * 3, 1);
}

export function quarterEndDate(quarter: string): Date {
  const m = quarter.match(/^(\d{4})-Q([1-4])$/);
  if (!m) return startOfDay(new Date());
  const year = Number(m[1]);
  const q = Number(m[2]);
  const endMonth = q * 3;
  return new Date(year, endMonth, 0);
}

export function isSameDay(a: Date, b: Date): boolean {
  return startOfDay(a).getTime() === startOfDay(b).getTime();
}

export function isSameWeek(a: Date, b: Date): boolean {
  return startOfWeekMonday(a).getTime() === startOfWeekMonday(b).getTime();
}

export interface CalendarWeekRow {
  label: string;
  monday: Date;
  days: Date[];
}

export function buildMonthWeekRows(year: number, monthIndex: number): CalendarWeekRow[] {
  const rows: CalendarWeekRow[] = [];
  let monday = startOfWeekMonday(new Date(year, monthIndex, 1));
  const monthEnd = new Date(year, monthIndex + 1, 0);

  for (let w = 0; w < 6; w++) {
    const days: Date[] = Array.from({ length: 7 }, (_, i) => {
      const d = new Date(monday);
      d.setDate(monday.getDate() + i);
      return d;
    });
    if (days.some((d) => d.getMonth() === monthIndex)) {
      const anchor = days.find((d) => d.getMonth() === monthIndex)!;
      rows.push({
        label: weekOfMonthLabel(anchor),
        monday: startOfDay(new Date(monday)),
        days,
      });
    }
    monday = new Date(monday);
    monday.setDate(monday.getDate() + 7);
    if (monday > monthEnd && monday.getMonth() !== monthIndex) break;
  }
  return rows;
}
