import { pixelsToDays } from "~/components/timeline/dragMath.js";

type RangeStateLike = {
  isSelecting: boolean;
  resourceId: string | null;
  startDate: Date | null;
  currentDate: Date | null;
  suggestedProjectId: string | null;
  startClientX: number;
};

export type RangeSelectionResult = {
  resourceId: string;
  startDate: Date;
  endDate: Date;
  suggestedProjectId: string | null;
  anchorX: number;
  anchorY: number;
};

export function createRangeSelectionState<TState extends RangeStateLike>(
  resourceId: string,
  startDate: Date,
  startClientX: number,
  suggestedProjectId?: string | null,
): TState {
  return {
    isSelecting: true,
    resourceId,
    startDate,
    currentDate: startDate,
    suggestedProjectId: suggestedProjectId ?? null,
    startClientX,
  } as TState;
}

export function updateRangeSelectionDraft<TState extends RangeStateLike>(
  state: TState,
  currentClientX: number,
  cellWidth: number,
): TState | null {
  if (!state.isSelecting || !state.startDate) return null;

  const daysDelta = pixelsToDays(currentClientX - state.startClientX, cellWidth);
  const currentDate = new Date(state.startDate);
  currentDate.setDate(currentDate.getDate() + daysDelta);

  const prevDelta = state.currentDate
    ? Math.round((state.currentDate.getTime() - state.startDate.getTime()) / 86400000)
    : 0;
  if (daysDelta === prevDelta) return null;

  return {
    ...state,
    currentDate,
  };
}

export function finalizeRangeSelection<TState extends RangeStateLike>(
  state: TState,
  anchorX: number,
  anchorY: number,
): RangeSelectionResult | null {
  if (!state.isSelecting || !state.resourceId || !state.startDate) {
    return null;
  }

  const endDate = state.currentDate ?? state.startDate;
  const [startDate, finalEnd] =
    state.startDate <= endDate ? [state.startDate, endDate] : [endDate, state.startDate];

  return {
    resourceId: state.resourceId,
    startDate,
    endDate: finalEnd,
    suggestedProjectId: state.suggestedProjectId,
    anchorX,
    anchorY,
  };
}
