import { describe, expect, it } from "vitest";
import { TRPCError } from "@trpc/server";
import {
  assertCommentManageableByActor,
  buildCommentCreateData,
  buildCommentMentionNotifications,
  commentAuthorSelect,
  commentBelongsToEntity,
  commentThreadInclude,
  commentWithAuthorInclude,
  parseCommentMentions,
} from "../router/comment-support.js";

describe("comment support", () => {
  it("parses unique mention ids from comment markdown", () => {
    expect(parseCommentMentions("Hi @[Alice](user_1) and @[Bob](user_2) and @[Alice](user_1)")).toEqual([
      "user_1",
      "user_2",
    ]);
  });

  it("exposes stable include definitions for comment reads and writes", () => {
    expect(commentAuthorSelect).toEqual({
      id: true,
      name: true,
      email: true,
      image: true,
    });

    expect(commentWithAuthorInclude).toEqual({
      author: { select: commentAuthorSelect },
    });

    expect(commentThreadInclude).toEqual({
      author: { select: commentAuthorSelect },
      replies: {
        include: {
          author: { select: commentAuthorSelect },
        },
        orderBy: { createdAt: "asc" },
      },
    });
  });

  it("builds comment create payloads and mention notifications", () => {
    expect(buildCommentCreateData({
      entityType: "estimate",
      entityId: "est_1",
      parentId: "comment_parent",
      authorId: "user_1",
      body: "Please review @[Bob](user_2)",
      mentions: ["user_2"],
    })).toEqual({
      entityType: "estimate",
      entityId: "est_1",
      parentId: "comment_parent",
      authorId: "user_1",
      body: "Please review @[Bob](user_2)",
      mentions: ["user_2"],
    });

    expect(buildCommentMentionNotifications({
      mentionedUserIds: ["user_2"],
      authorName: "Alice Example",
      body: "x".repeat(121),
      entityId: "est_1",
      entityType: "estimate",
      senderId: "user_1",
      link: "/estimates/est_1",
    })).toEqual([
      {
        userId: "user_2",
        type: "COMMENT_MENTION",
        title: "Alice Example mentioned you in a comment",
        body: `${"x".repeat(120)}...`,
        entityId: "est_1",
        entityType: "estimate",
        senderId: "user_1",
        link: "/estimates/est_1",
        channel: "in_app",
      },
    ]);
  });

  it("checks entity ownership and author-or-admin permissions", () => {
    expect(commentBelongsToEntity({
      comment: {
        entityType: "resource",
        entityId: "res_1",
      },
      entityType: "resource",
      entityId: "res_1",
    })).toBe(true);

    expect(() => assertCommentManageableByActor({
      authorId: "user_2",
      actorUserId: "user_1",
      isAdmin: false,
      action: "delete",
    })).toThrowError(TRPCError);

    expect(() => assertCommentManageableByActor({
      authorId: "user_2",
      actorUserId: "user_1",
      isAdmin: true,
      action: "resolve",
    })).not.toThrow();
  });
});
