/**
 * Divisi Metrics — Date range calculation helpers and preset definitions
 */

// ── DateRange interface ─────────────────────────────────────────────────────

export interface DateRange {
  start: Date;
  end: Date;
  label: string;
}

// ── Preset builders ─────────────────────────────────────────────────────────

/**
 * Build a "Last N days" range ending at the start of today (00:00).
 */
function lastNDays(days: number, label: string): DateRange {
  const end = startOfToday();
  const start = new Date(end);
  start.setDate(start.getDate() - days);
  return { start, end, label };
}

/**
 * Return midnight of the current day (local time).
 */
function startOfToday(): Date {
  const d = new Date();
  d.setHours(0, 0, 0, 0);
  return d;
}

// ── Preset definitions ──────────────────────────────────────────────────────

export type PresetKey =
  | 'last7Days'
  | 'last30Days'
  | 'last90Days'
  | 'last12Months'
  | 'yearToDate';

export interface DatePreset {
  key: PresetKey;
  label: string;
  buildRange: () => DateRange;
}

export const datePresets: readonly DatePreset[] = [
  {
    key: 'last7Days',
    label: 'Last 7 Days',
    buildRange: () => lastNDays(7, 'Last 7 Days'),
  },
  {
    key: 'last30Days',
    label: 'Last 30 Days',
    buildRange: () => lastNDays(30, 'Last 30 Days'),
  },
  {
    key: 'last90Days',
    label: 'Last 90 Days',
    buildRange: () => lastNDays(90, 'Last 90 Days'),
  },
  {
    key: 'last12Months',
    label: 'Last 12 Months',
    buildRange: () => {
      const end = startOfToday();
      const start = new Date(end);
      start.setFullYear(start.getFullYear() - 1);
      return { start, end, label: 'Last 12 Months' };
    },
  },
  {
    key: 'yearToDate',
    label: 'Year to Date',
    buildRange: () => {
      const end = startOfToday();
      const start = new Date(end.getFullYear(), 0, 1); // Jan 1
      return { start, end, label: 'Year to Date' };
    },
  },
] as const;

// ── Helpers ─────────────────────────────────────────────────────────────────

/**
 * Build the default date range used when a dashboard first loads.
 * Default: "Last 12 Months" (Requirement 15.6).
 */
export function getDefaultDateRange(): DateRange {
  const preset = datePresets.find((p) => p.key === 'last12Months')!;
  return preset.buildRange();
}

/**
 * Build a DateRange from a preset key.
 */
export function getDateRangeByPreset(key: PresetKey): DateRange {
  const preset = datePresets.find((p) => p.key === key);
  if (!preset) {
    throw new Error(`Unknown date preset: ${key}`);
  }
  return preset.buildRange();
}

/**
 * Build a custom DateRange from explicit start/end dates.
 * Throws if start ≥ end.
 */
export function buildCustomDateRange(start: Date, end: Date): DateRange {
  if (start >= end) {
    throw new Error('Start date must be before end date');
  }

  const fmt = (d: Date) =>
    d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });

  return {
    start,
    end,
    label: `${fmt(start)} – ${fmt(end)}`,
  };
}

/**
 * Check whether a given date falls within a DateRange (inclusive on both ends).
 */
export function isDateInRange(date: Date, range: DateRange): boolean {
  return date >= range.start && date <= range.end;
}

/**
 * Format a DateRange as a human-readable string.
 * @example "Jan 1, 2025 – Jun 30, 2025"
 */
export function formatDateRange(range: DateRange): string {
  const fmt = (d: Date) =>
    d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
  return `${fmt(range.start)} – ${fmt(range.end)}`;
}
