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

vi.mock('@/services/employes.service', () => ({
  listEmployes: vi.fn(),
  getEmployeByCos: vi.fn(),
  createEmploye: vi.fn(),
  updateEmployeByCos: vi.fn(),
  deleteEmployeByCos: vi.fn(),
}));

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

import {
   listEmployes,
  getEmployeByCos,
  createEmploye,
  updateEmployeByCos,
  deleteEmployeByCos,
} from '@/services/employes.service';

import {
  getEmployesFeed,
  getEmployeDetails,
  createEmployeFeed,
  updateEmployeFeed,
  deleteEmployeFeed,
} from '../../../src/server/employes.server';


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

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

    vi.mocked(listEmployes).mockResolvedValue(employes as never);

    const result = await getEmployesFeed(25, 50);

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

  it('getEmployeDetails returns a public employe by technical cos', async () => {
    const employe = { id: 1, COS: 999 };

    vi.mocked(getEmployeByCos).mockResolvedValue(employe as never);

    const result = await getEmployeDetails(1);

    expect(getEmployeByCos).toHaveBeenCalledWith(1);
    expect(result).toEqual({
      employe: {
        id: 1,
        COS: 999,
        public: true,
      },
    });
  });

  it('getEmployeDetails returns null when Employe does not exist', async () => {
    vi.mocked(getEmployeByCos).mockResolvedValue(null as never);

    const result = await getEmployeDetails(999);

    expect(getEmployeByCos).toHaveBeenCalledWith(999);
    expect(result).toEqual({
      employe: null,
    });
  });


  it('createEmployeFeed creates and returns a public employe', async () => {
    const payload = {
      COS: 1937,
    };

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

    vi.mocked(createEmploye).mockResolvedValue(employe as never);

    const result = await createEmployeFeed(payload as any);

    expect(createEmploye).toHaveBeenCalledWith(payload);
    expect(result).toEqual({
      employe: {
        id: 1,
        COS: 1937,
        public: true,
      },
    });
  });

  it('updateEmployeFeed updates and returns a public employe', async () => {
    const payload = {
      POS: 'Développeur fullstack',
    };

    const employe = {
      id: 1,
      COS: 999,
    };

    vi.mocked(updateEmployeByCos).mockResolvedValue(employe as never);

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

    expect(updateEmployeByCos).toHaveBeenCalledWith(1, payload);
    expect(result).toEqual({
      employe: {
        id: 1,
        COS: 999,
        public: true,
      },
    });
  });

  it('deleteEmployeFeed deletes and returns a public employe', async () => {
    const employe = {
      id: 1,
      COS:999
    };

    vi.mocked(deleteEmployeByCos).mockResolvedValue(employe as never);

    const result = await deleteEmployeFeed(1);

    expect(deleteEmployeByCos).toHaveBeenCalledWith(1);
    expect(result).toEqual({
      employe: {
        id: 1,
        COS: 999,
        public: true,
      },
    });
  });
});