import { describe, it, expect } from 'vitest';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { HttpResponse, http } from 'msw';
import { renderRoute } from './render';
import { server } from './mocks/server';

describe('Companies page', () => {
  it('renders page title', async () => {
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByRole('heading', { name: 'Companies' })).toBeInTheDocument();
    });
  });

  it('renders company list with tickers', async () => {
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('AAPL')).toBeInTheDocument();
    });
    expect(screen.getByText('MSFT')).toBeInTheDocument();
  });

  it('shows company names', async () => {
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('Apple Inc.')).toBeInTheDocument();
    });
    expect(screen.getByText('Microsoft Corporation')).toBeInTheDocument();
  });

  it('shows sector column', async () => {
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('AAPL')).toBeInTheDocument();
    });
    const row = screen.getByText('AAPL').closest('tr')!;
    expect(row).toHaveTextContent('Technology');
  });

  it('shows active status badge', async () => {
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('AAPL')).toBeInTheDocument();
    });
    const row = screen.getByText('AAPL').closest('tr')!;
    expect(row).toHaveTextContent('active');
  });

  it('shows source count', async () => {
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('AAPL')).toBeInTheDocument();
    });
    const row = screen.getByText('AAPL').closest('tr')!;
    expect(row).toHaveTextContent('3');
  });

  it('renders Add Company button', async () => {
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('Add Company')).toBeInTheDocument();
    });
  });

  it('shows add company form on button click', async () => {
    const user = userEvent.setup();
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('Add Company')).toBeInTheDocument();
    });
    await user.click(screen.getByText('Add Company'));
    await waitFor(() => {
      expect(screen.getByLabelText('Ticker')).toBeInTheDocument();
    });
    expect(screen.getByLabelText('Legal Name')).toBeInTheDocument();
    expect(screen.getByLabelText('Sector')).toBeInTheDocument();
    expect(screen.getByLabelText('Exchange')).toBeInTheDocument();
  });

  it('submits new company form', async () => {
    const user = userEvent.setup();
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('Add Company')).toBeInTheDocument();
    });
    await user.click(screen.getByText('Add Company'));
    await waitFor(() => {
      expect(screen.getByLabelText('Ticker')).toBeInTheDocument();
    });
    await user.type(screen.getByLabelText('Ticker'), 'GOOG');
    await user.type(screen.getByLabelText('Legal Name'), 'Alphabet Inc.');
    await user.click(screen.getByText('Create'));
    // Form should close on success
    await waitFor(() => {
      expect(screen.queryByLabelText('Ticker')).not.toBeInTheDocument();
    });
  });

  it('cancel closes the add form', async () => {
    const user = userEvent.setup();
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('Add Company')).toBeInTheDocument();
    });
    await user.click(screen.getByText('Add Company'));
    await waitFor(() => {
      expect(screen.getByText('Cancel')).toBeInTheDocument();
    });
    await user.click(screen.getByText('Cancel'));
    await waitFor(() => {
      expect(screen.queryByLabelText('Ticker')).not.toBeInTheDocument();
    });
  });

  it('shows empty state when no companies', async () => {
    server.use(
      http.get('/api/companies', () => HttpResponse.json([])),
    );
    renderRoute('/companies');
    await waitFor(() => {
      expect(screen.getByText('No data')).toBeInTheDocument();
    });
  });
});
