import AsyncStorage from '@react-native-async-storage/async-storage';
import { saveUserSettings, loadUserSettings } from '../AsyncStorage';

jest.mock('@react-native-async-storage/async-storage', () => ({
  setItem: jest.fn(),
  getItem: jest.fn(),
}));

const mockedSetItem = AsyncStorage.setItem as jest.MockedFunction<typeof AsyncStorage.setItem>;
const mockedGetItem = AsyncStorage.getItem as jest.MockedFunction<typeof AsyncStorage.getItem>;

describe('UserSettings functions', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  describe('saveUserSettings', () => {
    test('should save data to AsyncStorage', async () => {
      const key = 'theme';
      const value = 'dark';

      await saveUserSettings(key, value);

      expect(AsyncStorage.setItem).toHaveBeenCalledWith(key, value);
    });

    test('should throw an error if AsyncStorage.setItem fails', async () => {
      mockedSetItem.mockRejectedValueOnce(new Error('AsyncStorage error'));

      await expect(saveUserSettings('theme', 'dark')).rejects.toThrow(
        'Failed to load the data from AsyncStorage'
      );
    });
  });

  describe('loadUserSettings', () => {
    test('should load data from AsyncStorage', async () => {
      const key = 'theme';
      const value = 'dark';

      mockedGetItem.mockResolvedValueOnce(value);

      const result = await loadUserSettings(key);

      expect(result).toBe(value);

      expect(AsyncStorage.getItem).toHaveBeenCalledWith(key);
    });

    test('should return null if the value does not exist in AsyncStorage', async () => {
      mockedGetItem.mockResolvedValueOnce(null);

      const result = await loadUserSettings('nonexistent_key');

      expect(result).toBeUndefined();
    });

    test('should throw an error if AsyncStorage.getItem fails', async () => {
      mockedGetItem.mockRejectedValueOnce(new Error('AsyncStorage error'));

      await expect(loadUserSettings('theme')).rejects.toThrow(
        'Failed to load the data from AsyncStorage'
      );
    });
  });
});
