import React from 'react';
import '@testing-library/jest-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { ConfirmProvider } from './confirm';
import { PromptProvider } from './prompt';
import { ToastProvider } from './toast';
import { I18nProvider } from './i18n/I18nProvider';
import JobDetailsDialog from './components/JobDetailsDialog';
import { api } from './api';

jest.setTimeout(15000);

jest.mock('./api', () => ({
  api: {
    get: jest.fn(),
    post: jest.fn(() => Promise.resolve({ data: {} })),
    put: jest.fn(() => Promise.resolve({ data: {} })),
    patch: jest.fn(() => Promise.resolve({ data: {} })),
    delete: jest.fn(() => Promise.resolve({ data: {} })),
    interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } },
  },
  getApiErrorMessage: jest.fn(() => 'error'),
}));

const mockedApi = api as jest.Mocked<typeof api>;

function renderDialog() {
  return render(
    <ToastProvider>
      <I18nProvider>
        <ConfirmProvider>
          <PromptProvider>
            <JobDetailsDialog open jobId={42} onClose={() => {}} />
          </PromptProvider>
        </ConfirmProvider>
      </I18nProvider>
    </ToastProvider>,
  );
}

beforeEach(() => {
  mockedApi.get.mockImplementation((url: string) => {
    if (url === '/jobapplications/42') {
      return Promise.resolve({ data: { id: 42, jobTitle: 'Backend Developer', status: 'Applied', dateApplied: new Date().toISOString(), daysSince: 3, company: { name: 'Acme' } } } as any);
    }
    if (url === '/jobapplications/42/status-suggestion') {
      return Promise.resolve({ data: { hasSuggestion: true, suggestedStatus: 'Interview', currentStatus: 'Applied', signal: 'schedule an interview', confidence: 'medium' } } as any);
    }
    if (url === '/auth/me') return Promise.resolve({ data: { roles: [] } } as any);
    if (url === '/jobapplications/42/history') return Promise.resolve({ data: [] } as any);
    if (url === '/attachments/42') return Promise.resolve({ data: [] } as any);
    return Promise.resolve({ data: {} } as any);
  });
});

afterEach(() => {
  jest.clearAllMocks();
});

test('status suggestion banner appears and applies via PATCH', async () => {
  renderDialog();

  expect(await screen.findByText(/looks like a move to interview/i)).toBeInTheDocument();

  fireEvent.click(await screen.findByRole('button', { name: /move to interview/i }));

  await waitFor(() => {
    expect(mockedApi.patch).toHaveBeenCalledWith('/jobapplications/42/status', { status: 'Interview' });
  });
});

test('no banner when there is no suggestion', async () => {
  mockedApi.get.mockImplementation((url: string) => {
    if (url === '/jobapplications/42') {
      return Promise.resolve({ data: { id: 42, jobTitle: 'Backend Developer', status: 'Applied', dateApplied: new Date().toISOString(), daysSince: 3, company: { name: 'Acme' } } } as any);
    }
    if (url === '/jobapplications/42/status-suggestion') {
      return Promise.resolve({ data: { hasSuggestion: false } } as any);
    }
    if (url === '/auth/me') return Promise.resolve({ data: { roles: [] } } as any);
    if (url === '/jobapplications/42/history') return Promise.resolve({ data: [] } as any);
    if (url === '/attachments/42') return Promise.resolve({ data: [] } as any);
    return Promise.resolve({ data: {} } as any);
  });

  renderDialog();

  expect(await screen.findByText(/backend developer/i)).toBeInTheDocument();
  expect(screen.queryByText(/looks like a move to/i)).not.toBeInTheDocument();
});
