import {
  ACCESS_TOKEN_KEY,
  REFRESH_TOKEN_KEY,
  authorizationHeader,
  clearTokens,
  getAccessToken,
  getRefreshToken,
  hydrateTokensFromNativeStorage,
  setTokens,
} from './tokenStorage';

describe('tokenStorage', () => {
  const originalCapacitor = window.Capacitor;

  beforeEach(() => {
    localStorage.clear();
    delete window.Capacitor;
  });

  afterEach(() => {
    if (originalCapacitor === undefined) {
      delete window.Capacitor;
    } else {
      window.Capacitor = originalCapacitor;
    }
  });

  it('stores and reads tokens from localStorage', async () => {
    await setTokens('access-1', 'refresh-1');
    expect(getAccessToken()).toBe('access-1');
    expect(getRefreshToken()).toBe('refresh-1');
    expect(localStorage.getItem(ACCESS_TOKEN_KEY)).toBe('access-1');
    expect(localStorage.getItem(REFRESH_TOKEN_KEY)).toBe('refresh-1');
  });

  it('clears tokens from localStorage', async () => {
    await setTokens('a', 'r');
    await clearTokens();
    expect(getAccessToken()).toBeNull();
    expect(getRefreshToken()).toBeNull();
  });

  it('builds JWT Authorization header', () => {
    expect(authorizationHeader('tok')).toBe('JWT tok');
    expect(authorizationHeader(null)).toBeNull();
  });

  it('mirrors tokens to Capacitor Preferences when available', async () => {
    const set = jest.fn().mockResolvedValue(undefined);
    window.Capacitor = {
      Plugins: {
        Preferences: { set, get: jest.fn(), remove: jest.fn() },
      },
    };

    await setTokens('access-n', 'refresh-n');

    expect(set).toHaveBeenCalledWith({
      key: ACCESS_TOKEN_KEY,
      value: 'access-n',
    });
    expect(set).toHaveBeenCalledWith({
      key: REFRESH_TOKEN_KEY,
      value: 'refresh-n',
    });
  });

  it('hydrates localStorage from Preferences when empty', async () => {
    const get = jest.fn(async ({ key }) => {
      if (key === ACCESS_TOKEN_KEY) {
        return { value: 'pref-access' };
      }
      if (key === REFRESH_TOKEN_KEY) {
        return { value: 'pref-refresh' };
      }
      return { value: null };
    });
    window.Capacitor = {
      Plugins: { Preferences: { get, set: jest.fn(), remove: jest.fn() } },
    };

    const result = await hydrateTokensFromNativeStorage();

    expect(result).toEqual({
      access: 'pref-access',
      refresh: 'pref-refresh',
    });
    expect(getAccessToken()).toBe('pref-access');
    expect(getRefreshToken()).toBe('pref-refresh');
  });

  it('does not overwrite existing localStorage on hydrate', async () => {
    localStorage.setItem(ACCESS_TOKEN_KEY, 'local-access');
    localStorage.setItem(REFRESH_TOKEN_KEY, 'local-refresh');
    const get = jest.fn();
    window.Capacitor = {
      Plugins: { Preferences: { get, set: jest.fn(), remove: jest.fn() } },
    };

    const result = await hydrateTokensFromNativeStorage();

    expect(get).not.toHaveBeenCalled();
    expect(result).toEqual({
      access: 'local-access',
      refresh: 'local-refresh',
    });
  });
});
