import { act, renderHook } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

const LOCAL_KEY = 'goodgo:avm_v2';

function installMemoryStorage(): Storage {
  const store = new Map<string, string>();
  const storage: Storage = {
    get length() {
      return store.size;
    },
    clear: () => store.clear(),
    getItem: (k) => (store.has(k) ? store.get(k)! : null),
    key: (i) => Array.from(store.keys())[i] ?? null,
    removeItem: (k) => {
      store.delete(k);
    },
    setItem: (k, v) => {
      store.set(k, String(v));
    },
  };
  vi.stubGlobal('localStorage', storage);
  Object.defineProperty(window, 'localStorage', {
    configurable: true,
    value: storage,
  });
  return storage;
}

describe('useAvmV2Flag', () => {
  let storage: Storage;

  beforeEach(() => {
    vi.resetModules();
    storage = installMemoryStorage();
    window.history.replaceState({}, '', '/');
    delete (process.env as Record<string, string | undefined>)[
      'NEXT_PUBLIC_FEATURE_AVM_V2'
    ];
  });

  afterEach(() => {
    storage.clear();
    vi.unstubAllGlobals();
  });

  it('returns false by default when env flag is not set', async () => {
    const { useAvmV2Flag } = await import('../use-avm-v2-flag');
    const { result } = renderHook(() => useAvmV2Flag());
    expect(result.current).toBe(false);
  });

  it('returns true when NEXT_PUBLIC_FEATURE_AVM_V2 is "1"', async () => {
    process.env['NEXT_PUBLIC_FEATURE_AVM_V2'] = '1';
    const { useAvmV2Flag } = await import('../use-avm-v2-flag');
    const { result } = renderHook(() => useAvmV2Flag());
    expect(result.current).toBe(true);
  });

  it('returns true when NEXT_PUBLIC_FEATURE_AVM_V2 is "true"', async () => {
    process.env['NEXT_PUBLIC_FEATURE_AVM_V2'] = 'true';
    const { useAvmV2Flag } = await import('../use-avm-v2-flag');
    const { result } = renderHook(() => useAvmV2Flag());
    expect(result.current).toBe(true);
  });

  it('query param ?avm_v2=1 forces on and persists to localStorage', async () => {
    window.history.replaceState({}, '', '/?avm_v2=1');
    const { useAvmV2Flag } = await import('../use-avm-v2-flag');
    const { result } = renderHook(() => useAvmV2Flag());
    await act(async () => {
      await Promise.resolve();
    });
    expect(result.current).toBe(true);
    expect(storage.getItem(LOCAL_KEY)).toBe('1');
  });

  it('query param ?avm_v2=0 forces off and persists to localStorage', async () => {
    process.env['NEXT_PUBLIC_FEATURE_AVM_V2'] = '1';
    window.history.replaceState({}, '', '/?avm_v2=0');
    const { useAvmV2Flag } = await import('../use-avm-v2-flag');
    const { result } = renderHook(() => useAvmV2Flag());
    await act(async () => {
      await Promise.resolve();
    });
    expect(result.current).toBe(false);
    expect(storage.getItem(LOCAL_KEY)).toBe('0');
  });

  it('respects localStorage override over env default', async () => {
    storage.setItem(LOCAL_KEY, '1');
    const { useAvmV2Flag } = await import('../use-avm-v2-flag');
    const { result } = renderHook(() => useAvmV2Flag());
    await act(async () => {
      await Promise.resolve();
    });
    expect(result.current).toBe(true);
  });
});
