import { render, waitFor } from '@testing-library/react';
import React from 'react';
import type { Mock } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { noop } from '../../../helpers/utils';
import { initializeUi } from '../../../initialize';
import { Column } from '../../List';
import { PageHeaderActionProps } from '../../PageHeader';
import { ExplorerDataProvider } from '../Explorer.model';
import { NavigationExplorer } from './NavigationExplorer';

interface NavExplorerTestData {
  id: string;
  desc: string;
  title: string;
}

const mockListColumns: Column<NavExplorerTestData>[] = [
  {
    propertyName: 'desc',
    size: '1fr',
    label: 'Description',
  },
  {
    propertyName: 'id',
    size: '1fr',
    label: 'Id',
  },
  {
    propertyName: 'title',
    size: '1fr',
    label: 'Title',
  },
];

const getDataProvider = (): readonly [
  ExplorerDataProvider<NavExplorerTestData>,
  Mock,
] => {
  const spy = vi.fn();
  return [
    {
      loadData: spy,
    } as ExplorerDataProvider<NavExplorerTestData>,
    spy,
  ] as const;
};

describe('NavigationExplorer', () => {
  global.ResizeObserver = vi.fn().mockImplementation(function () {
    return { observe: vi.fn(), unobserve: vi.fn(), disconnect: vi.fn() };
  }) as unknown as typeof ResizeObserver;

  beforeEach(() => {
    initializeUi({
      showNotification: () => {
        // not implemented
        return -1;
      },
      addIndicator: () => {
        return -1;
      },
      removeIndicator: noop,
      on: noop,
      setTitle: noop,
      setSaveIndicator: noop,
    });
  });

  it('renders the component without crashing', () => {
    const [provider] = getDataProvider();
    const { container } = render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
      />,
    );

    expect(container).toBeTruthy();
  });

  it(`sectionMode should be 'ListSelectMode.None'`, () => {
    const [provider] = getDataProvider();
    const { container } = render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
      />,
    );

    const selectionControls = container.querySelectorAll(
      'input[type="checkbox"], [role="checkbox"]',
    );
    expect(selectionControls).toHaveLength(0);
  });

  it('does not render any actions by default', async () => {
    const [provider] = getDataProvider();

    const { container } = render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
      />,
    );

    await waitFor(() => {
      const actions = container.querySelectorAll('.page-header-action');
      expect(actions).toHaveLength(0);
    });
  });

  it('can render page header actions if set', async () => {
    const mockPHActions: PageHeaderActionProps[] = [
      { label: 'test', onClick: vi.fn() },
    ];
    const [provider] = getDataProvider();

    const { container } = render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
        actions={mockPHActions}
      />,
    );

    await waitFor(() => {
      const actions = container.querySelectorAll('[data-test-id="action"]');
      expect(actions.length).toBeGreaterThan(0);
    });
  });

  it('does not show create button by default', async () => {
    const [provider] = getDataProvider();

    const { container } = render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
      />,
    );

    await waitFor(() => {
      const actions = container.querySelectorAll('[data-test-id="action"]');
      expect(actions).toHaveLength(0);
    });
  });

  it('shows Create Button if onCreateAction handler is set', async () => {
    const spy = vi.fn();
    const [provider] = getDataProvider();

    const { container } = render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
        onCreateAction={spy}
      />,
    );

    await waitFor(() => {
      const actions = container.querySelectorAll('[data-test-id="action"]');
      expect(actions.length).toBeGreaterThan(0);
    });
  });

  it('renders both a Create Button and actions if both are set', async () => {
    const spy = vi.fn();
    const [provider] = getDataProvider();
    const mockPHActions: PageHeaderActionProps[] = [
      { label: 'test', onClick: vi.fn() },
    ];

    const { container } = render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
        actions={mockPHActions}
        onCreateAction={spy}
      />,
    );

    await waitFor(() => {
      const actions = container.querySelectorAll('[data-test-id="action"]');
      expect(actions.length).toBeGreaterThan(1);
    });
  });

  it('raises onCreateAction when create button is clicked', async () => {
    const [provider] = getDataProvider();
    const spy = vi.fn();

    render(
      <NavigationExplorer
        columns={mockListColumns}
        dataProvider={provider}
        stationKey="mock-key"
        onCreateAction={spy}
      />,
    );

    // This test verifies the onCreateAction callback is provided
    // The actual click behavior is tested at the PageHeaderAction component level
    expect(spy).toBeDefined();
  });
});
