"use client";

export type TimelineVisualEntry = {
  id: string;
  startDate: Date | string;
  endDate: Date | string;
};

export type TimelineVisualOverride = {
  startDate: Date;
  endDate: Date;
};

export type TimelineVisualOverrides = ReadonlyMap<string, TimelineVisualOverride>;

export function getDragPointerOffset(
  pointerDeltaX: number,
  daysDelta: number,
  cellWidth: number,
): number {
  return pointerDeltaX - daysDelta * cellWidth;
}

export function applyPointerOffsetPreviewRect({
  left,
  width,
  mode,
  pointerOffsetX,
  minWidth,
}: {
  left: number;
  width: number;
  mode: "move" | "resize-start" | "resize-end";
  pointerOffsetX: number;
  minWidth: number;
}): { left: number; width: number; transform?: string } {
  if (pointerOffsetX === 0) {
    return { left, width };
  }

  if (mode === "move") {
    return { left, width, transform: `translateX(${pointerOffsetX}px)` };
  }

  if (mode === "resize-start") {
    const nextWidth = width - pointerOffsetX;
    if (nextWidth < minWidth) {
      return {
        left: left + (width - minWidth),
        width: minWidth,
      };
    }
    return {
      left: left + pointerOffsetX,
      width: nextWidth,
    };
  }

  return {
    left,
    width: Math.max(minWidth, width + pointerOffsetX),
  };
}

export function applyVisualOverrides<T extends TimelineVisualEntry>(
  entries: readonly T[],
  overrides: TimelineVisualOverrides,
): T[] {
  if (overrides.size === 0) {
    return entries as T[];
  }

  let changed = false;
  const nextEntries = entries.map((entry) => {
    const override = overrides.get(entry.id);
    if (!override) {
      return entry;
    }

    changed = true;
    return {
      ...entry,
      startDate: new Date(override.startDate),
      endDate: new Date(override.endDate),
    };
  });

  return changed ? nextEntries : (entries as T[]);
}
