import { act, renderHook } from '@testing-library/react';

import { useChangelogBadge } from './useChangelogBadge';

const SEEN_KEY = 'rankwiz_changelog_seen_at';
const LATEST_KEY = 'rankwiz_changelog_latest_at';

beforeEach(() => {
  localStorage.clear();
});

describe('useChangelogBadge', () => {
  it('returns hasNew=false when neither key is set', () => {
    const { result } = renderHook(() => useChangelogBadge());
    expect(result.current.hasNew).toBe(false);
  });

  it('returns hasNew=true when latestAt is set but seenAt is not', () => {
    localStorage.setItem(LATEST_KEY, '2025-01-01T00:00:00.000Z');
    const { result } = renderHook(() => useChangelogBadge());
    expect(result.current.hasNew).toBe(true);
  });

  it('returns hasNew=false when seenAt is after latestAt', () => {
    localStorage.setItem(LATEST_KEY, '2025-01-01T00:00:00.000Z');
    localStorage.setItem(SEEN_KEY, '2025-06-01T00:00:00.000Z');
    const { result } = renderHook(() => useChangelogBadge());
    expect(result.current.hasNew).toBe(false);
  });

  it('returns hasNew=true when latestAt is after seenAt', () => {
    localStorage.setItem(LATEST_KEY, '2025-06-01T00:00:00.000Z');
    localStorage.setItem(SEEN_KEY, '2025-01-01T00:00:00.000Z');
    const { result } = renderHook(() => useChangelogBadge());
    expect(result.current.hasNew).toBe(true);
  });

  it('markSeen sets seenAt and clears hasNew', () => {
    localStorage.setItem(LATEST_KEY, '2025-06-01T00:00:00.000Z');
    const { result } = renderHook(() => useChangelogBadge('2025-06-01T00:00:00.000Z'));
    expect(result.current.hasNew).toBe(true);

    act(() => {
      result.current.markSeen();
    });

    expect(result.current.hasNew).toBe(false);
    expect(localStorage.getItem(SEEN_KEY)).toBeTruthy();
  });

  it('markSeen stores the provided latestAt in localStorage', () => {
    const { result } = renderHook(() => useChangelogBadge());

    act(() => {
      result.current.markSeen('2025-09-01T00:00:00.000Z');
    });

    expect(localStorage.getItem(LATEST_KEY)).toBe('2025-09-01T00:00:00.000Z');
  });

  it('updates hasNew reactively when changelog-visited event fires', () => {
    localStorage.setItem(LATEST_KEY, '2025-06-01T00:00:00.000Z');
    const { result } = renderHook(() => useChangelogBadge());
    expect(result.current.hasNew).toBe(true);

    // Simulate another tab marking it as seen
    act(() => {
      localStorage.setItem(SEEN_KEY, new Date().toISOString());
      window.dispatchEvent(new Event('changelog-visited'));
    });

    expect(result.current.hasNew).toBe(false);
  });

  it('transitions hasNew to true when changelog-latest-updated event fires after LATEST_KEY is seeded', () => {
    // Start with no keys — badge is off
    const { result } = renderHook(() => useChangelogBadge());
    expect(result.current.hasNew).toBe(false);

    // DashboardLayout seeds LATEST_KEY and fires the event
    act(() => {
      localStorage.setItem(LATEST_KEY, '2025-12-01T00:00:00.000Z');
      window.dispatchEvent(new Event('changelog-latest-updated'));
    });

    expect(result.current.hasNew).toBe(true);
  });

  it('transitions hasNew back to false when changelog-visited fires after markSeen sets SEEN_KEY', () => {
    // Start with unread entries
    localStorage.setItem(LATEST_KEY, '2025-12-01T00:00:00.000Z');
    const { result } = renderHook(() => useChangelogBadge('2025-12-01T00:00:00.000Z'));
    expect(result.current.hasNew).toBe(true);

    // User visits changelog: markSeen writes SEEN_KEY and fires changelog-visited
    act(() => {
      result.current.markSeen();
    });

    // The visited event (dispatched inside markSeen) should re-compute hasNew to false
    expect(result.current.hasNew).toBe(false);
    expect(localStorage.getItem(SEEN_KEY)).toBeTruthy();
  });
});
