// @vitest-environment jsdom
import { act, render, screen } from '@testing-library/react';
import { useMemo, useReducer, useRef } from 'react';
import { MemoryRouter, useSearchParams } from 'react-router-dom';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { DEFAULT_TRADE_PLANS_UI_STATE, reduceTradePlansUiState } from './tradePlansState';
import { useTradePlansNavigationState } from './useTradePlansNavigationState';

function NavigationHarness() {
  const [uiState, dispatch] = useReducer(reduceTradePlansUiState, DEFAULT_TRADE_PLANS_UI_STATE);
  const [searchParams, setSearchParams] = useSearchParams();
  const setupCardRefs = useRef<Record<string, HTMLDivElement | null>>({});

  const availableSellHoldings = useMemo(() => ([
    {
      symbol: 'AAPL',
      size: 5,
      entryPrice: 180,
      profileId: 'p1',
      tradeId: 'TRD-AAPL',
    },
    {
      symbol: 'MSFT',
      size: 2,
      entryPrice: 410,
      profileId: 'p1',
      tradeId: 'TRD-MSFT',
    },
  ]), []);

  const savedSetups = useMemo(() => ([
    {
      stock_instance_id: 'setup-aapl',
      symbol: 'AAPL',
      workflow_type: 'simple',
      simple_side: 'buy',
      status: 'simple_bought',
      active: true,
      is_crypto: false,
      is_real_trade: false,
    },
    {
      stock_instance_id: 'setup-msft',
      symbol: 'MSFT',
      workflow_type: 'simple',
      simple_side: 'buy',
      status: 'simple_bought',
      active: true,
      is_crypto: false,
      is_real_trade: false,
    },
  ] as any[]), []);

  const applyHoldingToDraft = (holding: { symbol: string; size: number; entryPrice: number; profileId?: string; tradeId?: string }) => {
    dispatch({
      type: 'apply-holding',
      tradeId: holding.tradeId || null,
      symbol: holding.symbol,
      quantity: String(holding.size),
    });
  };

  useTradePlansNavigationState({
    searchParams,
    setSearchParams,
    savedSetups,
    availableSellHoldings,
    applyHoldingToDraft,
    dispatch,
    setupCardRefs,
  });

  return (
    <div>
      <button type="button" onClick={() => setSearchParams({ setupId: 'setup-msft' })}>
        focus msft
      </button>
      <div data-testid="symbol">{uiState.draft.symbol}</div>
      <div data-testid="holding">{uiState.selectedHoldingTradeId || ''}</div>
      <div data-testid="focused">{uiState.focusedSetupId || ''}</div>
      <div data-testid="message">{uiState.message || ''}</div>
    </div>
  );
}

describe('useTradePlansNavigationState', () => {
  beforeEach(() => {
    vi.useFakeTimers();
    Object.defineProperty(window, 'requestAnimationFrame', {
      writable: true,
      value: (cb: FrameRequestCallback) => {
        cb(0);
        return 0;
      },
    });
    Object.defineProperty(Element.prototype, 'scrollIntoView', {
      writable: true,
      value: vi.fn(),
    });
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  it('applies sell prefill and responds to repeated same-page setup focus changes', () => {
    render(
      <MemoryRouter initialEntries={['/plans?mode=sell&symbol=AAPL&tradeId=TRD-AAPL']}>
        <NavigationHarness />
      </MemoryRouter>,
    );

    expect(screen.getByTestId('symbol').textContent).toBe('AAPL');
    expect(screen.getByTestId('holding').textContent).toBe('TRD-AAPL');
    expect(screen.getByTestId('message').textContent).toContain('Loaded AAPL from Portfolio');

    act(() => {
      screen.getByRole('button', { name: 'focus msft' }).click();
    });

    expect(screen.getByTestId('focused').textContent).toBe('setup-msft');
    expect(screen.getByTestId('message').textContent).toContain('Focused saved plan for MSFT');

    act(() => {
      vi.advanceTimersByTime(2200);
    });

    expect(screen.getByTestId('focused').textContent).toBe('');
  });
});
