import { beforeEach, describe, expect, it, vi } from 'vitest';

const createServiceAppMock = vi.fn();
const registerOptionalJwtContextMock = vi.fn(async () => undefined);
const startServiceMock = vi.fn(async () => undefined);
const initCosmosIfNeededMock = vi.fn(async () => undefined);
const initDatastoreMock = vi.fn(() => undefined);

const appMock = {
  register: vi.fn(async () => undefined),
};

vi.mock('@bytelyst/fastify-core', () => ({
  createServiceApp: createServiceAppMock,
  registerOptionalJwtContext: registerOptionalJwtContextMock,
  startService: startServiceMock,
}));

vi.mock('jose', () => ({
  jwtVerify: vi.fn(async () => ({ payload: { sub: 'user_1', productId: 'bytelyst-notes' } })),
}));

vi.mock('./modules/note-agent-actions/routes.js', () => ({ noteAgentActionRoutes: vi.fn() }));
vi.mock('./modules/note-artifacts/routes.js', () => ({ noteArtifactRoutes: vi.fn() }));
vi.mock('./modules/notes/routes.js', () => ({ noteRoutes: vi.fn() }));
vi.mock('./modules/note-relationships/routes.js', () => ({ noteRelationshipRoutes: vi.fn() }));
vi.mock('./modules/note-tasks/routes.js', () => ({ noteTaskRoutes: vi.fn() }));
vi.mock('./modules/workspaces/routes.js', () => ({ workspaceRoutes: vi.fn() }));
vi.mock('./lib/cosmos-init.js', () => ({ initCosmosIfNeeded: initCosmosIfNeededMock }));
vi.mock('./lib/datastore.js', () => ({ initDatastore: initDatastoreMock }));
vi.mock('./lib/config.js', () => ({
  config: {
    SERVICE_NAME: 'bytelyst-notes-backend',
    CORS_ORIGIN: '*',
    PORT: 4016,
    HOST: '0.0.0.0',
    JWT_SECRET: 'test-secret',
  },
}));
vi.mock('./lib/product-config.js', () => ({ DISPLAY_NAME: 'ByteLyst Agentic Notes' }));

describe('server bootstrap', () => {
  beforeEach(() => {
    vi.resetModules();
    vi.clearAllMocks();
    createServiceAppMock.mockResolvedValue(appMock);
    appMock.register.mockReset();
    appMock.register.mockResolvedValue(undefined);
  });

  it('initializes app, routes, and starts service', async () => {
    await import('./server.js');

    expect(initCosmosIfNeededMock).toHaveBeenCalledOnce();
    expect(initDatastoreMock).toHaveBeenCalledOnce();
    expect(createServiceAppMock).toHaveBeenCalledOnce();
    expect(registerOptionalJwtContextMock).toHaveBeenCalledOnce();
    expect(appMock.register).toHaveBeenCalledTimes(6);
    expect(startServiceMock).toHaveBeenCalledWith(appMock, { port: 4016, host: '0.0.0.0' });
  });
});
