import { configureStore } from '@reduxjs/toolkit';
import EmployeeSelfServiceSlice, { fetchMyProfile, updateMyProfile, fetchMyEmergencyContacts, createEmergencyContact, deleteEmergencyContact, fetchMyDependents, fetchMyQualifications, fetchMyDocuments, fetchMyAssets, fetchMyJobHistory } from '../EmployeeSelfServiceSlice';

jest.mock('@/services/api/api', () => ({
  apiGet: jest.fn(),
  apiPost: jest.fn(),
  apiPut: jest.fn(),
  apiDelete: jest.fn(),
}));

jest.mock('antd', () => ({
  message: { success: jest.fn(), error: jest.fn(), warning: jest.fn() },
}));

jest.mock('@/utilities/Helpers', () => ({
  default: { handleServerError: jest.fn((e) => e?.message || 'Error') },
}));

const createStore = () => configureStore({ reducer: { ess: EmployeeSelfServiceSlice.reducer } });

describe('EmployeeSelfServiceSlice', () => {
  it('has correct initial state', () => {
    const store = createStore();
    const state = store.getState().ess;
    expect(state.profile).toBeNull();
    expect(state.emergencyContacts).toEqual([]);
    expect(state.dependents).toEqual([]);
    expect(state.qualifications).toEqual([]);
    expect(state.documents).toEqual([]);
    expect(state.assets).toEqual([]);
    expect(state.jobHistory).toEqual([]);
    expect(state.loading).toBe(false);
    expect(state.actionLoading).toBe(false);
    expect(state.error).toBeNull();
  });

  describe('fetchMyProfile', () => {
    it('sets loading on pending', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyProfile.pending.type });
      expect(store.getState().ess.loading).toBe(true);
    });

    it('sets profile on fulfilled', () => {
      const store = createStore();
      const profile = { employee_id: 'e1', staff_id: 'S001', firstname: 'John', lastname: 'Doe' };
      store.dispatch({ type: fetchMyProfile.fulfilled.type, payload: profile });
      expect(store.getState().ess.profile).toEqual(profile);
      expect(store.getState().ess.loading).toBe(false);
    });
  });

  describe('updateMyProfile', () => {
    it('sets actionLoading on pending', () => {
      const store = createStore();
      store.dispatch({ type: updateMyProfile.pending.type });
      expect(store.getState().ess.actionLoading).toBe(true);
    });

    it('updates profile on fulfilled', () => {
      const store = createStore();
      const payload = { data: { employee_id: 'e1', firstname: 'Jane', lastname: 'Doe', staff_id: 'S001' }, message: 'Updated' };
      store.dispatch({ type: updateMyProfile.fulfilled.type, payload });
      expect(store.getState().ess.profile?.firstname).toBe('Jane');
      expect(store.getState().ess.actionLoading).toBe(false);
    });
  });

  describe('fetchMyEmergencyContacts', () => {
    it('populates contacts on fulfilled', () => {
      const store = createStore();
      const contacts = [{ id: 'c1', name: 'Mom', relationship: 'Mother', phone: '123' }];
      store.dispatch({ type: fetchMyEmergencyContacts.fulfilled.type, payload: contacts });
      expect(store.getState().ess.emergencyContacts).toEqual(contacts);
    });
  });

  describe('createEmergencyContact', () => {
    it('appends contact on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyEmergencyContacts.fulfilled.type, payload: [{ id: 'c1' }] });
      store.dispatch({ type: createEmergencyContact.fulfilled.type, payload: { data: { id: 'c2' }, message: 'Created' } });
      expect(store.getState().ess.emergencyContacts).toHaveLength(2);
    });
  });

  describe('deleteEmergencyContact', () => {
    it('removes contact on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyEmergencyContacts.fulfilled.type, payload: [{ id: 'c1' }, { id: 'c2' }] });
      store.dispatch({ type: deleteEmergencyContact.fulfilled.type, payload: 'c1' });
      expect(store.getState().ess.emergencyContacts).toHaveLength(1);
    });
  });

  describe('fetchMyDependents', () => {
    it('populates dependents on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyDependents.fulfilled.type, payload: [{ id: 'd1' }] });
      expect(store.getState().ess.dependents).toHaveLength(1);
    });
  });

  describe('fetchMyQualifications', () => {
    it('populates qualifications on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyQualifications.fulfilled.type, payload: [{ id: 'q1' }] });
      expect(store.getState().ess.qualifications).toHaveLength(1);
    });
  });

  describe('fetchMyDocuments', () => {
    it('populates documents on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyDocuments.fulfilled.type, payload: [{ id: 'doc1' }] });
      expect(store.getState().ess.documents).toHaveLength(1);
    });
  });

  describe('fetchMyAssets', () => {
    it('populates assets on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyAssets.fulfilled.type, payload: [{ id: 'a1' }] });
      expect(store.getState().ess.assets).toHaveLength(1);
    });
  });

  describe('fetchMyJobHistory', () => {
    it('populates jobHistory on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchMyJobHistory.fulfilled.type, payload: [{ id: 'j1' }] });
      expect(store.getState().ess.jobHistory).toHaveLength(1);
    });
  });
});
