import '@testing-library/jest-dom/vitest';
import { render, waitFor } from '@testing-library/vue';
import { describe, expect, test } from 'vitest';
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '../index';

describe('UiSelectTrigger', () => {
  test('applies custom class', () => {
    const { getByRole } = render({
      components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
      template: `
        <UiSelect>
          <UiSelectTrigger class="w-[200px]">
            <UiSelectValue placeholder="Select" />
          </UiSelectTrigger>
          <UiSelectContent />
        </UiSelect>
      `,
    });

    expect(getByRole('combobox')).toHaveClass('w-[200px]');
  });

  test('is disabled when disabled prop is true', () => {
    const { getByRole } = render({
      components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
      template: `
        <UiSelect :disabled="true">
          <UiSelectTrigger>
            <UiSelectValue placeholder="Select" />
          </UiSelectTrigger>
          <UiSelectContent />
        </UiSelect>
      `,
    });

    expect(getByRole('combobox')).toBeDisabled();
  });

  test('applies aria-label when provided', () => {
    const { getByRole } = render({
      components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
      template: `
        <UiSelect>
          <UiSelectTrigger ariaLabel="Select your preference">
            <UiSelectValue placeholder="Choose" />
          </UiSelectTrigger>
          <UiSelectContent />
        </UiSelect>
      `,
    });

    expect(getByRole('combobox')).toHaveAttribute(
      'aria-label',
      'Select your preference',
    );
  });

  test('has data-placeholder when no value is selected', () => {
    const { getByRole } = render({
      components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
      template: `
        <UiSelect>
          <UiSelectTrigger>
            <UiSelectValue placeholder="Select" />
          </UiSelectTrigger>
          <UiSelectContent />
        </UiSelect>
      `,
    });

    const trigger = getByRole('combobox');
    expect(trigger).toHaveAttribute('data-placeholder');
  });

  test('uses focus-ring border for focus and open states without default shadow', () => {
    const { getByRole } = render({
      components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
      template: `
        <UiSelect>
          <UiSelectTrigger>
            <UiSelectValue placeholder="Select" />
          </UiSelectTrigger>
          <UiSelectContent />
        </UiSelect>
      `,
    });

    const trigger = getByRole('combobox');

    expect(trigger).toHaveClass('focus:border-border-surface-focus-ring');
    expect(trigger).toHaveClass(
      'focus-visible:border-border-surface-focus-ring',
    );
    expect(trigger).toHaveClass('active:border-border-surface-focus-ring');
    expect(trigger).toHaveClass(
      'data-[state=open]:border-border-surface-focus-ring',
    );
    expect(trigger).toHaveClass('focus:shadow-xs');
    expect(trigger).not.toHaveClass('shadow-xs');
  });

  test('uses focus-ring border for multi-select focus and open states without default shadow', () => {
    const { getByRole } = render({
      components: { UiSelect, UiSelectTrigger, UiSelectContent, UiSelectValue },
      template: `
        <UiSelect :multiple="true">
          <UiSelectTrigger>
            <UiSelectValue placeholder="Select" />
          </UiSelectTrigger>
          <UiSelectContent />
        </UiSelect>
      `,
    });

    const trigger = getByRole('combobox');

    expect(trigger).toHaveClass('focus:border-border-surface-focus-ring');
    expect(trigger).toHaveClass(
      'focus-visible:border-border-surface-focus-ring',
    );
    expect(trigger).toHaveClass('active:border-border-surface-focus-ring');
    expect(trigger).toHaveClass(
      'data-[state=open]:border-border-surface-focus-ring',
    );
    expect(trigger).toHaveClass('focus:shadow-xs');
    expect(trigger).not.toHaveClass('shadow-xs');
  });

  test('removes data-placeholder when a value is selected', async () => {
    const { getByRole } = render({
      components: {
        UiSelect,
        UiSelectTrigger,
        UiSelectContent,
        UiSelectItem,
        UiSelectValue,
      },
      template: `
        <UiSelect default-value="option1">
          <UiSelectTrigger>
            <UiSelectValue placeholder="Select" />
          </UiSelectTrigger>
          <UiSelectContent>
            <UiSelectItem value="option1">Option 1</UiSelectItem>
          </UiSelectContent>
        </UiSelect>
      `,
    });

    await waitFor(() => {
      const trigger = getByRole('combobox');
      expect(trigger).not.toHaveAttribute('data-placeholder');
      expect(trigger).toHaveTextContent('Option 1');
      expect(trigger).toHaveClass(
        '[&:not([data-placeholder])]:border-border-surface-focus-ring',
      );
    });
  });

  test('uses focus-ring border when multi-select has a value', async () => {
    const { getByRole } = render({
      components: {
        UiSelect,
        UiSelectTrigger,
        UiSelectContent,
        UiSelectItem,
        UiSelectValue,
      },
      template: `
        <UiSelect :multiple="true" :default-value="['option1']">
          <UiSelectTrigger>
            <UiSelectValue placeholder="Select" />
          </UiSelectTrigger>
          <UiSelectContent>
            <UiSelectItem value="option1">Option 1</UiSelectItem>
          </UiSelectContent>
        </UiSelect>
      `,
    });

    await waitFor(() => {
      const trigger = getByRole('combobox');
      expect(trigger).not.toHaveAttribute('data-placeholder');
      expect(trigger).toHaveTextContent('Option 1');
      expect(trigger).toHaveClass(
        '[&:not([data-placeholder])]:border-border-surface-focus-ring',
      );
    });
  });
});
