import ListHref from "../../href/ListHref";
import Href from "../../href/Href";
import FilterCollection from "../../filters/FilterCollection";

import ListModel from "../ListModel";

import mockList from "./list.json";
import mockListContributions from "./listContributions.json";

import testData from "./related-data.json";
import testContributions from "./related-contributions.json";
import ModularUIResponse from "../../../modularui/ModularUIResponse";

describe("listModel spec", () => {
  it("should be able to create an empty list", () => {
    const list = new ListModel();

    expect(list).toBeInstanceOf(ListModel);

    expect(list.selfhref).toBeInstanceOf(ListHref);
    expect(list.key).toBe("unknown");

    expect(list.listItemCollection.all).toStrictEqual([]);
    expect(list.filterCollection).toBeInstanceOf(FilterCollection);

    expect(list.listItemCollection.isEmpty).toBeTruthy();

    expect(list.headers).toHaveLength(0);

    expect(list.introtext).toBe("");
  });

  it("should be able to create a list from a typical modular ui response", () => {
    const list = new ListModel({
      request: {
        href: new Href("/Books"),
      },
      key: "Books",
      data: mockList.Books,
      contributions: mockListContributions.Books,
    });

    expect(list).toBeInstanceOf(ListModel);

    const selfLink = new ListHref("/books/books", list);

    selfLink.page = 1;
    selfLink.pagesize = 50;

    expect(list.selfhref.href).toStrictEqual(selfLink.href);
    expect(list.key).toBe("Books");

    expect(list.listItemCollection).toHaveLength(32);

    expect(list.listItemCollection.hasItems).toBeTruthy();

    expect(list.headers).toHaveLength(6);

    expect(list.introtext).toBe("<p>This is introtext</p>");
  });

  it("should be able to handle different kind of introtext", () => {
    const listOldStructure = new ListModel({
      key: "Books",
      data: mockList.Books,
      contributions: mockListContributions.Books,
    });

    expect(listOldStructure.introtext).toBe("<p>This is introtext</p>");

    const listFromDataPlain = new ListModel({
      key: "Books",
      data: {
        content: { text: { message: "<p>This is introtext</p>" } },
        ...mockList.Books,
      },
      contributions: mockListContributions.Books,
    });

    expect(listFromDataPlain.introtext).toBe("<p>This is introtext</p>");

    const listFromDataApplicationMessage = new ListModel({
      key: "Books",
      data: {
        ...mockList.Books,
        content: {
          text: {
            message: "<p>This is introtext</p>",
          },
        },
      },
      contributions: mockListContributions.Books,
    });

    expect(listFromDataApplicationMessage.introtext).toBe(
      "<p>This is introtext</p>",
    );

    const listFromNewContributionsRawTextMessage = new ListModel({
      key: "Books",
      data: mockList.Books,
      contributions: {
        ...mockListContributions.Books,
        text: {
          message: "<p>This is introtext</p>",
        },
      },
    });

    expect(listFromNewContributionsRawTextMessage.introtext).toBe(
      "<p>This is introtext</p>",
    );

    const listFromNewContributionsSimpleMessage = new ListModel({
      key: "Books",
      data: mockList.Books,
      contributions: {
        ...mockListContributions.Books,
        text: "<p>This is introtext</p>",
      },
    });

    expect(listFromNewContributionsSimpleMessage.introtext).toBe(
      "<p>This is introtext</p>",
    );
  });

  it("list model is applicable for contributions with resourcetype RecordRelatedDataStorePanel", () => {
    const data = ModularUIResponse.create({
      key: "Bewijsstukken",
      data: testData,
      contributions: testContributions,
    });

    expect(ListModel.isApplicableModel(data)).toBe(true);
  });

  it("can retrieve the label of an additional detail list", () => {
    const list = new ListModel({
      request: {
        href: new Href("/Books"),
      },
      key: "Books",
      data: mockList.Books,
      contributions: mockListContributions.Books,
    });

    expect(list.getAdditionalDetailLabel("list-related-cases")).toBe(
      "Contributors",
    );
  });
});
