import { configureStore } from '@reduxjs/toolkit';
import { BranchSlice, fetchBranches, createBranch, deleteBranch, fetchBranch, fetchSystemDefaultWorkingDays } from '../BranchSlice';

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: { branches: BranchSlice.reducer } });

describe('BranchSlice', () => {
  it('has correct initial state', () => {
    const store = createStore();
    const state = store.getState().branches;
    expect(state.branches).toEqual([]);
    expect(state.loading).toBe(false);
    expect(state.error).toBeNull();
    expect(state.systemDefaultWorkingDays).toBeNull();
    expect(state.systemDefaultLoading).toBe(false);
  });

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

    it('populates branches on fulfilled', () => {
      const store = createStore();
      const branches = [{ branch_id: 'b1', name: 'HQ' }];
      store.dispatch({ type: fetchBranches.fulfilled.type, payload: branches });
      expect(store.getState().branches.branches).toEqual(branches);
      expect(store.getState().branches.loading).toBe(false);
    });

    it('sets loading false on rejected', () => {
      const store = createStore();
      store.dispatch({ type: fetchBranches.pending.type });
      store.dispatch({ type: fetchBranches.rejected.type });
      expect(store.getState().branches.loading).toBe(false);
    });
  });

  describe('createBranch', () => {
    it('prepends branch on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchBranches.fulfilled.type, payload: [{ branch_id: 'b1' }] });
      store.dispatch({ type: createBranch.fulfilled.type, payload: { branch: { branch_id: 'b2' }, message: 'Created' } });
      expect(store.getState().branches.branches[0].branch_id).toBe('b2');
    });
  });

  describe('deleteBranch', () => {
    it('removes branch on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchBranches.fulfilled.type, payload: [{ branch_id: 'b1' }, { branch_id: 'b2' }] });
      store.dispatch({ type: deleteBranch.fulfilled.type, payload: { branch_id: 'b1', message: 'Deleted' } });
      expect(store.getState().branches.branches).toHaveLength(1);
    });
  });

  describe('fetchBranch', () => {
    it('sets branch on fulfilled', () => {
      const store = createStore();
      const branch = { branch_id: 'b1', name: 'HQ' };
      store.dispatch({ type: fetchBranch.fulfilled.type, payload: branch });
      expect(store.getState().branches.branch).toEqual(branch);
      expect(store.getState().branches.loading).toBe(false);
    });
  });

  describe('fetchSystemDefaultWorkingDays', () => {
    it('sets systemDefaultWorkingDays on fulfilled', () => {
      const store = createStore();
      const data = { id: '1', working_days: [] };
      store.dispatch({ type: fetchSystemDefaultWorkingDays.fulfilled.type, payload: data });
      expect(store.getState().branches.systemDefaultWorkingDays).toEqual(data);
      expect(store.getState().branches.systemDefaultLoading).toBe(false);
    });
  });
});
