import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { renderHook, act, waitFor } from '@testing-library/react';
import { CVProvider, useCVData } from '../CVContext';

const mockFetch = vi.fn();
const mockUpdateCV = vi.fn();
const mockExportCV = vi.fn();
const mockImportCV = vi.fn();

vi.mock('../../../lib/api', () => ({
  fetchCV: () => mockFetch(),
  updateCV: (data) => mockUpdateCV(data),
  exportCV: () => mockExportCV(),
  importCV: (data) => mockImportCV(data),
}));

const defaultMockData = {
  personal: { name: 'Test User', title: 'Developer', email: 'test@test.com' },
  experience: [],
  skills: {},
  education: [],
  projects: []
};

describe('CVContext', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockFetch.mockResolvedValue(defaultMockData);
    mockUpdateCV.mockResolvedValue({ success: true });
    mockExportCV.mockResolvedValue(new Blob([JSON.stringify(defaultMockData)], { type: 'application/json' }));
    mockImportCV.mockResolvedValue({ success: true });
  });
  
  afterEach(() => {
    vi.resetAllMocks();
  });
  
  const wrapper = ({ children }) => <CVProvider>{children}</CVProvider>;
  
  it('provides default data after loading', async () => {
    const { result } = renderHook(() => useCVData(), { wrapper });
    
    await waitFor(() => {
      expect(result.current.loading).toBe(false);
    });
    
    expect(result.current.data).toBeDefined();
    expect(result.current.data.personal.name).toBe('Test User');
  });
  
  it('updates personal data', async () => {
    const { result } = renderHook(() => useCVData(), { wrapper });
    
    await waitFor(() => expect(result.current.loading).toBe(false));
    
    act(() => {
      result.current.updatePersonal({ 
        ...result.current.data.personal,
        name: 'New Name' 
      });
    });
    
    await waitFor(() => {
      expect(result.current.data.personal.name).toBe('New Name');
    });
    expect(mockUpdateCV).toHaveBeenCalled();
  });
  
  it('updates experience data', async () => {
    const { result } = renderHook(() => useCVData(), { wrapper });
    
    await waitFor(() => expect(result.current.loading).toBe(false));
    
    const newExperience = [{ id: 1, role: 'New Role' }];
    act(() => {
      result.current.updateExperience(newExperience);
    });
    
    await waitFor(() => {
      expect(result.current.data.experience).toEqual(newExperience);
    });
  });
  
  it('throws error when used outside CVProvider', () => {
    expect(() => {
      renderHook(() => useCVData());
    }).toThrow('useCVData must be used within a CVProvider');
  });
});
