import { describe, expect, it } from "vitest";
import { resolveAllocationDragPosition, resolveProjectDragPosition } from "./timelineDragPosition.js";

describe("timelineDragPosition", () => {
  it("ignores project drags that are inactive or missing their original dates", () => {
    expect(
      resolveProjectDragPosition(
        {
          isDragging: false,
          originalStartDate: new Date("2026-01-10"),
          originalEndDate: new Date("2026-01-12"),
          currentStartDate: null,
          currentEndDate: null,
          startMouseX: 100,
          pointerDeltaX: 0,
          daysDelta: 0,
        },
        180,
        40,
      ),
    ).toEqual({ handled: false });

    expect(
      resolveProjectDragPosition(
        {
          isDragging: true,
          originalStartDate: null,
          originalEndDate: new Date("2026-01-12"),
          currentStartDate: null,
          currentEndDate: null,
          startMouseX: 100,
          pointerDeltaX: 0,
          daysDelta: 0,
        },
        180,
        40,
      ),
    ).toEqual({ handled: false });
  });

  it("updates only the pointer delta when the rounded day delta does not change", () => {
    const result = resolveProjectDragPosition(
      {
        isDragging: true,
        originalStartDate: new Date("2026-01-10"),
        originalEndDate: new Date("2026-01-12"),
        currentStartDate: null,
        currentEndDate: null,
        startMouseX: 100,
        pointerDeltaX: 0,
        daysDelta: 0,
      },
      118,
      40,
    );

    expect(result).toMatchObject({
      handled: true,
      pointerDeltaX: 18,
      daysDelta: 0,
      shouldSyncState: false,
      nextState: {
        pointerDeltaX: 18,
        daysDelta: 0,
        currentStartDate: null,
        currentEndDate: null,
      },
    });
  });

  it("recomputes project dates once the drag crosses into a different day bucket", () => {
    const result = resolveProjectDragPosition(
      {
        isDragging: true,
        originalStartDate: new Date("2026-01-10"),
        originalEndDate: new Date("2026-01-12"),
        currentStartDate: null,
        currentEndDate: null,
        startMouseX: 100,
        pointerDeltaX: 0,
        daysDelta: 0,
      },
      195,
      40,
    );

    expect(result).toMatchObject({
      handled: true,
      pointerDeltaX: 95,
      daysDelta: 2,
      shouldSyncState: true,
      nextState: {
        currentStartDate: new Date("2026-01-12"),
        currentEndDate: new Date("2026-01-14"),
        pointerDeltaX: 95,
        daysDelta: 2,
      },
    });
  });

  it("clamps allocation resize-end drags so the end date does not cross the start date", () => {
    const result = resolveAllocationDragPosition(
      {
        isActive: true,
        mode: "resize-end",
        originalStartDate: new Date("2026-01-10"),
        originalEndDate: new Date("2026-01-12"),
        currentStartDate: null,
        currentEndDate: null,
        startMouseX: 100,
        pointerDeltaX: 0,
        daysDelta: 0,
      },
      -10,
      40,
    );

    expect(result).toMatchObject({
      handled: true,
      pointerDeltaX: -110,
      daysDelta: -3,
      shouldSyncState: true,
      nextState: {
        currentStartDate: new Date("2026-01-10"),
        currentEndDate: new Date("2026-01-10"),
        pointerDeltaX: -110,
        daysDelta: -3,
      },
    });
  });
});
