/**
 * Skip-to-next-episode reporting tests.
 *
 * Regression: pressing "skip to next episode" left the outgoing episode with a
 * mid-episode resume position, so it showed a partial progress bar and offered
 * to resume. A manual skip means the user is done with that episode — it must
 * be recorded as fully watched.
 *
 * TRACES: UR-059, UR-025 | DR-088
 */

import { describe, it, expect, beforeEach, vi } from "vitest";

const markAsPlayed = vi.fn(async (_itemId: string) => undefined);
const reportPlaybackStopped = vi.fn(
  async (_itemId: string, _positionSeconds: number) => undefined
);

vi.mock("./playbackReporting", () => ({
  markAsPlayed: (itemId: string) => markAsPlayed(itemId),
  reportPlaybackStopped: (itemId: string, positionSeconds: number) =>
    reportPlaybackStopped(itemId, positionSeconds),
}));

import {
  shouldSuppressStopReport,
  markSkipped,
  reportSkippedEpisode,
  resetSkipState,
} from "./skipReporting";

describe("skip reporting", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    resetSkipState();
  });

  describe("reportSkippedEpisode", () => {
    it("marks the skipped episode as fully played", async () => {
      await reportSkippedEpisode("ep-1");

      expect(markAsPlayed).toHaveBeenCalledWith("ep-1");
    });

    it("does not stamp the mid-episode position as a resume point", async () => {
      await reportSkippedEpisode("ep-1");

      expect(reportPlaybackStopped).not.toHaveBeenCalled();
    });

    it("ignores a null item id", async () => {
      await reportSkippedEpisode(null);

      expect(markAsPlayed).not.toHaveBeenCalled();
    });
  });

  describe("shouldSuppressStopReport", () => {
    it("suppresses the unmount stop report for the skipped episode", async () => {
      await reportSkippedEpisode("ep-1");

      // VideoPlayer.onDestroy fires after navigation with the mid-episode time.
      expect(shouldSuppressStopReport("ep-1")).toBe(true);
    });

    it("only suppresses the episode that was actually skipped", async () => {
      await reportSkippedEpisode("ep-1");

      expect(shouldSuppressStopReport("ep-2")).toBe(false);
    });

    it("suppresses only once, so a later real stop still reports", async () => {
      await reportSkippedEpisode("ep-1");

      expect(shouldSuppressStopReport("ep-1")).toBe(true);
      expect(shouldSuppressStopReport("ep-1")).toBe(false);
    });

    it("does not suppress when nothing was skipped", () => {
      expect(shouldSuppressStopReport("ep-1")).toBe(false);
    });

    it("does not suppress a null item id", () => {
      markSkipped("ep-1");
      expect(shouldSuppressStopReport(null)).toBe(false);
    });
  });
});
