import React from 'react';
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import { MemoryRouter, Route, Routes } from 'react-router-dom';

import CvBuilderEditor from './views/CvBuilderEditor';
import { I18nProvider } from './i18n/I18nProvider';
import { ToastProvider } from './toast';
import { api } from './api';
import { emptyCvVariantSettings } from './cvBuilder';

// The Application Workspace CV section deep-links straight into the builder at
// /career/builder/:id. These tests cover that entry point: the variant loads, and a variant the
// server refuses (missing, or someone else's) lands on a safe error state rather than a blank editor.
jest.mock('./api', () => ({
  api: {
    get: jest.fn(),
    post: jest.fn(),
    put: jest.fn(),
    delete: jest.fn(),
    interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } },
  },
  getApiErrorMessage: (_e: any, fallback?: string) => fallback || 'Request failed.',
}));

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

const variant = {
  id: 3,
  name: 'Backend CV',
  settings: emptyCvVariantSettings(),
  isPublic: false,
  publicSlug: 'abc123',
  version: 4,
  jobApplicationId: 7,
  updatedAtUtc: '2026-07-19T10:00:00Z',
};

function renderAt(id: number) {
  return render(
    <I18nProvider>
      <ToastProvider>
        <MemoryRouter initialEntries={[`/career/builder/${id}`]}>
          <Routes>
            <Route path="/career/builder/:id" element={<CvBuilderEditor />} />
          </Routes>
        </MemoryRouter>
      </ToastProvider>
    </I18nProvider>,
  );
}

beforeEach(() => {
  jest.clearAllMocks();
  mockedApi.post.mockResolvedValue({ data: { themeId: 'nordic', html: '<p>cv</p>', suggestedFileName: 'cv.pdf' } } as any);
});

function routeGet(onVariant: () => Promise<any>) {
  mockedApi.get.mockImplementation((url: string) => {
    if (url === '/cv/variants/3') return onVariant();
    if (url === '/cv/themes') return Promise.resolve({ data: [] } as any);
    if (url === '/cv/outline') return Promise.resolve({ data: { sections: [] } } as any);
    return Promise.resolve({ data: [] } as any);
  });
}

test('deep link loads the exact variant named in the route', async () => {
  routeGet(() => Promise.resolve({ data: variant } as any));

  renderAt(3);

  expect(await screen.findByDisplayValue('Backend CV')).toBeInTheDocument();
  expect(mockedApi.get).toHaveBeenCalledWith('/cv/variants/3');
});

test('a variant that does not exist shows a safe error instead of an empty editor', async () => {
  routeGet(() => Promise.reject(new Error('404')));

  renderAt(3);

  expect(await screen.findByText(/Could not open this CV/i)).toBeInTheDocument();
  expect(screen.queryByDisplayValue('Backend CV')).not.toBeInTheDocument();
});

test("another user's variant is refused by the server and never rendered", async () => {
  // Ownership is enforced server-side: CvVariantService scopes every read to the owner and the
  // controller returns 404, so the client only ever sees the same safe failure.
  routeGet(() => Promise.reject({ response: { status: 404 } }));

  renderAt(3);

  expect(await screen.findByText(/Could not open this CV/i)).toBeInTheDocument();
});
