/**
 * TriggerFilterBuilder Tests
 *
 * Tests the filter builder wrapper component including:
 * - Empty state rendering
 * - Enable/disable filters
 * - Integration with FilterGroupBuilder
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TriggerFilterBuilder } from './TriggerFilterBuilder';
import { FilterGroup } from '../types/filter';
import { TriggerField } from '../types/trigger';

// Mock FilterGroupBuilder to isolate TriggerFilterBuilder tests
vi.mock('./FilterGroupBuilder', () => ({
  FilterGroupBuilder: ({
    group,
    onChange,
  }: {
    group: FilterGroup;
    onChange: (group: FilterGroup) => void;
  }) => (
    <div data-testid="filter-group-builder" data-logic={group.logic}>
      <button onClick={() => onChange({ ...group, logic: 'or' })}>Change Logic</button>
    </div>
  ),
}));

describe('TriggerFilterBuilder', () => {
  const mockAvailableFields: TriggerField[] = [
    { name: 'user_email', type: 'string', description: 'User email', example: 'user@example.com' },
    { name: 'user_role', type: 'string', description: 'User role', example: 'subscriber' },
    { name: 'post_type', type: 'string', description: 'Post type', example: 'post' },
  ];

  const mockOnChange = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
  });

  // ==========================================================================
  // Empty State Tests
  // ==========================================================================

  describe('empty state (no filters)', () => {
    it('renders empty state when filters is null', () => {
      render(
        <TriggerFilterBuilder
          filters={null}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      expect(
        screen.getByText(
          'No filters configured. This workflow will trigger for all events of this type.',
        ),
      ).toBeInTheDocument();
    });

    it('renders Add Filter Conditions button in empty state', () => {
      render(
        <TriggerFilterBuilder
          filters={null}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      expect(screen.getByText('Add Filter Conditions')).toBeInTheDocument();
    });

    it('enables filters when Add Filter Conditions is clicked', async () => {
      render(
        <TriggerFilterBuilder
          filters={null}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      await userEvent.click(screen.getByText('Add Filter Conditions'));

      expect(mockOnChange).toHaveBeenCalledWith({
        logic: 'and',
        conditions: [
          {
            field: 'user_email',
            operator: 'equals',
            value: '',
          },
        ],
      });
    });

    it('disables Add button when no available fields', () => {
      render(<TriggerFilterBuilder filters={null} availableFields={[]} onChange={mockOnChange} />);

      const button = screen.getByText('Add Filter Conditions');
      expect(button).toBeDisabled();
    });

    it('shows error message when no fields available', () => {
      render(<TriggerFilterBuilder filters={null} availableFields={[]} onChange={mockOnChange} />);

      expect(screen.getByText('No fields available for this trigger type.')).toBeInTheDocument();
    });
  });

  // ==========================================================================
  // Active Filters State Tests
  // ==========================================================================

  describe('active filters state', () => {
    const mockFilters: FilterGroup = {
      logic: 'and',
      conditions: [{ field: 'user_email', operator: 'contains', value: '@example.com' }],
    };

    it('renders FilterGroupBuilder when filters exist', () => {
      render(
        <TriggerFilterBuilder
          filters={mockFilters}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      expect(screen.getByTestId('filter-group-builder')).toBeInTheDocument();
    });

    it('renders header with Filter Conditions title', () => {
      render(
        <TriggerFilterBuilder
          filters={mockFilters}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      expect(screen.getByText('Filter Conditions')).toBeInTheDocument();
    });

    it('renders info text about filter conditions', () => {
      render(
        <TriggerFilterBuilder
          filters={mockFilters}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      expect(
        screen.getByText('Only trigger this workflow when the following conditions are met:'),
      ).toBeInTheDocument();
    });

    it('renders Remove All Filters button', () => {
      render(
        <TriggerFilterBuilder
          filters={mockFilters}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      expect(screen.getByText('Remove All Filters')).toBeInTheDocument();
    });

    it('disables filters when Remove All Filters is clicked', async () => {
      render(
        <TriggerFilterBuilder
          filters={mockFilters}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      await userEvent.click(screen.getByText('Remove All Filters'));

      expect(mockOnChange).toHaveBeenCalledWith(null);
    });

    it('passes filters to FilterGroupBuilder', () => {
      render(
        <TriggerFilterBuilder
          filters={mockFilters}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      expect(screen.getByTestId('filter-group-builder')).toHaveAttribute('data-logic', 'and');
    });

    it('passes onChange to FilterGroupBuilder', async () => {
      render(
        <TriggerFilterBuilder
          filters={mockFilters}
          availableFields={mockAvailableFields}
          onChange={mockOnChange}
        />,
      );

      // The mock FilterGroupBuilder has a "Change Logic" button that calls onChange
      await userEvent.click(screen.getByText('Change Logic'));

      expect(mockOnChange).toHaveBeenCalledWith(expect.objectContaining({ logic: 'or' }));
    });
  });
});
