/**
 * Model Selection Tests for ProviderForm Component
 * Tests for Story 4.3: Model Selection Configuration
 */

import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { ProviderForm } from './provider-form';
import { useSettingsStore } from '@/store/use-settings';

// Helper to reset store before each test
const resetStore = () => {
  useSettingsStore.setState({
    apiKey: '',
    baseUrl: 'https://api.openai.com/v1',
    modelName: 'gpt-4o',
    isConfigured: false,
    actions: useSettingsStore.getState().actions
  });
  // Reset localStorage
  localStorage.clear();
};

describe('ProviderForm - Model Selection (Story 4.3)', () => {
  beforeEach(() => {
    resetStore();
  });

  afterEach(() => {
    resetStore();
  });

  describe('AC 1: Model Name Field with Examples', () => {
    it('should render model name input field with label', () => {
      render(<ProviderForm />);

      const modelLabel = screen.getByLabelText('Model Name');
      expect(modelLabel).toBeInTheDocument();
    });

    it('should have placeholder text showing example model format', () => {
      render(<ProviderForm />);

      const modelInput = screen.getByLabelText('Model Name');
      expect(modelInput).toHaveAttribute('placeholder', 'gpt-4o');
    });

    it('should have helper text with model examples', () => {
      render(<ProviderForm />);

      const helperText = screen.getByText(/Model identifier/i);
      expect(helperText).toBeInTheDocument();
      expect(helperText.textContent).toMatch(/gpt-4o|deepseek-chat/i);
    });
  });

  describe('AC 2: Custom Model Name Storage', () => {
    it('should store custom model name in settings store', () => {
      render(<ProviderForm />);

      const modelInput = screen.getByLabelText('Model Name');
      fireEvent.change(modelInput, { target: { value: 'gpt-3.5-turbo' } });

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('gpt-3.5-turbo');
    });

    it('should persist model name across page reloads', () => {
      const { unmount } = render(<ProviderForm />);

      // Set custom model
      const modelInput = screen.getByLabelText('Model Name');
      fireEvent.change(modelInput, { target: { value: 'deepseek-coder' } });

      // Unmount and remount (simulating page reload)
      unmount();
      render(<ProviderForm />);

      // Model name should be persisted
      const modelInputAfterReload = screen.getByLabelText('Model Name');
      expect(modelInputAfterReload).toHaveValue('deepseek-coder');
    });
  });

  describe('AC 3: Default Model Behavior', () => {
    it('should have sensible default model name in store', () => {
      // Reset to fresh state
      resetStore();
      const { unmount } = render(<ProviderForm />);
      unmount();

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('gpt-4o');
    });

    it('should use preset default model when provider preset is clicked', () => {
      render(<ProviderForm />);

      // Click OpenAI preset
      const openaiButton = screen.getByRole('button', { name: 'OpenAI' });
      fireEvent.click(openaiButton);

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('gpt-4o');
    });

    it('should set deepseek-chat when DeepSeek preset is clicked', () => {
      render(<ProviderForm />);

      const deepseekButton = screen.getByRole('button', { name: 'DeepSeek' });
      fireEvent.click(deepseekButton);

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('deepseek-chat');
    });

    it('should set claude-3-haiku when OpenRouter preset is clicked', () => {
      render(<ProviderForm />);

      const openrouterButton = screen.getByRole('button', { name: 'OpenRouter' });
      fireEvent.click(openrouterButton);

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('anthropic/claude-3-haiku');
    });
  });

  describe('Integration: Model Name in LLM API Calls', () => {
    it('should allow custom model name to be set and used', () => {
      render(<ProviderForm />);

      const modelInput = screen.getByLabelText('Model Name');
      fireEvent.change(modelInput, { target: { value: 'custom-model-v1' } });

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('custom-model-v1');
    });

    it('should preserve custom model name when provider preset is clicked', () => {
      render(<ProviderForm />);

      // Set a custom model name
      const modelInput = screen.getByLabelText('Model Name');
      fireEvent.change(modelInput, { target: { value: 'my-custom-model' } });

      // Click OpenAI preset - should NOT overwrite custom model because it's not a known default
      const openaiButton = screen.getByRole('button', { name: 'OpenAI' });
      fireEvent.click(openaiButton);

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('my-custom-model'); // Preserved

      const baseUrl = useSettingsStore.getState().baseUrl;
      expect(baseUrl).toBe('https://api.openai.com/v1'); // URL still updates
    });

    it('should update model name if current is a known default (e.g. switching presets)', () => {
      render(<ProviderForm />);

      // Start with OpenAI default
      useSettingsStore.setState({ modelName: 'gpt-4o' });

      // Click DeepSeek preset
      const deepseekButton = screen.getByRole('button', { name: 'DeepSeek' });
      fireEvent.click(deepseekButton);

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('deepseek-chat'); // Updated because 'gpt-4o' is a known default
    });

    it('should allow manual override of preset model', () => {
      render(<ProviderForm />);

      // First click a preset
      const openaiButton = screen.getByRole('button', { name: 'OpenAI' });
      fireEvent.click(openaiButton);

      // Then manually change the model
      const modelInput = screen.getByLabelText('Model Name');
      fireEvent.change(modelInput, { target: { value: 'gpt-3.5-turbo' } });

      const modelName = useSettingsStore.getState().modelName;
      expect(modelName).toBe('gpt-3.5-turbo');
    });
  });
});
