import { describe, it, expect, beforeEach, vi } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { ConnectionStatus } from './connection-status';
import { useSettingsStore } from '@/store/use-settings';
import { SettingsService } from '@/services/settings-service';

// Mock SettingsService (Logic Sandwich pattern)
vi.mock('@/services/settings-service', () => ({
  SettingsService: {
    validateProviderConnection: vi.fn(),
  },
}));

describe('ConnectionStatus', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    useSettingsStore.setState({
      apiKey: '',
      baseUrl: 'https://api.openai.com/v1',
      modelName: 'gpt-4-turbo-preview',
      isConfigured: false,
    });
  });

  it('does not render when API key is not set', () => {
    render(<ConnectionStatus />);
    expect(screen.queryByText(/test connection/i)).not.toBeInTheDocument();
  });

  it('renders Test Connection button when API key is set', () => {
    useSettingsStore.setState({
      apiKey: 'sk-test-key',
      baseUrl: 'https://api.openai.com/v1',
      modelName: 'gpt-4-turbo-preview',
      isConfigured: true,
    });

    render(<ConnectionStatus />);
    expect(screen.getByRole('button', { name: /test connection/i })).toBeInTheDocument();
  });

  it('shows testing state during validation', async () => {
    useSettingsStore.setState({
      apiKey: 'sk-test-key',
      baseUrl: 'https://api.openai.com/v1',
      modelName: 'gpt-4-turbo-preview',
      isConfigured: true,
    });

    vi.mocked(SettingsService.validateProviderConnection).mockImplementation(
      () => new Promise((resolve) => setTimeout(() => resolve({ isValid: true }), 100))
    );

    render(<ConnectionStatus />);

    const button = screen.getByRole('button', { name: /test connection/i });
    fireEvent.click(button);

    // Should show testing state
    await waitFor(() => {
      expect(screen.getByText(/testing\.\.\./i)).toBeInTheDocument();
    });
  });

  it('shows success message on valid connection', async () => {
    useSettingsStore.setState({
      apiKey: 'sk-test-key',
      baseUrl: 'https://api.openai.com/v1',
      modelName: 'gpt-4-turbo-preview',
      isConfigured: true,
    });

    vi.mocked(SettingsService.validateProviderConnection).mockResolvedValue({ isValid: true });

    render(<ConnectionStatus />);

    const button = screen.getByRole('button', { name: /test connection/i });
    fireEvent.click(button);

    await waitFor(() => {
      expect(screen.getByText(/connected.*✅/i)).toBeInTheDocument();
    });
  });

  it('shows error message on failed connection', async () => {
    useSettingsStore.setState({
      apiKey: 'sk-invalid-key',
      baseUrl: 'https://api.openai.com/v1',
      modelName: 'gpt-4-turbo-preview',
      isConfigured: true,
    });

    vi.mocked(SettingsService.validateProviderConnection).mockResolvedValue({
      isValid: false,
      error: 'Invalid API key',
    });

    render(<ConnectionStatus />);

    const button = screen.getByRole('button', { name: /test connection/i });
    fireEvent.click(button);

    await waitFor(() => {
      expect(screen.getByText(/connection failed.*❌/i)).toBeInTheDocument();
    });

    // Should also show the error message
    await waitFor(() => {
      expect(screen.getByText(/invalid api key/i)).toBeInTheDocument();
    });
  });

  it('disables button during testing', async () => {
    useSettingsStore.setState({
      apiKey: 'sk-test-key',
      baseUrl: 'https://api.openai.com/v1',
      modelName: 'gpt-4-turbo-preview',
      isConfigured: true,
    });

    vi.mocked(SettingsService.validateProviderConnection).mockImplementation(
      () => new Promise((resolve) => setTimeout(() => resolve({ isValid: true }), 100))
    );

    render(<ConnectionStatus />);

    const button = screen.getByRole('button', { name: /test connection/i });
    fireEvent.click(button);

    // Button should be disabled during testing
    await waitFor(() => {
      expect(button).toBeDisabled();
    });
  });

  it('calls SettingsService.validateProviderConnection on test', async () => {
    useSettingsStore.setState({
      apiKey: 'sk-test-key',
      baseUrl: 'https://api.custom.com/v1',
      modelName: 'custom-model',
      isConfigured: true,
    });

    vi.mocked(SettingsService.validateProviderConnection).mockResolvedValue({ isValid: true });

    render(<ConnectionStatus />);

    const button = screen.getByRole('button', { name: /test connection/i });
    fireEvent.click(button);

    await waitFor(() => {
      expect(SettingsService.validateProviderConnection).toHaveBeenCalled();
    });
  });
});
