/**
 * 周期性记账（plan.md「5.6 周期性记账」）。
 */

import type { TransactionDraft } from '../core/types';

export interface RecurringTransaction {
  id: string;
  name: string;
  draft: TransactionDraft;
  frequency: 'daily' | 'weekly' | 'monthly' | 'yearly';
  /** 间隔（如每 2 周 = weekly + interval: 2）。 */
  interval: number;
  nextDueDate: string;
  enabled: boolean;
  /** 是否自动确认（无需手动点击）。默认 false。 */
  autoConfirm?: boolean;
}

/** 检查到期的周期性交易。 */
export function getDueRecurring(
  recurring: RecurringTransaction[],
  currentDate: string,
): RecurringTransaction[] {
  const current = Date.parse(currentDate);
  if (isNaN(current)) {
    // 回退到字符串比较
    return recurring.filter(r => r.enabled && r.nextDueDate <= currentDate);
  }
  return recurring.filter(r => {
    if (!r.enabled) return false;
    const due = Date.parse(r.nextDueDate);
    if (isNaN(due)) return r.nextDueDate <= currentDate;
    return due <= current;
  });
}

/** 计算下次到期日期。 */
export function calculateNextDueDate(
  frequency: RecurringTransaction['frequency'],
  interval: number,
  lastDueDate: string,
): string {
  const date = new Date(lastDueDate + 'T00:00:00'); // 强制本地时间，避免 toISOString 的 UTC 偏移
  switch (frequency) {
    case 'daily': date.setDate(date.getDate() + interval); break;
    case 'weekly': date.setDate(date.getDate() + 7 * interval); break;
    case 'monthly': {
      // 先设为 1 日避免 setMonth 溢出（如 1月31日 + 1月 → 3月3日）
      const targetMonth = date.getMonth() + interval;
      const originalDay = date.getDate();
      date.setDate(1);
      date.setMonth(targetMonth);
      const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
      date.setDate(Math.min(originalDay, lastDay));
      break;
    }
    case 'yearly': {
      // 避免闰年 2月29日 加 1 年变成 3月1日，应为 2月28日
      const targetYear = date.getFullYear() + interval;
      const originalMonth = date.getMonth();
      const originalDay = date.getDate();
      date.setDate(1);
      date.setFullYear(targetYear);
      date.setMonth(originalMonth);
      const lastDay = new Date(date.getFullYear(), originalMonth + 1, 0).getDate();
      date.setDate(Math.min(originalDay, lastDay));
      break;
    }
  }
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  return `${y}-${m}-${d}`;
}

/** 生成到期实例（把 nextDueDate 设为 draft.date）。 */
export function instantiateRecurring(r: RecurringTransaction): TransactionDraft {
  return { ...r.draft, date: r.nextDueDate };
}
