import { render } from '@testing-library/react';
import { ReactNode } from 'react';
import { it, describe, expect } from 'vitest';
import { mergeParentLayoutScreen } from './mergeParentLayoutScreen';
import { Screen } from '..';
import { RouteScreen } from '../types/RouteScreen';

declare global {
  interface HTMLElement {
    innerHTML: string;
  }
}

function ItemLayout({ children }: { children: ReactNode }) {
  return <div id="item-layout">{children}</div>;
}

function RootLayout({ children }: { children: ReactNode }) {
  return <div id="root-layout">{children}</div>;
}

function SubItemLayout({ children }: { children: ReactNode }) {
  return <div id="sub-item-layout">{children}</div>;
}

describe('mergeParentLayoutScreen', () => {
  it('부모 레이아웃과 자식 레이아웃이 올바른 순서로 중첩되어야 합니다', () => {
    const map = new Map<string, RouteScreen>();

    map.set('./item/detail', {
      component: ItemLayout as Screen,
      path: './item/_layout',
    });

    map.set('./item/_layout', {
      component: RootLayout as Screen,
      path: './_layout',
    });

    const MergedLayout = mergeParentLayoutScreen(map, './item/detail');

    const { container } = render(<MergedLayout>item detail</MergedLayout>);

    // RootLayout > ItemLayout > content 순서로 중첩되어야 함
    expect(container.innerHTML).toBe(
      render(
        <div id="root-layout">
          <div id="item-layout">item detail</div>
        </div>
      ).container.innerHTML
    );
  });

  it('3중 중첩된 레이아웃이 올바른 순서로 렌더링되어야 합니다', () => {
    const map = new Map<string, RouteScreen>();

    map.set('./item/detail/sub', {
      component: SubItemLayout as Screen,
      path: './item/detail/_layout',
    });

    map.set('./item/detail/_layout', {
      component: ItemLayout as Screen,
      path: './item/_layout',
    });

    map.set('./item/_layout', {
      component: RootLayout as Screen,
      path: './_layout',
    });

    const MergedLayout = mergeParentLayoutScreen(map, './item/detail/sub');

    const { container } = render(<MergedLayout>sub item detail</MergedLayout>);

    // RootLayout > ItemLayout > SubItemLayout > content 순서로 중첩되어야 함
    expect(container.innerHTML).toBe(
      render(
        <div id="root-layout">
          <div id="item-layout">
            <div id="sub-item-layout">sub item detail</div>
          </div>
        </div>
      ).container.innerHTML
    );
  });

  it('단일 레이아웃이 올바르게 렌더링되어야 합니다', () => {
    const map = new Map<string, RouteScreen>();

    map.set('./item/detail', {
      component: RootLayout as Screen,
      path: './_layout',
    });

    const MergedLayout = mergeParentLayoutScreen(map, './item/detail');

    const { container } = render(<MergedLayout>item detail</MergedLayout>);

    expect(container.innerHTML).toBe(render(<div id="root-layout">item detail</div>).container.innerHTML);
  });

  it('레이아웃이 정의되지 않은 경우 컨텐츠만 렌더링되어야 합니다', () => {
    const map = new Map<string, RouteScreen>();

    const MergedLayout = mergeParentLayoutScreen(map, './item/detail');

    const { container } = render(<MergedLayout>item detail</MergedLayout>);

    expect(container.innerHTML).toBe(render(<>item detail</>).container.innerHTML);
  });
});
