import { describe, it, expect, beforeEach, vi } from "vitest";
import { popupRouter } from "./popup.ts";
import * as popupService from "../services/popupNotificationService.ts";

// Mock the popup service
vi.mock("../services/popupNotificationService", () => ({
  getActivePopups: vi.fn(),
  recordPopupView: vi.fn(),
  getPopupAnalytics: vi.fn(),
  createPopup: vi.fn(),
  deletePopup: vi.fn(),
  updatePopup: vi.fn(),
}));

describe("popupRouter", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("should have getActive procedure", () => {
    expect(popupRouter._def.procedures.getActive).toBeDefined();
  });

  it("should have recordView procedure", () => {
    expect(popupRouter._def.procedures.recordView).toBeDefined();
  });

  it("should have getAnalytics procedure", () => {
    expect(popupRouter._def.procedures.getAnalytics).toBeDefined();
  });

  it("should have create procedure", () => {
    expect(popupRouter._def.procedures.create).toBeDefined();
  });

  it("should have update procedure", () => {
    expect(popupRouter._def.procedures.update).toBeDefined();
  });

  it("should have delete procedure", () => {
    expect(popupRouter._def.procedures.delete).toBeDefined();
  });

  it("getActive should call popupService.getActivePopups", async () => {
    const mockPopups = [
      {
        id: 1,
        title: "Test Popup",
        description: "Test",
        type: "game_release" as const,
        ctaText: "Click",
        ctaLink: "/test",
        targetSegments: ["all"],
        startDate: new Date(),
        endDate: new Date(),
        priority: "high" as const,
        dismissible: true,
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    ];

    vi.mocked(popupService.getActivePopups).mockResolvedValue(mockPopups);

    // Verify the mock works
    const result = await popupService.getActivePopups(1);
    expect(result).toEqual(mockPopups);
    expect(popupService.getActivePopups).toHaveBeenCalledWith(1);
  });

  it("recordView should call popupService.recordPopupView", async () => {
    vi.mocked(popupService.recordPopupView).mockResolvedValue({ success: true });

    const result = await popupService.recordPopupView(1, 1, "viewed");
    expect(result).toEqual({ success: true });
    expect(popupService.recordPopupView).toHaveBeenCalledWith(1, 1, "viewed");
  });

  it("getPopupAnalytics should return analytics data", async () => {
    const mockAnalytics = {
      views: 1000,
      dismissals: 200,
      clicks: 150,
      ctr: 15,
    };

    vi.mocked(popupService.getPopupAnalytics).mockResolvedValue(mockAnalytics);

    const result = await popupService.getPopupAnalytics(1);
    expect(result).toEqual(mockAnalytics);
    expect(popupService.getPopupAnalytics).toHaveBeenCalledWith(1);
  });

  it("createPopup should return success", async () => {
    const mockResult = { success: true, popupId: 1 };
    vi.mocked(popupService.createPopup).mockResolvedValue(mockResult);

    const result = await popupService.createPopup({
      title: "Test",
      description: "Test",
      type: "game_release",
      ctaText: "Click",
      ctaLink: "/test",
      targetSegments: ["all"],
      startDate: new Date(),
      endDate: new Date(),
      priority: "high",
      dismissible: true,
    });

    expect(result).toEqual(mockResult);
  });

  it("deletePopup should return success", async () => {
    const mockResult = { success: true };
    vi.mocked(popupService.deletePopup).mockResolvedValue(mockResult);

    const result = await popupService.deletePopup(1);
    expect(result).toEqual(mockResult);
    expect(popupService.deletePopup).toHaveBeenCalledWith(1);
  });

  it("updatePopup should return success", async () => {
    const mockResult = { success: true };
    vi.mocked(popupService.updatePopup).mockResolvedValue(mockResult);

    const result = await popupService.updatePopup(1, { title: "Updated" });
    expect(result).toEqual(mockResult);
    expect(popupService.updatePopup).toHaveBeenCalledWith(1, { title: "Updated" });
  });
});
