import React, { useContext } from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import { AuthContext, AuthProvider } from './AuthContext';

const Probe = () => {
  const { authenticated, loading, setAuthentication } = useContext(AuthContext);

  if (loading) {
    return <div>loading</div>;
  }

  return (
    <div>
      <span data-testid="auth-state">{authenticated ? 'yes' : 'no'}</span>
      <button type="button" onClick={() => setAuthentication(true)}>
        login
      </button>
    </div>
  );
};

const renderWithProvider = () =>
  render(
    <MemoryRouter>
      <AuthProvider>
        <Probe />
      </AuthProvider>
    </MemoryRouter>
  );

/** Minimal JWT payload with exp far in the future (year 2286). */
const FUTURE_TOKEN =
  'eyJhbGciOiJub25lIn0.eyJleHAiOjE5OTk5OTk5OTk5fQ.';

describe('AuthProvider', () => {
  beforeEach(() => {
    localStorage.clear();
  });

  it('starts unauthenticated when no token stored', async () => {
    renderWithProvider();

    await waitFor(() => {
      expect(screen.queryByText('loading')).not.toBeInTheDocument();
    });
    expect(screen.getByTestId('auth-state')).toHaveTextContent('no');
  });

  it('authenticates when valid access token present', async () => {
    localStorage.setItem('access_token', FUTURE_TOKEN);
    renderWithProvider();

    await waitFor(() => {
      expect(screen.getByTestId('auth-state')).toHaveTextContent('yes');
    });
  });

  it('updates authenticated state via setAuthentication', async () => {
    const user = userEvent.setup();
    renderWithProvider();

    await waitFor(() => {
      expect(screen.getByTestId('auth-state')).toHaveTextContent('no');
    });

    await user.click(screen.getByRole('button', { name: 'login' }));
    expect(screen.getByTestId('auth-state')).toHaveTextContent('yes');
  });
});
