vi.mock('@/features.ts', () => ({
  default: { feature1: true, feature2: false },
}));

import { useFeatureFlipper } from './featureFlipper.composable';
import { describe, expect, it } from 'vitest';

const initialFeatures = { feature1: true, feature2: false };

describe('featureFlipper', () => {
  const {
    resetFeatures,
    fetchFeatures,
    features,
    isFeatureEnabled,
    toggleFeature,
  } = useFeatureFlipper();
  beforeEach(() => {
    vi.resetAllMocks();
    vi.resetModules();
    vi.stubGlobal('localStorage', {
      getItem: vi.fn(),
      setItem: vi.fn(),
    });
    resetFeatures(initialFeatures);
  });

  describe('fetchFeatures', () => {
    it('should return value in localStorage', () => {
      (localStorage.getItem as any).mockReturnValue(
        '{"feature1": false, "feature2": true}',
      );
      fetchFeatures();
      expect(features.value).toEqual({
        feature1: false,
        feature2: true,
      });
    });
    it('should return defaultValues if localStorage invalid', () => {
      (localStorage.getItem as any).mockReturnValue(
        '{"feature1": false, "feature2": true',
      );
      fetchFeatures();
      expect(features.value).toEqual({
        feature1: true,
        feature2: false,
      });
    });
    it('should return value only present in initialValues', () => {
      (localStorage.getItem as any).mockReturnValue(
        '{"feature1": false, "feature2": true, "feature3": true}',
      );
      fetchFeatures();
      expect(features.value).toEqual({
        feature1: false,
        feature2: true,
      });
    });
    it('should return value with all in initialValues', () => {
      (localStorage.getItem as any).mockReturnValue('{"feature1": false}');
      fetchFeatures();
      expect(features.value).toEqual({
        feature1: false,
        feature2: false,
      });
    });
  });

  describe('isFeatureEnabled', () => {
    it('should return value in localStorage', () => {
      (localStorage.getItem as any).mockReturnValue(
        '{"feature1": false, "feature2": true}',
      );
      fetchFeatures();
      expect(isFeatureEnabled('feature1')).toEqual(false);
    });
    it('should return defaultValue if not in localStorage', () => {
      (localStorage.getItem as any).mockReturnValue('{"feature2": true}');
      fetchFeatures();
      expect(isFeatureEnabled('feature1')).toEqual(true);
    });
    it('should return false if does not exist', () => {
      (localStorage.getItem as any).mockReturnValue('{"feature2": true}');
      fetchFeatures();
      expect(isFeatureEnabled('tartampion')).toEqual(false);
    });
    it('should return false if exist in localStorage but not in setup file', () => {
      (localStorage.getItem as any).mockReturnValue('{"tartampion": true}');
      fetchFeatures();
      expect(isFeatureEnabled('tartampion')).toEqual(false);
    });
  });

  describe('toggleFeature', () => {
    it('should change feature in localStorage', () => {
      toggleFeature('feature1');
      expect(localStorage.setItem).toHaveBeenCalledWith(
        'features',
        '{"feature1":false,"feature2":false}',
      );
    });
    it('should not do something if feature is not valid', () => {
      toggleFeature('invalid');
      expect(localStorage.setItem).not.toHaveBeenCalled();
    });
  });
});
