import { render } from '@testing-library/vue';
import userEvent from '@testing-library/user-event';
import { describe, expect, test, beforeEach, afterEach, vi } from 'vitest';
import UiSidebar from '../UiSidebar.vue';
import UiSidebarContent from '../UiSidebarContent.vue';
import UiSidebarMenu from '../UiSidebarMenu.vue';
import UiSidebarMenuButton from '../UiSidebarMenuButton.vue';
import UiSidebarMenuItem from '../UiSidebarMenuItem.vue';
import UiSidebarProvider from '../UiSidebarProvider.vue';
import { mockMatchMediaDesktop } from './sidebar-test-helpers';

beforeEach(() => mockMatchMediaDesktop());
afterEach(() => vi.restoreAllMocks());

describe('UiSidebarMenuButton', () => {
  test('renders only one button when tooltip is not provided', () => {
    const Harness = {
      components: {
        UiSidebarProvider,
        UiSidebar,
        UiSidebarContent,
        UiSidebarMenu,
        UiSidebarMenuItem,
        UiSidebarMenuButton,
      },
      template: `
        <UiSidebarProvider :default-open="true">
          <UiSidebar collapsible="none">
            <UiSidebarContent>
              <UiSidebarMenu>
                <UiSidebarMenuItem>
                  <UiSidebarMenuButton>
                    Item
                  </UiSidebarMenuButton>
                </UiSidebarMenuItem>
              </UiSidebarMenu>
            </UiSidebarContent>
          </UiSidebar>
        </UiSidebarProvider>
      `,
    };
    const { getAllByRole } = render(Harness);

    expect(getAllByRole('button', { name: 'Item' })).toHaveLength(1);
  });

  test('uses the shared active indicator class', () => {
    const Harness = {
      components: {
        UiSidebarProvider,
        UiSidebar,
        UiSidebarContent,
        UiSidebarMenu,
        UiSidebarMenuItem,
        UiSidebarMenuButton,
      },
      template: `
        <UiSidebarProvider :default-open="true">
          <UiSidebar collapsible="none">
            <UiSidebarContent>
              <UiSidebarMenu>
                <UiSidebarMenuItem>
                  <UiSidebarMenuButton :is-active="true">
                    Item
                  </UiSidebarMenuButton>
                </UiSidebarMenuItem>
              </UiSidebarMenu>
            </UiSidebarContent>
          </UiSidebar>
        </UiSidebarProvider>
      `,
    };
    const { container } = render(Harness);

    const activeIndicator = container.querySelector('.ui-active-indicator');
    expect(activeIndicator).toBeInTheDocument();
    expect(activeIndicator).toHaveAttribute('data-active', 'true');
  });

  test('renders label and emits end-icon-click when endIconClickable', async () => {
    const user = userEvent.setup();
    const onEndIconClick = vi.fn();
    const Harness = {
      components: {
        UiSidebarProvider,
        UiSidebar,
        UiSidebarContent,
        UiSidebarMenu,
        UiSidebarMenuItem,
        UiSidebarMenuButton,
      },
      setup() {
        return { onEndIconClick };
      },
      template: `
        <UiSidebarProvider :default-open="true">
          <UiSidebar collapsible="none">
            <UiSidebarContent>
              <UiSidebarMenu>
                <UiSidebarMenuItem>
                  <UiSidebarMenuButton
                    tooltip="Hint"
                    :end-icon-clickable="true"
                    end-icon-aria-label="Open tree"
                    @end-icon-click="onEndIconClick"
                  >
                    Item <template #end-icon>
                      <span data-testid="chev" aria-hidden="true">›</span>
                    </template>
                  </UiSidebarMenuButton>
                </UiSidebarMenuItem>
              </UiSidebarMenu>
            </UiSidebarContent>
          </UiSidebar>
        </UiSidebarProvider>
      `,
    };
    const { getAllByRole } = render(Harness);
    const endButton = getAllByRole('button', { name: 'Open tree' }).at(0);
    if (!endButton) {
      throw new Error('Expected end icon button to be rendered');
    }

    await user.click(endButton);
    expect(onEndIconClick).toHaveBeenCalledTimes(1);
  });
});
