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

import type { Like, CreateLikeDto, LikeResponse, LikedItemDto, LikeCountDto } from "../src/lib/like.types";

describe("like Types", () => {
  describe("like interface", () => {
    it("should accept valid like object for a book", () => {
      const bookLike: Like = {
        createdAt:  new Date("2024-01-15"),
        entityId:   "book456",
        entityType: "book",
        id:         "like123",
        userId:     "user123",
      };

      expect(bookLike.entityType).toBe("book");
      expect(bookLike.entityId).toBe("book456");
    });

    it("should accept valid like object for a game", () => {
      const gameLike: Like = {
        createdAt:  new Date("2024-01-20"),
        entityId:   "game123",
        entityType: "game",
        id:         "like456",
        userId:     "user789",
      };

      expect(gameLike.entityType).toBe("game");
      expect(gameLike.entityId).toBe("game123");
    });

    it("should accept likes for all entity types", () => {
      const showLike: Like = {
        createdAt:  new Date("2024-02-01"),
        entityId:   "show222",
        entityType: "show",
        id:         "like789",
        userId:     "user111",
      };

      const mangaLike: Like = {
        createdAt:  new Date("2024-02-05"),
        entityId:   "manga444",
        entityType: "manga",
        id:         "like999",
        userId:     "user333",
      };

      const musicLike: Like = {
        createdAt:  new Date("2024-02-10"),
        entityId:   "music666",
        entityType: "music",
        id:         "like111",
        userId:     "user555",
      };

      const artLike: Like = {
        createdAt:  new Date("2024-02-15"),
        entityId:   "art888",
        entityType: "art",
        id:         "like222",
        userId:     "user777",
      };

      expect(showLike.entityType).toBe("show");
      expect(mangaLike.entityType).toBe("manga");
      expect(musicLike.entityType).toBe("music");
      expect(artLike.entityType).toBe("art");
    });
  });

  describe("createLikeDto type", () => {
    it("should pick only entityType and entityId from Like", () => {
      const createDto: CreateLikeDto = {
        entityId:   "book123",
        entityType: "book",
      };

      expect(createDto.entityType).toBe("book");
      expect(createDto.entityId).toBe("book123");
      // Verify it only has these two properties
      expect(Object.keys(createDto)).toHaveLength(2);
    });

    it("should accept different entity types", () => {
      const gameDto: CreateLikeDto = {
        entityId:   "game456",
        entityType: "game",
      };

      const artDto: CreateLikeDto = {
        entityId:   "art789",
        entityType: "art",
      };

      expect(gameDto.entityType).toBe("game");
      expect(artDto.entityType).toBe("art");
    });
  });

  describe("likeCountDto interface", () => {
    it("should accept valid like count object", () => {
      const likeCount: LikeCountDto = {
        count:      42,
        entityId:   "book123",
        entityType: "book",
      };

      expect(likeCount.count).toBe(42);
      expect(likeCount.entityType).toBe("book");
    });

    it("should accept like counts for different entities", () => {
      const gameLikeCount: LikeCountDto = {
        count:      15,
        entityId:   "game456",
        entityType: "game",
      };

      const showLikeCount: LikeCountDto = {
        count:      0,
        entityId:   "show789",
        entityType: "show",
      };

      expect(gameLikeCount.count).toBe(15);
      expect(showLikeCount.count).toBe(0);
    });
  });

  describe("likedItemDto interface", () => {
    it("should accept liked item with unknown item type", () => {
      const likedBook: LikedItemDto = {
        item: {
          author: "F. Scott Fitzgerald",
          id:     "book456",
          title:  "The Great Gatsby",
          // ... other book properties
        },
        like: {
          createdAt:  new Date("2024-01-15"),
          entityId:   "book456",
          entityType: "book",
          id:         "like123",
          userId:     "user123",
        },
      };

      expect(likedBook.like.entityType).toBe("book");
      expect(likedBook.item).toBeDefined();
    });

    it("should accept liked items for different entity types", () => {
      const likedGame: LikedItemDto = {
        item: {
          id:       "game123",
          platform: "Nintendo Switch",
          title:    "Hades",
          // ... other game properties
        },
        like: {
          createdAt:  new Date("2024-02-01"),
          entityId:   "game123",
          entityType: "game",
          id:         "like456",
          userId:     "user789",
        },
      };

      const likedArt: LikedItemDto = {
        item: {
          artist:   "Jane Doe",
          id:       "art456",
          imageUrl: "https://example.com/sunset.jpg",
          title:    "Beautiful Sunset",
          // ... other art properties
        },
        like: {
          createdAt:  new Date("2024-02-10"),
          entityId:   "art456",
          entityType: "art",
          id:         "like789",
          userId:     "user999",
        },
      };

      expect(likedGame.like.entityType).toBe("game");
      expect(likedArt.like.entityType).toBe("art");
    });
  });

  describe("likeResponse interface", () => {
    it("should accept response with liked true", () => {
      const likedResponse: LikeResponse = {
        count: 10,
        liked: true,
      };

      expect(likedResponse.liked).toBeTruthy();
      expect(likedResponse.count).toBe(10);
    });

    it("should accept response with liked false", () => {
      const notLikedResponse: LikeResponse = {
        count: 5,
        liked: false,
      };

      expect(notLikedResponse.liked).toBeFalsy();
      expect(notLikedResponse.count).toBe(5);
    });

    it("should accept response with zero count", () => {
      const zeroResponse: LikeResponse = {
        count: 0,
        liked: false,
      };

      expect(zeroResponse.liked).toBeFalsy();
      expect(zeroResponse.count).toBe(0);
    });
  });
});
