/**
 * Pure math utilities for timeline drag operations.
 * Extracted from useTimelineDrag to make the conversion logic testable
 * and reusable across different drag modes.
 */

/** Convert a pixel delta to a number of whole days based on cell width. */
export function pixelsToDays(deltaX: number, cellWidth: number): number {
  if (!Number.isFinite(cellWidth) || cellWidth <= 0) {
    return 0;
  }
  return Math.round(deltaX / cellWidth);
}

/**
 * Shift a date by a given number of days, returning a new Date.
 * Does not mutate the input.
 */
export function shiftDate(date: Date, daysDelta: number): Date {
  const result = new Date(date);
  result.setDate(result.getDate() + daysDelta);
  return result;
}

/**
 * Compute new start/end dates for a drag operation.
 * Handles move, resize-start, and resize-end modes with clamping
 * to prevent start from crossing past end (or vice versa).
 */
export function computeDragDates(
  mode: "move" | "resize-start" | "resize-end",
  originalStart: Date,
  originalEnd: Date,
  daysDelta: number,
): { start: Date; end: Date } {
  const newStart = new Date(originalStart);
  const newEnd = new Date(originalEnd);

  if (mode === "move") {
    newStart.setDate(newStart.getDate() + daysDelta);
    newEnd.setDate(newEnd.getDate() + daysDelta);
  } else if (mode === "resize-start") {
    newStart.setDate(newStart.getDate() + daysDelta);
    // Clamp: allow same-day but prevent crossing
    if (newStart > newEnd) newStart.setTime(newEnd.getTime());
  } else {
    // resize-end
    newEnd.setDate(newEnd.getDate() + daysDelta);
    // Clamp: allow same-day but prevent crossing
    if (newEnd < newStart) newEnd.setTime(newStart.getTime());
  }

  return { start: newStart, end: newEnd };
}
