import * as React from 'react';
import { render } from '@testing-library/react';
import { useMDController } from '../components/Markdown/hooks';

describe('@tingwu/components', () => {
  describe('useMDController hook', () => {
    it('should return a controller instance', () => {
      const TestComponent = () => {
        const controller = useMDController();
        return (
          <div data-testid="controller">
            {controller ? 'has-controller' : 'no-controller'}
          </div>
        );
      };

      const { getByTestId } = render(<TestComponent />);
      const element = getByTestId('controller');
      expect(element.textContent).toBe('has-controller');
    });

    it('should return controller with renderRoot method', () => {
      const TestComponent = () => {
        const controller = useMDController();
        const hasRenderRoot = controller && typeof controller.renderRoot === 'function';
        return (
          <div data-testid="has-render">
            {hasRenderRoot ? 'has-render' : 'no-render'}
          </div>
        );
      };

      const { getByTestId } = render(<TestComponent />);
      const element = getByTestId('has-render');
      expect(element.textContent).toBe('has-render');
    });

    it('should return controller with renderChildren method', () => {
      const TestComponent = () => {
        const controller = useMDController();
        const hasRenderChildren = controller && typeof controller.renderChildren === 'function';
        return (
          <div data-testid="has-render-children">
            {hasRenderChildren ? 'has-render-children' : 'no-render-children'}
          </div>
        );
      };

      const { getByTestId } = render(<TestComponent />);
      const element = getByTestId('has-render-children');
      expect(element.textContent).toBe('has-render-children');
    });

    it('should return the same controller instance on re-render (memoization)', () => {
      let firstController: any = null;
      let secondController: any = null;

      const TestComponent = ({ renderCount }: { renderCount: number }) => {
        const controller = useMDController();
        if (renderCount === 1) {
          firstController = controller;
        } else if (renderCount === 2) {
          secondController = controller;
        }
        return <div data-testid={`render-${renderCount}`}>Render {renderCount}</div>;
      };

      const { rerender, getByTestId } = render(<TestComponent renderCount={1} />);
      expect(getByTestId('render-1')).toBeTruthy();

      rerender(<TestComponent renderCount={2} />);
      expect(getByTestId('render-2')).toBeTruthy();

      // useMemo 应该返回相同的实例
      expect(firstController).toBe(secondController);
    });
  });
});
