import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import HomePage from '../routes/+page.svelte';
import { pushNotificationManager } from '$lib/client/PushNotificationManager';

// Mock $app/environment
vi.mock('$app/environment', () => ({
  browser: true
}));

// Mock fetch for queue API calls
globalThis.fetch = vi.fn(() =>
  Promise.resolve({
    ok: true,
    json: () => Promise.resolve({ items: [], stats: { total: 0, pending: 0, in_progress: 0, completed: 0, error: 0 } })
  } as Response)
);

// Mock EventSource for SSE
globalThis.EventSource = vi.fn(() => ({
  addEventListener: vi.fn(),
  removeEventListener: vi.fn(),
  close: vi.fn(),
  onerror: null,
  onmessage: null,
  onopen: null,
  readyState: 0,
  url: '',
  withCredentials: false,
  CONNECTING: 0,
  OPEN: 1,
  CLOSED: 2,
  dispatchEvent: vi.fn()
})) as any;

vi.mock('$lib/client/PushNotificationManager', () => ({
  pushNotificationManager: {
    getState: vi.fn(),
    subscribe: vi.fn(),
    onStateChange: vi.fn(() => () => {})
  }
}));

describe('Automatic Notification Subscription', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(pushNotificationManager.getState).mockReturnValue({
      supported: true,
      permission: 'default',
      subscribed: false,
      loading: false,
      error: null
    });
  });

  it('should auto-subscribe on first user click when supported and not subscribed', async () => {
    render(HomePage);
    
    // Wait for component to mount and set up event listeners
    await new Promise(resolve => setTimeout(resolve, 100));

    // Simulate user click anywhere on page
    document.body.click();

    // Wait for event handlers to process
    await new Promise(resolve => setTimeout(resolve, 50));

    expect(pushNotificationManager.subscribe).toHaveBeenCalledTimes(1);
  });

  it('should not auto-subscribe if permission denied', async () => {
    vi.mocked(pushNotificationManager.getState).mockReturnValue({
      supported: true,
      permission: 'denied',
      subscribed: false,
      loading: false,
      error: null
    });

    render(HomePage);
    await new Promise(resolve => setTimeout(resolve, 100));
    
    document.body.click();
    await new Promise(resolve => setTimeout(resolve, 50));

    expect(pushNotificationManager.subscribe).not.toHaveBeenCalled();
  });

  it('should not auto-subscribe if already subscribed', async () => {
    vi.mocked(pushNotificationManager.getState).mockReturnValue({
      supported: true,
      permission: 'granted',
      subscribed: true,
      loading: false,
      error: null
    });

    render(HomePage);
    await new Promise(resolve => setTimeout(resolve, 100));
    
    document.body.click();
    await new Promise(resolve => setTimeout(resolve, 50));

    expect(pushNotificationManager.subscribe).not.toHaveBeenCalled();
  });

  it('should only attempt subscription once', async () => {
    render(HomePage);
    await new Promise(resolve => setTimeout(resolve, 100));

    document.body.click();
    document.body.click();
    document.body.click();

    await new Promise(resolve => setTimeout(resolve, 50));

    expect(pushNotificationManager.subscribe).toHaveBeenCalledTimes(1);
  });
});
