import {
  describe,
  expect,
  it
} from 'vitest';

import { portalHostElementToBody } from './portal-host-to-body.logic';

interface MockElement {
  parentElement: MockElement | null;
  children: MockElement[];
  appendChild(child: MockElement): void;
}

function createMockElement(parent: MockElement | null = null): MockElement {
  const element: MockElement = {
    parentElement: parent,
    children: [],
    appendChild(child: MockElement): void {
      if (child.parentElement) {
        child.parentElement.children = child.parentElement.children.filter((entry) => entry !== child);
      }

      child.parentElement = this;
      this.children.push(child);
    }
  };

  parent?.appendChild(element);
  return element;
}

describe('portalHostElementToBody', () => {
  it('appends the host to document.body when it is nested elsewhere', () => {
    const body = createMockElement();
    const container = createMockElement(body);
    const host = createMockElement(container);

    expect(portalHostElementToBody(host as unknown as HTMLElement, body as unknown as HTMLElement)).toBe(true);
    expect(host.parentElement).toBe(body);
    expect(container.children).toEqual([]);
  });

  it('returns false when the host is already attached to document.body', () => {
    const body = createMockElement();
    const host = createMockElement(body);

    expect(portalHostElementToBody(host as unknown as HTMLElement, body as unknown as HTMLElement)).toBe(false);
    expect(host.parentElement).toBe(body);
  });
});
