/**
 * Date range helpers for dashboard and conversion queries.
 */

export type DateRange = "1d" | "7d" | "28d" | "30d" | "90d" | "12m";
export type CompareMode = "previous" | "yoy";

export function getDateRange(range: DateRange | string): { start: Date; end: Date } {
  const end = new Date();
  end.setHours(23, 59, 59, 999);

  const start = new Date();
  start.setHours(0, 0, 0, 0);

  switch (range) {
    case "1d":  break;
    case "7d":  start.setDate(start.getDate() - 7); break;
    case "28d": start.setDate(start.getDate() - 28); break;
    case "30d": start.setDate(start.getDate() - 30); break;
    case "90d": start.setDate(start.getDate() - 90); break;
    case "12m": start.setFullYear(start.getFullYear() - 1); break;
    default: {
      const match = /^(\d+)d$/.exec(range);
      if (match) start.setDate(start.getDate() - parseInt(match[1], 10));
    }
  }

  return { start, end };
}

export function getComparisonRange(
  start: Date,
  end: Date,
  mode: CompareMode
): { start: Date; end: Date } {
  const diffMs = end.getTime() - start.getTime();

  if (mode === "yoy") {
    return {
      start: new Date(start.getFullYear() - 1, start.getMonth(), start.getDate()),
      end: new Date(end.getFullYear() - 1, end.getMonth(), end.getDate()),
    };
  }

  // previous period — same duration, shifted back.
  // Round diffMs to whole days before shifting so that a 23h59m59.999s
  // window (produced when end = setHours(23,59,59,999)) doesn't land
  // comp.start 1ms after midnight, which would exclude MetricSnapshot
  // rows stored at exactly midnight UTC.
  const days = Math.round(diffMs / 86_400_000);
  return {
    start: new Date(start.getTime() - days * 86_400_000),
    end: new Date(start.getTime() - 1),
  };
}

export function daysBetween(start: Date, end: Date): number {
  return Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
}

export function rangeToDays(range: string): number {
  switch (range) {
    case "1d":  return 1;
    case "7d":  return 7;
    case "28d": return 28;
    case "30d": return 30;
    case "90d": return 90;
    case "12m": return 365;
    default: {
      const match = /^(\d+)d$/.exec(range);
      return match ? parseInt(match[1], 10) : 30;
    }
  }
}

export function rangeSince(range: string): Date {
  return new Date(Date.now() - rangeToDays(range) * 86_400_000);
}
