import { configureStore } from '@reduxjs/toolkit';
import PayrollReportsSlice, {
  fetchPayslipPreview,
  fetchTaxCertificatePreview,
  createBulkPayslips,
  fetchBulkPayslipStatus,
  createBulkTaxCertificates,
  fetchBulkTaxCertificateStatus,
  fetchPayslipArchives,
  fetchTaxCertArchives,
  fetchPensionPreview,
  fetchJournalPreview,
  fetchTaxSchedulePreview,
  clearPayslipPreview,
  clearTaxCertificatePreview,
} from '../PayrollReportsSlice';

global.URL.revokeObjectURL = jest.fn();

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

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

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

const createTestStore = () =>
  configureStore({ reducer: { payrollReports: PayrollReportsSlice.reducer } });

describe('PayrollReportsSlice', () => {
  beforeEach(() => jest.clearAllMocks());

  it('has correct initial state', () => {
    const store = createTestStore();
    const state = store.getState().payrollReports;
    expect(state.payslipPreviewUrl).toBeNull();
    expect(state.taxCertificatePreviewUrl).toBeNull();
    expect(state.bulkPayslipBatch).toBeNull();
    expect(state.bulkTaxCertificateBatch).toBeNull();
    expect(state.payslipArchives).toEqual([]);
    expect(state.taxCertArchives).toEqual([]);
    expect(state.archivesLoading).toBe(false);
    expect(state.pensionPreview).toBeNull();
    expect(state.journalPreview).toBeNull();
    expect(state.taxSchedulePreview).toBeNull();
    expect(state.loading).toBe(false);
    expect(state.downloading).toBe(false);
    expect(state.error).toBeNull();
  });

  describe('fetchPayslipPreview', () => {
    it('sets loading on pending and payslipPreviewUrl on fulfilled', () => {
      const store = createTestStore();
      store.dispatch({ type: fetchPayslipPreview.pending.type });
      expect(store.getState().payrollReports.loading).toBe(true);
      store.dispatch({ type: fetchPayslipPreview.fulfilled.type, payload: 'blob:url' });
      expect(store.getState().payrollReports.payslipPreviewUrl).toBe('blob:url');
      expect(store.getState().payrollReports.loading).toBe(false);
    });
  });

  describe('fetchTaxCertificatePreview', () => {
    it('sets taxCertificatePreviewUrl on fulfilled', () => {
      const store = createTestStore();
      store.dispatch({ type: fetchTaxCertificatePreview.fulfilled.type, payload: 'blob:cert' });
      expect(store.getState().payrollReports.taxCertificatePreviewUrl).toBe('blob:cert');
    });
  });

  describe('createBulkPayslips', () => {
    it('sets loading on pending and clears on fulfilled', () => {
      const store = createTestStore();
      store.dispatch({ type: createBulkPayslips.pending.type });
      expect(store.getState().payrollReports.loading).toBe(true);
      store.dispatch({ type: createBulkPayslips.fulfilled.type });
      expect(store.getState().payrollReports.loading).toBe(false);
    });
  });

  describe('fetchBulkPayslipStatus', () => {
    it('updates bulkPayslipBatch on fulfilled', () => {
      const store = createTestStore();
      const batch = { finished: false, progress: 50 };
      store.dispatch({ type: fetchBulkPayslipStatus.fulfilled.type, payload: batch });
      expect(store.getState().payrollReports.bulkPayslipBatch).toEqual(batch);
    });
  });

  describe('createBulkTaxCertificates', () => {
    it('sets loading on pending and clears on fulfilled', () => {
      const store = createTestStore();
      store.dispatch({ type: createBulkTaxCertificates.pending.type });
      expect(store.getState().payrollReports.loading).toBe(true);
      store.dispatch({ type: createBulkTaxCertificates.fulfilled.type });
      expect(store.getState().payrollReports.loading).toBe(false);
    });
  });

  describe('fetchBulkTaxCertificateStatus', () => {
    it('updates bulkTaxCertificateBatch on fulfilled', () => {
      const store = createTestStore();
      const batch = { finished: true, progress: 100 };
      store.dispatch({ type: fetchBulkTaxCertificateStatus.fulfilled.type, payload: batch });
      expect(store.getState().payrollReports.bulkTaxCertificateBatch).toEqual(batch);
    });
  });

  describe('fetchPayslipArchives', () => {
    it('sets archivesLoading and populates archives on fulfilled', () => {
      const store = createTestStore();
      store.dispatch({ type: fetchPayslipArchives.pending.type });
      expect(store.getState().payrollReports.archivesLoading).toBe(true);
      const archives = [{ id: 'a1', filename: 'payslips.zip' }];
      store.dispatch({ type: fetchPayslipArchives.fulfilled.type, payload: archives });
      expect(store.getState().payrollReports.payslipArchives).toEqual(archives);
      expect(store.getState().payrollReports.archivesLoading).toBe(false);
    });
  });

  describe('fetchTaxCertArchives', () => {
    it('populates tax cert archives on fulfilled', () => {
      const store = createTestStore();
      const archives = [{ id: 'a2', filename: 'certs.zip' }];
      store.dispatch({ type: fetchTaxCertArchives.fulfilled.type, payload: archives });
      expect(store.getState().payrollReports.taxCertArchives).toEqual(archives);
    });
  });

  describe('fetchPensionPreview', () => {
    it('populates pensionPreview on fulfilled', () => {
      const store = createTestStore();
      const preview = { headers: [], rows: [] };
      store.dispatch({ type: fetchPensionPreview.fulfilled.type, payload: preview });
      expect(store.getState().payrollReports.pensionPreview).toEqual(preview);
    });
  });

  describe('fetchJournalPreview', () => {
    it('populates journalPreview on fulfilled', () => {
      const store = createTestStore();
      const preview = { headers: [], rows: [] };
      store.dispatch({ type: fetchJournalPreview.fulfilled.type, payload: preview });
      expect(store.getState().payrollReports.journalPreview).toEqual(preview);
    });
  });

  describe('fetchTaxSchedulePreview', () => {
    it('populates taxSchedulePreview on fulfilled', () => {
      const store = createTestStore();
      const preview = { headers: [], rows: [] };
      store.dispatch({ type: fetchTaxSchedulePreview.fulfilled.type, payload: preview });
      expect(store.getState().payrollReports.taxSchedulePreview).toEqual(preview);
    });
  });

  describe('clearPayslipPreview', () => {
    it('clears payslipPreviewUrl', () => {
      const store = createTestStore();
      store.dispatch({ type: fetchPayslipPreview.fulfilled.type, payload: 'blob:url' });
      store.dispatch(clearPayslipPreview());
      expect(store.getState().payrollReports.payslipPreviewUrl).toBeNull();
    });
  });

  describe('clearTaxCertificatePreview', () => {
    it('clears taxCertificatePreviewUrl', () => {
      const store = createTestStore();
      store.dispatch({ type: fetchTaxCertificatePreview.fulfilled.type, payload: 'blob:cert' });
      store.dispatch(clearTaxCertificatePreview());
      expect(store.getState().payrollReports.taxCertificatePreviewUrl).toBeNull();
    });
  });
});
