// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { Currency, DEFAULT_CURRENCY } from '@/app/(root)/account/constants';

import {
  getCurrencyFromUrlParams,
  getUserCurrencyPreference,
  setUserCurrencyPreference,
} from './currencyStorage';

// Mock localStorage
const localStorageMock = {
  getItem: vi.fn(),
  setItem: vi.fn(),
  clear: vi.fn(),
};

Object.defineProperty(window, 'localStorage', {
  value: localStorageMock,
});

describe('currencyStorage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('getUserCurrencyPreference', () => {
    it('returns DEFAULT_CURRENCY when no preference is stored', () => {
      localStorageMock.getItem.mockReturnValue(null);
      expect(getUserCurrencyPreference()).toBe(DEFAULT_CURRENCY);
    });

    it('returns stored valid currency', () => {
      localStorageMock.getItem.mockReturnValue('EUR');
      expect(getUserCurrencyPreference()).toBe(Currency.EUR);
    });

    it('returns DEFAULT_CURRENCY for invalid stored currency', () => {
      localStorageMock.getItem.mockReturnValue('INVALID');
      expect(getUserCurrencyPreference()).toBe(DEFAULT_CURRENCY);
    });

    it('handles localStorage errors gracefully', () => {
      localStorageMock.getItem.mockImplementation(() => {
        throw new Error('localStorage error');
      });
      expect(getUserCurrencyPreference()).toBe(DEFAULT_CURRENCY);
    });
  });

  describe('setUserCurrencyPreference', () => {
    it('stores currency in localStorage', () => {
      setUserCurrencyPreference(Currency.EUR);
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        'suno-selected-currency',
        Currency.EUR
      );
    });

    it('handles localStorage errors gracefully', () => {
      localStorageMock.setItem.mockImplementation(() => {
        throw new Error('localStorage error');
      });
      expect(() => setUserCurrencyPreference(Currency.EUR)).not.toThrow();
    });
  });

  describe('getCurrencyFromUrlParams', () => {
    it('returns undefined when no currency parameter', () => {
      const params = new URLSearchParams('?other=value');
      expect(getCurrencyFromUrlParams(params)).toBeUndefined();
    });

    it('returns valid currency from URL parameter', () => {
      const params = new URLSearchParams('?currency=eur');
      expect(getCurrencyFromUrlParams(params)).toBe(Currency.EUR);
    });

    it('returns undefined for invalid currency parameter', () => {
      const params = new URLSearchParams('?currency=invalid');
      expect(getCurrencyFromUrlParams(params)).toBeUndefined();
    });

    it('handles case insensitive currency parameters', () => {
      const params = new URLSearchParams('?currency=USD');
      expect(getCurrencyFromUrlParams(params)).toBe(Currency.USD);
    });
  });
});
