/**
 * Player Events Service tests
 *
 * TRACES: UR-005, UR-019, UR-023, UR-026 | DR-001, DR-028, DR-047
 */

import { describe, it, expect, vi, beforeEach } from "vitest";
import { isPlayerEventsInitialized, cleanupPlayerEvents } from "./playerEvents";

// Mock Tauri
vi.mock("@tauri-apps/api/event", () => ({
  listen: vi.fn(async (event, handler) => {
    return () => {}; // Return unlisten function
  }),
}));

vi.mock("@tauri-apps/api/core", () => ({
  invoke: vi.fn(),
}));

// Mock stores
vi.mock("$lib/stores/player", () => ({
  player: {
    updatePosition: vi.fn(),
    setPlaying: vi.fn(),
    setPaused: vi.fn(),
    setLoading: vi.fn(),
    setIdle: vi.fn(),
    setError: vi.fn(),
    setVolume: vi.fn(),
    setMuted: vi.fn(),
  },
  playbackPosition: { subscribe: vi.fn() },
}));

vi.mock("$lib/stores/queue", () => ({
  queue: { subscribe: vi.fn() },
  currentQueueItem: { subscribe: vi.fn() },
}));

vi.mock("$lib/stores/playbackMode", () => ({
  playbackMode: { setMode: vi.fn(), initializeSessionMonitoring: vi.fn() },
}));

vi.mock("$lib/stores/sleepTimer", () => ({
  sleepTimer: { set: vi.fn() },
}));

vi.mock("$lib/stores/nextEpisode", () => ({
  nextEpisode: {
    showPopup: vi.fn(),
    updateCountdown: vi.fn(),
  },
}));

vi.mock("$lib/services/preload", () => ({
  preloadUpcomingTracks: vi.fn(),
}));

describe("Player Events Service", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("should initialize player event listener", async () => {
    const { initPlayerEvents } = await import("./playerEvents");
    await initPlayerEvents();

    expect(isPlayerEventsInitialized()).toBe(true);
  });

  it("should prevent duplicate initialization", async () => {
    const { initPlayerEvents } = await import("./playerEvents");

    await initPlayerEvents();
    const consoleSpy = vi.spyOn(console, "warn");

    await initPlayerEvents();

    expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("already initialized"));
  });

  it("should cleanup event listeners", async () => {
    const { initPlayerEvents } = await import("./playerEvents");

    await initPlayerEvents();
    expect(isPlayerEventsInitialized()).toBe(true);

    cleanupPlayerEvents();
    expect(isPlayerEventsInitialized()).toBe(false);
  });

  it("should handle player event initialization errors", async () => {
    const { listen } = await import("@tauri-apps/api/event");
    (listen as any).mockRejectedValueOnce(new Error("Event setup failed"));

    const { initPlayerEvents } = await import("./playerEvents");
    const consoleSpy = vi.spyOn(console, "error");

    await initPlayerEvents();

    // console.error is called with: ("Failed to initialize player events:", Error)
    expect(consoleSpy).toHaveBeenCalledWith(
      expect.stringContaining("Failed to initialize player events"),
      expect.any(Error)
    );
  });
});
