/**
 * loginRedirect — one-shot sessionStorage-guarded redirect helper.
 *
 * Covers:
 *   - maybeRedirectToLogin() redirects to /api/login on first call and returns true
 *   - maybeRedirectToLogin() does NOT redirect on second call (one-shot guard) and returns false
 *   - clearLoginRedirect() removes the flag so a subsequent call redirects again
 */

import { describe, it, expect, beforeEach, vi } from 'vitest';

// Stub window.location with a writable href before importing the module.
// jsdom sets window.location to a read-only getter backed by a Location object;
// we need to replace it with a plain object so href assignment is detectable.
const locationStub = { href: '' };
Object.defineProperty(window, 'location', {
  value: locationStub,
  writable: true,
});

import { maybeRedirectToLogin, clearLoginRedirect } from './loginRedirect.js';

describe('maybeRedirectToLogin', () => {
  beforeEach(() => {
    sessionStorage.clear();
    locationStub.href = '';
    vi.clearAllMocks();
  });

  it('sets window.location.href to /api/login and returns true on first call', () => {
    const result = maybeRedirectToLogin();
    expect(result).toBe(true);
    expect(locationStub.href).toBe('/api/login');
  });

  it('sets the sessionStorage flag after first call', () => {
    maybeRedirectToLogin();
    expect(sessionStorage.getItem('familysync.loginRedirectAttempted')).toBe('1');
  });

  it('does NOT change href on second call and returns false (one-shot guard)', () => {
    maybeRedirectToLogin(); // first call — redirects
    locationStub.href = ''; // reset the stub to detect a second assignment
    const result = maybeRedirectToLogin(); // second call — should NOT redirect
    expect(result).toBe(false);
    expect(locationStub.href).toBe(''); // href must NOT have been reassigned
  });
});

describe('clearLoginRedirect', () => {
  beforeEach(() => {
    sessionStorage.clear();
    locationStub.href = '';
    vi.clearAllMocks();
  });

  it('removes the sessionStorage flag', () => {
    sessionStorage.setItem('familysync.loginRedirectAttempted', '1');
    clearLoginRedirect();
    expect(sessionStorage.getItem('familysync.loginRedirectAttempted')).toBeNull();
  });

  it('allows maybeRedirectToLogin to redirect again after the flag is cleared', () => {
    maybeRedirectToLogin(); // first call — sets flag
    clearLoginRedirect(); // clear the flag
    locationStub.href = ''; // reset stub
    const result = maybeRedirectToLogin(); // should redirect again
    expect(result).toBe(true);
    expect(locationStub.href).toBe('/api/login');
  });
});
