// @vitest-environment jsdom

import { describe, expect, it, beforeAll, beforeEach, vi } from 'vitest';
import { act, createElement } from 'react';
import { createRoot, type Root } from 'react-dom/client';

import { ProductProvider, useProduct } from '@/lib/product-context';

beforeAll(() => {
  (globalThis as Record<string, unknown>).IS_REACT_ACT_ENVIRONMENT = true;
});

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

function renderProductHarness() {
  const container = document.createElement('div');
  document.body.appendChild(container);
  let root!: Root;

  function Harness() {
    const { productId, productName, setProductId } = useProduct();
    return createElement(
      'div',
      null,
      createElement('span', { 'data-testid': 'product-id' }, productId),
      createElement('span', { 'data-testid': 'product-name' }, productName),
      createElement(
        'button',
        { type: 'button', onClick: () => setProductId('chronomind') },
        'ChronoMind'
      )
    );
  }

  act(() => {
    root = createRoot(container);
    root.render(createElement(ProductProvider, null, createElement(Harness)));
  });

  return { container, cleanup: () => act(() => root.unmount()) };
}

describe('ProductProvider', () => {
  it('dispatches product change events when the selected product changes', () => {
    const listener = vi.fn();
    window.addEventListener('tracker:product-changed', listener);
    const { container, cleanup } = renderProductHarness();

    act(() => {
      container.querySelector('button')?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
    });

    expect(localStorage.getItem('tracker_selected_product')).toBe('chronomind');
    expect(container.querySelector('[data-testid="product-id"]')?.textContent).toBe('chronomind');
    expect(listener).toHaveBeenCalledTimes(1);

    cleanup();
    window.removeEventListener('tracker:product-changed', listener);
  });

  it('syncs when settings updates localStorage and emits the shared product event', () => {
    const { container, cleanup } = renderProductHarness();

    act(() => {
      localStorage.setItem('tracker_selected_product', 'nomgap');
      window.dispatchEvent(new Event('tracker:product-changed'));
    });

    expect(container.querySelector('[data-testid="product-id"]')?.textContent).toBe('nomgap');
    expect(container.querySelector('[data-testid="product-name"]')?.textContent).toBe('NomGap');

    cleanup();
  });
});
