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

vi.mock('@/services/diplomes.service', () => ({
  listDiplomes: vi.fn(),
  getDiplomeById: vi.fn(),
  createDiplome: vi.fn(),
  updateDiplomeById: vi.fn(),
  deleteDiplomeById: vi.fn(),
}));

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

import {
   listDiplomes,
  getDiplomeById,
  createDiplome,
  updateDiplomeById,
  deleteDiplomeById,
} from '@/services/diplomes.service';

import {
  getDiplomesFeed,
  getDiplomeDetails,
  createDiplomeFeed,
  updateDiplomeFeed,
  deleteDiplomeFeed,
} from '../../../src/server/diplomes.server';

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

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

    vi.mocked(listDiplomes).mockResolvedValue(diplomes as never);

    const result = await getDiplomesFeed(25, 50);

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

  it('getDiplomeDetails returns a public diplome by technical id', async () => {
    const diplome = { id: 1, id_salarie: 5524, diplome: "bac"};

    vi.mocked(getDiplomeById).mockResolvedValue(diplome as never);

    const result = await getDiplomeDetails(1);

    expect(getDiplomeById).toHaveBeenCalledWith(1);
    expect(result).toEqual({
      diplome: {
        id: 1,
        id_salarie: 5524, diplome: "bac",
        public: true,
      },
    });
  });

  it('getDiplomeDetails returns null when diplome does not exist', async () => {
    vi.mocked(getDiplomeById).mockResolvedValue(null as never);

    const result = await getDiplomeDetails(999);

    expect(getDiplomeById).toHaveBeenCalledWith(999);
    expect(result).toEqual({
      diplome: null,
    });
  });


  it('createDiplomeFeed creates and returns a public diplome', async () => {
    const payload = {
      id_salarie: 5524, diplome: "bac"
    };

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

    vi.mocked(createDiplome).mockResolvedValue(diplome as never);

    const result = await createDiplomeFeed(payload as any);

    expect(createDiplome).toHaveBeenCalledWith(payload);
    expect(result).toEqual({
      diplome: {
        id: 1,
        id_salarie: 5524, diplome: "bac",
        public: true,
      },
    });
  });

  it('updateDiplomeFeed updates and returns a public diplome', async () => {
    const payload = {
      id_salarie: 5524, diplome: "bac"
    };

    const diplome = {
      id: 1,
      id_salarie: 5524, diplome: "bac"
    };

    vi.mocked(updateDiplomeById).mockResolvedValue(diplome as never);

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

    expect(updateDiplomeById).toHaveBeenCalledWith(1, payload);
    expect(result).toEqual({
      diplome: {
        id: 1,
        id_salarie: 5524, diplome: "bac",
        public: true,
      },
    });
  });

  it('deleteDiplomeFeed deletes and returns a public diplome', async () => {
    const diplome = {
      id: 1,
      id_salarie: 5524, diplome: "bac"
    };

    vi.mocked(deleteDiplomeById).mockResolvedValue(diplome as never);

    const result = await deleteDiplomeFeed(1);

    expect(deleteDiplomeById).toHaveBeenCalledWith(1);
    expect(result).toEqual({
      diplome: {
        id: 1,
       id_salarie: 5524, diplome: "bac",
        public: true,
      },
    });
  });
});
