/**
 * @copyright NHCarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */

import {
  AuditAction,
  AuditCategory,
  type AuditLog,
  type AuditLogFilters,
  type AuditLogUser,
} from "../src/lib/audit.types";

describe("audit Types", () => {
  describe("auditAction enum", () => {
    it("should have all expected action values", () => {
      expect(AuditAction.login).toBe("LOGIN");
      expect(AuditAction.logout).toBe("LOGOUT");
      expect(AuditAction.loginFailed).toBe("LOGIN_FAILED");
      expect(AuditAction.commentCreate).toBe("COMMENT_CREATE");
      expect(AuditAction.commentUpdate).toBe("COMMENT_UPDATE");
      expect(AuditAction.commentDelete).toBe("COMMENT_DELETE");
      expect(AuditAction.entryCreate).toBe("ENTRY_CREATE");
      expect(AuditAction.entryUpdate).toBe("ENTRY_UPDATE");
      expect(AuditAction.entryDelete).toBe("ENTRY_DELETE");
      expect(AuditAction.like).toBe("LIKE");
      expect(AuditAction.unlike).toBe("UNLIKE");
      expect(AuditAction.userBan).toBe("USER_BAN");
      expect(AuditAction.userUnban).toBe("USER_UNBAN");
      expect(AuditAction.rateLimitExceeded).toBe("RATE_LIMIT_EXCEEDED");
      expect(AuditAction.csrfValidationFailed).toBe("CSRF_VALIDATION_FAILED");
      expect(AuditAction.unauthorizedAccess).toBe("UNAUTHORIZED_ACCESS");
    });
  });

  describe("auditCategory enum", () => {
    it("should have all expected category values", () => {
      expect(AuditCategory.auth).toBe("AUTH");
      expect(AuditCategory.content).toBe("CONTENT");
      expect(AuditCategory.admin).toBe("ADMIN");
      expect(AuditCategory.security).toBe("SECURITY");
    });
  });

  describe("auditLogUser interface", () => {
    it("should accept valid user objects", () => {
      const userWithAvatar: AuditLogUser = {
        avatar:   "https://example.com/avatar.png",
        id:       "user123",
        username: "testuser",
      };

      const userWithoutAvatar: AuditLogUser = {
        id:       "user456",
        username: "anotheruser",
      };

      expect(userWithAvatar.avatar).toBe("https://example.com/avatar.png");
      expect(userWithoutAvatar.avatar).toBeUndefined();
    });
  });

  describe("auditLog interface", () => {
    it("should accept valid audit log with minimal fields", () => {
      const minimalLog: AuditLog = {
        action:    AuditAction.login,
        category:  AuditCategory.auth,
        createdAt: new Date(),
        id:        "log123",
        success:   true,
      };

      expect(minimalLog.userId).toBeUndefined();
      expect(minimalLog.details).toBeUndefined();
    });

    it("should accept valid audit log with all fields", () => {
      const fullLog: AuditLog = {
        action:       AuditAction.commentDelete,
        category:     AuditCategory.admin,
        createdAt:    new Date(),
        details:      "Admin deleted inappropriate comment",
        id:           "log456",
        resourceId:   "comment123",
        resourceType: "comment",
        success:      true,
        targetUser:   {
          id:       "user789",
          username: "targetuser",
        },
        targetUserId: "user789",
        user:         {
          avatar:   "https://example.com/avatar.png",
          id:       "user123",
          username: "admin",
        },
        userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        userId:    "user123",
      };

      expect(fullLog.user?.username).toBe("admin");
      expect(fullLog.targetUser?.username).toBe("targetuser");
    });
  });

  describe("auditLogFilters interface", () => {
    it("should accept empty filters", () => {
      const emptyFilters: AuditLogFilters = {};
      expect(emptyFilters).toEqual({});
    });

    it("should accept filters with all fields", () => {
      const fullFilters: AuditLogFilters = {
        action:    AuditAction.login,
        category:  AuditCategory.auth,
        endDate:   new Date("2024-12-31"),
        limit:     50,
        page:      1,
        startDate: new Date("2024-01-01"),
        success:   true,
        userId:    "user123",
      };

      expect(fullFilters.page).toBe(1);
      expect(fullFilters.limit).toBe(50);
    });
  });
});
