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

vi.mock('@/services/visites-medicales.service', () => ({
  listVisitesMedicales: vi.fn(),
  getVisiteMedicaleById: vi.fn(),
  createVisiteMedicale: vi.fn(),
  updateVisiteMedicaleById: vi.fn(),
  deleteVisiteMedicaleById: vi.fn(),
}));

vi.mock('@/server/public-entity', () => ({
  omitInternalId: vi.fn((entity) =>
    entity ? { ...entity, public: true } : entity
  ),
  omitInternalIdList: vi.fn((items) =>
    items.map((item: any) => ({ ...item, public: true }))
  ),
}));

import {
  listVisitesMedicales,
  getVisiteMedicaleById,
  createVisiteMedicale,
  updateVisiteMedicaleById,
  deleteVisiteMedicaleById,
} from '@/services/visites-medicales.service';

import {
  omitInternalId,
  omitInternalIdList,
} from '@/server/public-entity';

import {
  getVisitesMedicalesFeed,
  getVisiteMedicaleDetails,
  createVisiteMedicaleFeed,
  updateVisiteMedicaleFeed,
  deleteVisiteMedicaleFeed,
} from '../../../src/server/visites-medicales.server';

describe('Unit - visites medicales server', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('getVisitesMedicalesFeed returns a public feed', async () => {
    const items = [{ id: 1 }, { id: 2 }];

    vi.mocked(listVisitesMedicales).mockResolvedValue({
      items,
      count: 2,
    } as never);

    const result = await getVisitesMedicalesFeed(25, 50);

    expect(listVisitesMedicales).toHaveBeenCalledWith(25, 50);
    expect(omitInternalIdList).toHaveBeenCalledWith(items);

    expect(result).toEqual({
      items: [
        { id: 1, public: true },
        { id: 2, public: true },
      ],
      count: 2,
    });
  });

  it('getVisiteMedicaleDetails returns a public visite medicale by id', async () => {
    const visiteMedicale = { id: 1, id_salarie: 1937 };

    vi.mocked(getVisiteMedicaleById).mockResolvedValue(visiteMedicale as never);

    const result = await getVisiteMedicaleDetails(1);

    expect(getVisiteMedicaleById).toHaveBeenCalledWith(1);
    expect(omitInternalId).toHaveBeenCalledWith(visiteMedicale);

    expect(result).toEqual({
      visiteMedicale: {
        id: 1,
        id_salarie: 1937,
        public: true,
      },
    });
  });

  it('getVisiteMedicaleDetails returns null when visite medicale does not exist', async () => {
    vi.mocked(getVisiteMedicaleById).mockResolvedValue(null as never);

    const result = await getVisiteMedicaleDetails(999);

    expect(getVisiteMedicaleById).toHaveBeenCalledWith(999);

    expect(result).toEqual({
      visiteMedicale: null,
    });
  });

  it('createVisiteMedicaleFeed creates and returns a public visite medicale', async () => {
    const payload = {
      id_salarie: 1937,
      apt: 'Apte',
    };

    const visiteMedicale = {
      id: 1,
      ...payload,
    };

    vi.mocked(createVisiteMedicale).mockResolvedValue(visiteMedicale as never);

    const result = await createVisiteMedicaleFeed(payload as any);

    expect(createVisiteMedicale).toHaveBeenCalledWith(payload);
    expect(omitInternalId).toHaveBeenCalledWith(visiteMedicale);

    expect(result).toEqual({
      visiteMedicale: {
        id: 1,
        id_salarie: 1937,
        apt: 'Apte',
        public: true,
      },
    });
  });

  it('updateVisiteMedicaleFeed updates and returns a public visite medicale', async () => {
    const payload = {
      apt: 'Apte avec réserve',
    };

    const visiteMedicale = {
      id: 1,
      id_salarie: 1937,
      apt: 'Apte avec réserve',
    };

    vi.mocked(updateVisiteMedicaleById).mockResolvedValue(visiteMedicale as never);

    const result = await updateVisiteMedicaleFeed(1, payload as any);

    expect(updateVisiteMedicaleById).toHaveBeenCalledWith(1, payload);
    expect(omitInternalId).toHaveBeenCalledWith(visiteMedicale);

    expect(result).toEqual({
      visiteMedicale: {
        id: 1,
        id_salarie: 1937,
        apt: 'Apte avec réserve',
        public: true,
      },
    });
  });

  it('deleteVisiteMedicaleFeed deletes and returns a public visite medicale', async () => {
    const visiteMedicale = {
      id: 1,
      id_salarie: 1937,
    };

    vi.mocked(deleteVisiteMedicaleById).mockResolvedValue(visiteMedicale as never);

    const result = await deleteVisiteMedicaleFeed(1);

    expect(deleteVisiteMedicaleById).toHaveBeenCalledWith(1);
    expect(omitInternalId).toHaveBeenCalledWith(visiteMedicale);

    expect(result).toEqual({
      visiteMedicale: {
        id: 1,
        id_salarie: 1937,
        public: true,
      },
    });
  });
});