/**
 * Unit tests for getDutyMarkerRows (time prefix and order).
 * Ported from webapp/js/hints.test.js.
 */

import { describe, it, expect } from "vitest";
import { getDutyMarkerRows } from "./duty-marker-rows";
import type { DutyWithUser } from "@/types";

const FROM = "from";
const TO = "until";
const SEP = "\u00a0";

function duty(
  full_name: string,
  start_at: string,
  end_at: string
): DutyWithUser {
  return {
    id: 1,
    user_id: 1,
    full_name,
    start_at,
    end_at,
    event_type: "duty",
    phone: null,
    username: null,
  };
}

describe("getDutyMarkerRows", () => {
  it("preserves input order (caller must sort by start_at before passing)", () => {
    const hintDay = "2025-02-25";
    const duties = [
      duty("Иванов", "2025-02-25T14:00:00", "2025-02-25T18:00:00"),
      duty("Петров", "2025-02-25T09:00:00", "2025-02-25T14:00:00"),
    ];
    const rows = getDutyMarkerRows(duties, hintDay, SEP, FROM, TO);
    expect(rows).toHaveLength(2);
    expect(rows[0].fullName).toBe("Иванов");
    expect(rows[1].fullName).toBe("Петров");
  });

  it("first of multiple with startSameDay shows full range (from HH:MM to HH:MM)", () => {
    const hintDay = "2025-02-25";
    const duties = [
      duty("Иванов", "2025-02-25T09:00:00", "2025-02-25T14:00:00"),
      duty("Петров", "2025-02-25T14:00:00", "2025-02-25T18:00:00"),
    ].sort(
      (a, b) =>
        new Date(a.start_at).getTime() - new Date(b.start_at).getTime()
    );
    const rows = getDutyMarkerRows(duties, hintDay, SEP, FROM, TO);
    expect(rows).toHaveLength(2);
    expect(rows[0].fullName).toBe("Иванов");
    expect(rows[0].timePrefix).toContain("09:00");
    expect(rows[0].timePrefix).toContain("14:00");
    expect(rows[0].timePrefix).toContain(FROM);
    expect(rows[0].timePrefix).toContain(TO);
  });

  it("first of multiple continuation from previous day shows only end time", () => {
    const hintDay = "2025-02-25";
    const duties = [
      duty("Иванов", "2025-02-24T22:00:00", "2025-02-25T06:00:00"),
      duty("Петров", "2025-02-25T09:00:00", "2025-02-25T14:00:00"),
    ].sort(
      (a, b) =>
        new Date(a.start_at).getTime() - new Date(b.start_at).getTime()
    );
    const rows = getDutyMarkerRows(duties, hintDay, SEP, FROM, TO);
    expect(rows).toHaveLength(2);
    expect(rows[0].fullName).toBe("Иванов");
    expect(rows[0].timePrefix).not.toContain(FROM);
    expect(rows[0].timePrefix).toContain(TO);
    expect(rows[0].timePrefix).toContain("06:00");
  });

  it("second duty continuation from previous day shows only end time (to HH:MM)", () => {
    const hintDay = "2025-02-23";
    const duties = [
      duty("A", "2025-02-23T00:00:00", "2025-02-23T09:00:00"),
      duty("B", "2025-02-22T09:00:00", "2025-02-23T09:00:00"),
    ];
    const rows = getDutyMarkerRows(duties, hintDay, SEP, FROM, TO);
    expect(rows).toHaveLength(2);
    expect(rows[0].fullName).toBe("A");
    expect(rows[0].timePrefix).toContain(FROM);
    expect(rows[0].timePrefix).toContain("00:00");
    expect(rows[0].timePrefix).toContain(TO);
    expect(rows[0].timePrefix).toContain("09:00");
    expect(rows[1].fullName).toBe("B");
    expect(rows[1].timePrefix).not.toContain(FROM);
    expect(rows[1].timePrefix).toContain(TO);
    expect(rows[1].timePrefix).toContain("09:00");
  });

  it("multiple duties in one day — correct order when input is pre-sorted", () => {
    const hintDay = "2025-02-25";
    const duties = [
      duty("A", "2025-02-25T09:00:00", "2025-02-25T12:00:00"),
      duty("B", "2025-02-25T12:00:00", "2025-02-25T15:00:00"),
      duty("C", "2025-02-25T15:00:00", "2025-02-25T18:00:00"),
    ].sort(
      (a, b) =>
        new Date(a.start_at).getTime() - new Date(b.start_at).getTime()
    );
    const rows = getDutyMarkerRows(duties, hintDay, SEP, FROM, TO);
    expect(rows.map((r) => r.fullName)).toEqual(["A", "B", "C"]);
    expect(rows[0].timePrefix).toContain("09:00");
    expect(rows[1].timePrefix).toContain("12:00");
    expect(rows[2].timePrefix).toContain("15:00");
  });
});
