/**
 * Tests for ProviderSelector Component
 * Story 4.4: Provider Switching
 */

import { describe, it, expect, beforeEach, vi } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { ProviderSelector } from './provider-selector';
import { useSettingsStore } from '@/store/use-settings';
import { ProviderManagementService } from '@/services/provider-management-service';
import type { ProviderProfile } from '@/types/settings';

// Mock the service
vi.mock('@/services/provider-management-service', () => ({
  ProviderManagementService: {
    setActiveProvider: vi.fn(),
    getActiveProvider: vi.fn(),
    getAllProviders: vi.fn(),
  },
}));

describe('ProviderSelector Component', () => {
  const mockProviders: ProviderProfile[] = [
    {
      id: 'provider-1',
      name: 'OpenAI GPT-4',
      baseUrl: 'https://api.openai.com/v1',
      apiKey: 'sk-openai-key',
      modelName: 'gpt-4o',
      createdAt: '2024-01-24T00:00:00.000Z',
      updatedAt: '2024-01-24T00:00:00.000Z',
    },
    {
      id: 'provider-2',
      name: 'DeepSeek Chat',
      baseUrl: 'https://api.deepseek.com/v1',
      apiKey: 'sk-deepseek-key',
      modelName: 'deepseek-chat',
      createdAt: '2024-01-24T00:00:00.000Z',
      updatedAt: '2024-01-24T00:00:00.000Z',
    },
    {
      id: 'provider-3',
      name: 'Claude',
      baseUrl: 'https://api.anthropic.com/v1',
      apiKey: 'sk-claude-key',
      modelName: 'claude-3-opus',
      createdAt: '2024-01-24T00:00:00.000Z',
      updatedAt: '2024-01-24T00:00:00.000Z',
    },
  ];

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

    // Reset store state before each test
    useSettingsStore.setState({
      savedProviders: mockProviders,
      activeProviderId: 'provider-1',
      providerMigrationState: {
        hasMigrated: false,
      },
    });

    // Setup default mock returns
    vi.mocked(ProviderManagementService.getAllProviders).mockReturnValue(mockProviders);
    vi.mocked(ProviderManagementService.getActiveProvider).mockReturnValue(mockProviders[0]);
  });

  describe('rendering', () => {
    it('renders all providers as options', () => {
      render(<ProviderSelector />);

      expect(screen.getByText('OpenAI GPT-4')).toBeTruthy();
      expect(screen.getByText('DeepSeek Chat')).toBeTruthy();
      expect(screen.getByText('Claude')).toBeTruthy();
    });

    it('shows visual indicator for active provider', () => {
      render(<ProviderSelector />);

      const activeLabel = screen.getByText('OpenAI GPT-4').closest('[data-active]');
      expect(activeLabel).toHaveAttribute('data-active', 'true');
    });

    it('shows empty state when no providers exist', () => {
      useSettingsStore.setState({ savedProviders: [] });
      vi.mocked(ProviderManagementService.getAllProviders).mockReturnValue([]);

      render(<ProviderSelector />);

      expect(screen.getByText(/no providers available/i)).toBeTruthy();
    });
  });

  describe('user interactions', () => {
    it('calls setActiveProvider when a provider is selected', async () => {
      render(<ProviderSelector />);

      const deepseekOption = screen.getByText('DeepSeek Chat');
      fireEvent.click(deepseekOption);

      await waitFor(() => {
        expect(ProviderManagementService.setActiveProvider).toHaveBeenCalledWith('provider-2');
      });
    });

    it('immediately switches active provider on selection', async () => {
      render(<ProviderSelector />);

      // Initially provider-1 is active
      expect(useSettingsStore.getState().activeProviderId).toBe('provider-1');

      // Click on provider-2
      fireEvent.click(screen.getByText('DeepSeek Chat'));

      await waitFor(() => {
        expect(ProviderManagementService.setActiveProvider).toHaveBeenCalledWith('provider-2');
      });
    });

    it('highlights newly selected provider after switch', async () => {
      // Mock setActiveProvider to update the store
      vi.mocked(ProviderManagementService.setActiveProvider).mockImplementation((id) => {
        useSettingsStore.setState({ activeProviderId: id as string });
      });

      const { rerender } = render(<ProviderSelector />);

      // Initially provider-1 is active
      expect(useSettingsStore.getState().activeProviderId).toBe('provider-1');

      // Click on provider-2
      fireEvent.click(screen.getByText('DeepSeek Chat'));

      await waitFor(() => {
        expect(useSettingsStore.getState().activeProviderId).toBe('provider-2');
      });

      // Rerender to see the updated UI
      rerender(<ProviderSelector />);

      // Provider-2 should now be highlighted
      const activeOption = screen.getByText('DeepSeek Chat').closest('[data-active]');
      expect(activeOption).toHaveAttribute('data-active', 'true');
    });
  });

  describe('accessibility', () => {
    it('has proper role for accessibility', () => {
      render(<ProviderSelector />);

      const radioGroup = screen.getByRole('radiogroup');
      expect(radioGroup).toBeTruthy();
      expect(radioGroup).toHaveAttribute('aria-label', 'Select AI provider');
    });

    it('has proper labels for screen readers', () => {
      render(<ProviderSelector />);

      const radioGroup = screen.getByRole('radiogroup');
      expect(radioGroup).toHaveAttribute('aria-label', 'Select AI provider');
    });
  });
});
