/**
 * Tests for src/modules/algorithms/algo.followUpScheduler.ts
 *
 * Pure function — no mocking needed.
 */

import { describe, test, expect } from "bun:test";
import { scheduleFollowUp } from "../../src/modules/algorithms/algo.followUpScheduler";

describe("scheduleFollowUp", () => {
  test("returns dueDate and dueDateIso", () => {
    const result = scheduleFollowUp({
      triggeredByUserId: "user-1",
      now: new Date("2026-03-02T14:00:00Z"), // Monday
    });
    expect(result.dueDate).toBeInstanceOf(Date);
    expect(typeof result.dueDateIso).toBe("string");
  });

  test("schedules for next day at 10 AM on a weekday (Mon → Tue)", () => {
    // Monday March 2, 2026
    const result = scheduleFollowUp({
      triggeredByUserId: "user-1",
      now: new Date("2026-03-02T14:00:00Z"),
    });
    // Should be Tuesday March 3, 2026 at 10:00 AM local
    expect(result.dueDate.getDate()).toBe(3);
    expect(result.dueDate.getHours()).toBe(10);
    expect(result.dueDate.getMinutes()).toBe(0);
    expect(result.dueDate.getSeconds()).toBe(0);
  });

  test("Friday → Monday (skips weekend)", () => {
    // Friday March 6, 2026
    const result = scheduleFollowUp({
      triggeredByUserId: "user-1",
      now: new Date("2026-03-06T14:00:00Z"),
    });
    // Next day is Saturday (day 6), should skip to Monday
    // March 6 (Fri) +1 = March 7 (Sat) → +2 → March 9 (Mon)
    expect(result.dueDate.getDay()).toBe(1); // Monday
    expect(result.dueDate.getHours()).toBe(10);
  });

  test("Saturday → Monday", () => {
    // Saturday March 7, 2026
    const result = scheduleFollowUp({
      triggeredByUserId: "user-1",
      now: new Date("2026-03-07T14:00:00Z"),
    });
    // +1 = Sunday (day 0) → +1 → Monday
    expect(result.dueDate.getDay()).toBe(1); // Monday
    expect(result.dueDate.getHours()).toBe(10);
  });

  test("defaults to current time when now is not provided", () => {
    const result = scheduleFollowUp({ triggeredByUserId: "user-1" });
    expect(result.dueDate).toBeInstanceOf(Date);
    // Due date should be in the future
    expect(result.dueDate.getTime()).toBeGreaterThan(Date.now() - 1000);
  });

  test("dueDate always has time set to 10:00:00.000", () => {
    // Test across several days of the week
    for (let d = 1; d <= 7; d++) {
      const result = scheduleFollowUp({
        triggeredByUserId: "user-1",
        now: new Date(`2026-03-0${d}T08:00:00Z`),
      });
      expect(result.dueDate.getHours()).toBe(10);
      expect(result.dueDate.getMinutes()).toBe(0);
      expect(result.dueDate.getSeconds()).toBe(0);
      expect(result.dueDate.getMilliseconds()).toBe(0);
    }
  });

  test("dueDateIso is a valid ISO string of the dueDate", () => {
    const result = scheduleFollowUp({
      triggeredByUserId: "user-1",
      now: new Date("2026-03-02T14:00:00Z"),
    });
    expect(new Date(result.dueDateIso).getTime()).toBe(
      result.dueDate.getTime(),
    );
  });
});
