import { describe, expect, it } from "vitest";
import { resolveRangeSelectionCancel, resolveRangeSelectionRelease } from "./timelineRangeRelease.js";

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

const INITIAL_RANGE_STATE: TestRangeState = {
  isSelecting: false,
  resourceId: null,
  startDate: null,
  currentDate: null,
  suggestedProjectId: null,
  startClientX: 0,
};

describe("timelineRangeRelease", () => {
  it("keeps state unchanged when release happens outside an active range selection", () => {
    const result = resolveRangeSelectionRelease(INITIAL_RANGE_STATE, 12, 34, INITIAL_RANGE_STATE);

    expect(result).toEqual({
      kind: "noop",
      nextState: INITIAL_RANGE_STATE,
      selection: null,
    });
  });

  it("keeps state unchanged when the active range is structurally invalid on release", () => {
    const invalidState: TestRangeState = {
      ...INITIAL_RANGE_STATE,
      isSelecting: true,
      resourceId: null,
      startDate: new Date("2026-04-01T00:00:00.000Z"),
      currentDate: new Date("2026-04-03T00:00:00.000Z"),
    };

    const result = resolveRangeSelectionRelease(invalidState, 40, 50, INITIAL_RANGE_STATE);

    expect(result).toEqual({
      kind: "noop",
      nextState: invalidState,
      selection: null,
    });
  });

  it("resets to the provided initial state when release completes a backwards drag", () => {
    const selectingState: TestRangeState = {
      isSelecting: true,
      resourceId: "res_1",
      startDate: new Date("2026-04-05T00:00:00.000Z"),
      currentDate: new Date("2026-04-02T00:00:00.000Z"),
      suggestedProjectId: "proj_1",
      startClientX: 120,
    };

    const result = resolveRangeSelectionRelease(selectingState, 200, 300, INITIAL_RANGE_STATE);

    expect(result).toEqual({
      kind: "complete",
      nextState: INITIAL_RANGE_STATE,
      selection: {
        resourceId: "res_1",
        startDate: new Date("2026-04-02T00:00:00.000Z"),
        endDate: new Date("2026-04-05T00:00:00.000Z"),
        suggestedProjectId: "proj_1",
        anchorX: 200,
        anchorY: 300,
      },
    });
  });

  it("does not reset on cancel when there is no active range selection", () => {
    const result = resolveRangeSelectionCancel(INITIAL_RANGE_STATE, INITIAL_RANGE_STATE);

    expect(result).toEqual({
      didReset: false,
      nextState: INITIAL_RANGE_STATE,
    });
  });

  it("resets on cancel when a range selection is active", () => {
    const selectingState: TestRangeState = {
      isSelecting: true,
      resourceId: "res_1",
      startDate: new Date("2026-04-01T00:00:00.000Z"),
      currentDate: new Date("2026-04-03T00:00:00.000Z"),
      suggestedProjectId: null,
      startClientX: 100,
    };

    const result = resolveRangeSelectionCancel(selectingState, INITIAL_RANGE_STATE);

    expect(result).toEqual({
      didReset: true,
      nextState: INITIAL_RANGE_STATE,
    });
  });
});
