/**
 * 报表周期导航（P4）：单一 anchor 日期 + 周期类型，替代周/月/年三套独立状态。
 * 全部本地时区字符串运算，避免 toISOString 的 UTC 偏移。
 */
import { toDateString } from '../core/decimal';

export type ReportPeriod = 'weekly' | 'monthly' | 'annual';

function parse(dateStr: string): Date {
  const [y, m, d] = dateStr.split('-').map(Number);
  return new Date(y, m - 1, d);
}

/** 平移 anchor：周 ±7 天；月 ±N（月末日钳制）；年 ±N。 */
export function shiftAnchor(anchor: string, period: ReportPeriod, delta: number): string {
  const d = parse(anchor);
  if (period === 'weekly') {
    d.setDate(d.getDate() + 7 * delta);
  } else if (period === 'monthly') {
    const day = d.getDate();
    d.setDate(1);
    d.setMonth(d.getMonth() + delta);
    // 月末钳制：目标月天数不足时退到月末
    const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
    d.setDate(Math.min(day, lastDay));
  } else {
    d.setFullYear(d.getFullYear() + delta);
  }
  return toDateString(d);
}

/** anchor 所在周期的起止日期（含两端）。周 = 周一~周日。 */
export function periodRange(anchor: string, period: ReportPeriod): { start: string; end: string } {
  const d = parse(anchor);
  if (period === 'weekly') {
    const day = d.getDay(); // 0=周日
    const diffToMonday = day === 0 ? -6 : 1 - day;
    const monday = new Date(d);
    monday.setDate(d.getDate() + diffToMonday);
    const sunday = new Date(monday);
    sunday.setDate(monday.getDate() + 6);
    return { start: toDateString(monday), end: toDateString(sunday) };
  }
  if (period === 'monthly') {
    const start = new Date(d.getFullYear(), d.getMonth(), 1);
    const end = new Date(d.getFullYear(), d.getMonth() + 1, 0);
    return { start: toDateString(start), end: toDateString(end) };
  }
  return { start: `${d.getFullYear()}-01-01`, end: `${d.getFullYear()}-12-31` };
}

/** ISO-8601 周数（周一开头）。 */
export function isoWeekNumber(dateStr: string): number {
  const date = parse(dateStr);
  date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));
  const week1 = new Date(date.getFullYear(), 0, 4);
  return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + ((week1.getDay() + 6) % 7)) / 7);
}
