/**
 * TriggerConfigContent Tests
 *
 * Tests the trigger configuration content component including:
 * - Loading state
 * - Error state with retry
 * - No trigger state
 * - Valid trigger state with TriggerFilterBuilder
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TriggerConfigContent } from './TriggerConfigContent';
import { Trigger } from '../../types/trigger';
import { FilterGroup } from '../../types/filter';

// Mock TriggerFilterBuilder with minimal stub
vi.mock('../TriggerFilterBuilder', () => ({
  TriggerFilterBuilder: ({
    filters,
    availableFields,
    onChange,
  }: {
    filters: FilterGroup | null;
    availableFields: Array<{ name: string }>;
    onChange: (filters: FilterGroup | null) => void;
  }) => (
    <div data-testid="trigger-filter-builder">
      <span data-testid="filter-status">{filters ? 'Has filters' : 'No filters'}</span>
      <span data-testid="field-count">{availableFields.length}</span>
      <button
        data-testid="add-filter"
        onClick={() =>
          onChange({
            logic: 'and',
            conditions: [{ field: 'test', operator: 'equals', value: 'test' }],
          })
        }
      >
        Add Filter
      </button>
      <button data-testid="clear-filters" onClick={() => onChange(null)}>
        Clear Filters
      </button>
    </div>
  ),
}));

// Test fixtures
const mockTrigger: Trigger = {
  type: 'wordpress/user_registration',
  label: 'User Registration',
  description: 'Triggered when a new user registers',
  integration: 'wordpress',
  available_fields: [
    {
      name: 'user_id',
      type: 'integer',
      description: 'User ID',
      example: '123',
    },
    {
      name: 'user_email',
      type: 'string',
      description: 'User email',
      example: 'user@example.com',
    },
  ],
  is_available: true,
  availability_reason: '',
};

const mockFilters: FilterGroup = {
  logic: 'and',
  conditions: [{ field: 'user_email', operator: 'contains', value: '@company.com' }],
};

const defaultProps = {
  trigger: undefined as Trigger | undefined,
  isLoading: false,
  error: null as string | null,
  onRetry: vi.fn(),
  filters: null as FilterGroup | null,
  onFiltersChange: vi.fn(),
};

describe('TriggerConfigContent', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('loading state', () => {
    it('renders spinner when isLoading is true', () => {
      const { container } = render(<TriggerConfigContent {...defaultProps} isLoading={true} />);

      expect(container.querySelector('.animate-spin')).toBeInTheDocument();
    });

    it('shows loading text', () => {
      render(<TriggerConfigContent {...defaultProps} isLoading={true} />);

      expect(screen.getByText('Loading trigger fields...')).toBeInTheDocument();
    });

    it('does not render TriggerFilterBuilder when loading', () => {
      render(<TriggerConfigContent {...defaultProps} isLoading={true} />);

      expect(screen.queryByTestId('trigger-filter-builder')).not.toBeInTheDocument();
    });

    it('does not render error state when loading even if error exists', () => {
      render(<TriggerConfigContent {...defaultProps} isLoading={true} error="Some error" />);

      expect(screen.getByText('Loading trigger fields...')).toBeInTheDocument();
      expect(screen.queryByText('Some error')).not.toBeInTheDocument();
    });
  });

  describe('error state', () => {
    it('renders error message', () => {
      render(<TriggerConfigContent {...defaultProps} error="Failed to load trigger" />);

      expect(screen.getByText('Failed to load trigger')).toBeInTheDocument();
    });

    it('renders with error styling', () => {
      const { container } = render(<TriggerConfigContent {...defaultProps} error="Error" />);

      expect(container.querySelector('.bg-red-50')).toBeInTheDocument();
    });

    it('renders Retry button', () => {
      render(<TriggerConfigContent {...defaultProps} error="Failed" />);

      expect(screen.getByRole('button', { name: 'Retry' })).toBeInTheDocument();
    });

    it('calls onRetry when Retry button is clicked', async () => {
      const onRetry = vi.fn();
      render(<TriggerConfigContent {...defaultProps} error="Failed" onRetry={onRetry} />);

      await userEvent.click(screen.getByRole('button', { name: 'Retry' }));

      expect(onRetry).toHaveBeenCalledTimes(1);
    });

    it('does not render TriggerFilterBuilder in error state', () => {
      render(<TriggerConfigContent {...defaultProps} error="Error" trigger={mockTrigger} />);

      expect(screen.queryByTestId('trigger-filter-builder')).not.toBeInTheDocument();
    });
  });

  describe('no trigger state', () => {
    it('renders placeholder message when trigger is undefined', () => {
      render(<TriggerConfigContent {...defaultProps} trigger={undefined} />);

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

    it('does not render TriggerFilterBuilder when no trigger', () => {
      render(<TriggerConfigContent {...defaultProps} trigger={undefined} />);

      expect(screen.queryByTestId('trigger-filter-builder')).not.toBeInTheDocument();
    });
  });

  describe('valid trigger state', () => {
    it('renders TriggerFilterBuilder when trigger is provided', () => {
      render(<TriggerConfigContent {...defaultProps} trigger={mockTrigger} />);

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

    it('passes available_fields to TriggerFilterBuilder', () => {
      render(<TriggerConfigContent {...defaultProps} trigger={mockTrigger} />);

      expect(screen.getByTestId('field-count')).toHaveTextContent('2');
    });

    it('passes filters to TriggerFilterBuilder', () => {
      render(
        <TriggerConfigContent {...defaultProps} trigger={mockTrigger} filters={mockFilters} />,
      );

      expect(screen.getByTestId('filter-status')).toHaveTextContent('Has filters');
    });

    it('passes null filters when no filters configured', () => {
      render(<TriggerConfigContent {...defaultProps} trigger={mockTrigger} filters={null} />);

      expect(screen.getByTestId('filter-status')).toHaveTextContent('No filters');
    });

    it('calls onFiltersChange when filters are modified', async () => {
      const onFiltersChange = vi.fn();
      render(
        <TriggerConfigContent
          {...defaultProps}
          trigger={mockTrigger}
          onFiltersChange={onFiltersChange}
        />,
      );

      await userEvent.click(screen.getByTestId('add-filter'));

      expect(onFiltersChange).toHaveBeenCalledWith(
        expect.objectContaining({
          logic: 'and',
          conditions: expect.any(Array),
        }),
      );
    });

    it('calls onFiltersChange with null when filters are cleared', async () => {
      const onFiltersChange = vi.fn();
      render(
        <TriggerConfigContent
          {...defaultProps}
          trigger={mockTrigger}
          filters={mockFilters}
          onFiltersChange={onFiltersChange}
        />,
      );

      await userEvent.click(screen.getByTestId('clear-filters'));

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

    it('handles trigger with empty available_fields', () => {
      const triggerNoFields = { ...mockTrigger, available_fields: [] };
      render(<TriggerConfigContent {...defaultProps} trigger={triggerNoFields} />);

      expect(screen.getByTestId('field-count')).toHaveTextContent('0');
    });
  });
});
