import { describe, it, expect, beforeEach, vi } from "vitest";
import { Test, TestingModule } from "@nestjs/testing";
import type { AuthUser, AuthSession } from "@mosaic/shared";
import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";

describe("AuthController", () => {
  let controller: AuthController;
  let authService: AuthService;

  const mockAuthService = {
    getAuth: vi.fn(),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [AuthController],
      providers: [
        {
          provide: AuthService,
          useValue: mockAuthService,
        },
      ],
    }).compile();

    controller = module.get<AuthController>(AuthController);
    authService = module.get<AuthService>(AuthService);

    vi.clearAllMocks();
  });

  describe("handleAuth", () => {
    it("should call BetterAuth handler", async () => {
      const mockHandler = vi.fn().mockResolvedValue({ status: 200 });
      mockAuthService.getAuth.mockReturnValue({ handler: mockHandler });

      const mockRequest = {
        method: "GET",
        url: "/auth/session",
      };

      await controller.handleAuth(mockRequest as unknown as Request);

      expect(mockAuthService.getAuth).toHaveBeenCalled();
      expect(mockHandler).toHaveBeenCalledWith(mockRequest);
    });
  });

  describe("getSession", () => {
    it("should return user and session data", () => {
      const mockUser: AuthUser = {
        id: "user-123",
        email: "test@example.com",
        name: "Test User",
        workspaceId: "workspace-123",
      };

      const mockSession = {
        id: "session-123",
        token: "session-token",
        expiresAt: new Date(Date.now() + 86400000),
      };

      const mockRequest = {
        user: mockUser,
        session: mockSession,
      };

      const result = controller.getSession(mockRequest);

      const expected: AuthSession = {
        user: mockUser,
        session: {
          id: mockSession.id,
          token: mockSession.token,
          expiresAt: mockSession.expiresAt,
        },
      };

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

    it("should throw error if user not found in request", () => {
      const mockRequest = {
        session: {
          id: "session-123",
          token: "session-token",
          expiresAt: new Date(),
        },
      };

      expect(() => controller.getSession(mockRequest)).toThrow("User session not found");
    });

    it("should throw error if session not found in request", () => {
      const mockRequest = {
        user: {
          id: "user-123",
          email: "test@example.com",
          name: "Test User",
        },
      };

      expect(() => controller.getSession(mockRequest)).toThrow("User session not found");
    });
  });

  describe("getProfile", () => {
    it("should return complete user profile with workspace fields", () => {
      const mockUser: AuthUser = {
        id: "user-123",
        email: "test@example.com",
        name: "Test User",
        image: "https://example.com/avatar.jpg",
        emailVerified: true,
        workspaceId: "workspace-123",
        currentWorkspaceId: "workspace-456",
        workspaceRole: "admin",
      };

      const result = controller.getProfile(mockUser);

      expect(result).toEqual({
        id: mockUser.id,
        email: mockUser.email,
        name: mockUser.name,
        image: mockUser.image,
        emailVerified: mockUser.emailVerified,
        workspaceId: mockUser.workspaceId,
        currentWorkspaceId: mockUser.currentWorkspaceId,
        workspaceRole: mockUser.workspaceRole,
      });
    });

    it("should return user profile with optional fields undefined", () => {
      const mockUser: AuthUser = {
        id: "user-123",
        email: "test@example.com",
        name: "Test User",
      };

      const result = controller.getProfile(mockUser);

      expect(result).toEqual({
        id: mockUser.id,
        email: mockUser.email,
        name: mockUser.name,
        image: undefined,
        emailVerified: undefined,
        workspaceId: undefined,
        currentWorkspaceId: undefined,
        workspaceRole: undefined,
      });
    });
  });
});
