import { Attachment, Collection, EmbedBuilder } from "discord.js";
import { handleAttachments } from "../../../src/utils/events/citation";

import { describe, it } from "node:test";
import assert from "node:assert/strict";

/**
 * Generate a new random string
 * @returns random string
 */
const newKey = () => Math.random().toString(36).substring(2);

describe("Attachements Handler", () => {
  const map = new Map([
    ["e_attachements", "yes_s"],
    ["e_attachement", "no_s"],
  ]);
  // 102 is the maximum for [f](url) before rupture in a field
  const max = 102;
  const max_field = Array.from({ length: max }, () => "[f](url)").join(", ");
  {
    const name = "One image";
    it(name, () => {
      const embedExpected = new EmbedBuilder();
      embedExpected.setImage("http://url");

      const embedTest = new EmbedBuilder();
      handleAttachments(
        map,
        embedTest,
        new Collection([[newKey(), { name: "image.png", url: "http://url" } as Attachment]]),
      );

      assert.deepStrictEqual(embedTest, embedExpected);
    });
  }
  {
    const name = "Two images";
    it(name, () => {
      const embedExpected = new EmbedBuilder();
      embedExpected.addFields({
        name: "yes_s",
        value: "[image.png](http://url), [image.png](http://url)",
      });

      const embedTest = new EmbedBuilder();
      handleAttachments(
        map,
        embedTest,
        new Collection([
          [newKey(), { name: "image.png", url: "http://url" } as Attachment],
          [newKey(), { name: "image.png", url: "http://url" } as Attachment],
        ]),
      );

      assert.deepStrictEqual(embedTest, embedExpected);
    });
  }
  {
    const name = "One link";
    it(name, () => {
      const embedExpected = new EmbedBuilder();
      embedExpected.addFields({ name: "no_s", value: "[f](url)" });

      const embedTest = new EmbedBuilder();
      handleAttachments(
        map,
        embedTest,
        new Collection([[newKey(), { name: "f", url: "url" } as Attachment]]),
      );

      assert.deepStrictEqual(embedTest, embedExpected);
    });
  }
  {
    const name = "Two files";
    it(name, () => {
      const embedExpected = new EmbedBuilder();
      embedExpected.addFields({ name: "yes_s", value: "[f](url), [f](url)" });

      const embedTest = new EmbedBuilder();
      handleAttachments(
        map,
        embedTest,
        new Collection([
          [newKey(), { name: "f", url: "url" } as Attachment],
          [newKey(), { name: "f", url: "url" } as Attachment],
        ]),
      );

      assert.deepStrictEqual(embedTest, embedExpected);
    });
  }
  {
    const name = "Two fields with multiples files each";
    it(name, () => {
      const total = 150;

      const embedExpected = new EmbedBuilder();
      embedExpected.addFields(
        {
          name: "yes_s (1)",
          value: max_field,
        },
        {
          name: "yes_s (2)",
          value: Array.from({ length: total - max }, () => "[f](url)").join(", "),
        },
      );

      const embedTest = new EmbedBuilder();
      handleAttachments(
        map,
        embedTest,
        new Collection(
          Array.from({ length: total }, () => [newKey(), { name: "f", url: "url" } as Attachment]),
        ),
      );

      assert.deepStrictEqual(embedTest, embedExpected);
    });
  }
  {
    const name = "Two fields with one field with one element";
    it(name, () => {
      const total = 103;

      const embedExpected = new EmbedBuilder();
      embedExpected.addFields(
        {
          name: "yes_s (1)",
          value: max_field,
        },
        {
          name: "no_s (2)",
          value: Array.from({ length: total - max }, () => "[f](url)").join(", "),
        },
      );

      const embedTest = new EmbedBuilder();
      handleAttachments(
        map,
        embedTest,
        new Collection(
          Array.from({ length: total }, () => [newKey(), { name: "f", url: "url" } as Attachment]),
        ),
      );

      assert.deepStrictEqual(embedTest, embedExpected);
    });
  }
});