import { configureStore } from '@reduxjs/toolkit';
import IncidentSlice, { fetchIncidents, fetchIncident, createIncident, updateIncident, updateIncidentStatus, fetchIncidentInjuries, createIncidentInjury, deleteIncidentInjury, fetchIncidentDocuments, uploadIncidentDocument, deleteIncidentDocument, fetchIncidentWitnesses, createIncidentWitness, fetchCorrectiveActions, createCorrectiveAction, fetchRegulatoryReports, createRegulatoryReport, fetchIncidentTimeline, fetchIncidentStats, clearIncidentState } from '../IncidentSlice';

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: { incidents: IncidentSlice.reducer } });

describe('IncidentSlice', () => {
  it('has correct initial state', () => {
    const store = createStore();
    const state = store.getState().incidents;
    expect(state.incidents).toEqual([]);
    expect(state.incident).toBeNull();
    expect(state.injuries).toEqual([]);
    expect(state.documents).toEqual([]);
    expect(state.witnesses).toEqual([]);
    expect(state.correctiveActions).toEqual([]);
    expect(state.regulatoryReports).toEqual([]);
    expect(state.timeline).toEqual([]);
    expect(state.stats).toBeNull();
    expect(state.loading).toBe(false);
    expect(state.subLoading).toBe(false);
    expect(state.error).toBeNull();
  });

  describe('reducers', () => {
    it('clearIncidentState resets detail fields', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncident.fulfilled.type, payload: { id: 'i1' } });
      store.dispatch(clearIncidentState());
      const state = store.getState().incidents;
      expect(state.incident).toBeNull();
      expect(state.injuries).toEqual([]);
      expect(state.documents).toEqual([]);
      expect(state.witnesses).toEqual([]);
      expect(state.correctiveActions).toEqual([]);
      expect(state.regulatoryReports).toEqual([]);
      expect(state.timeline).toEqual([]);
    });
  });

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

    it('populates incidents on fulfilled', () => {
      const store = createStore();
      const incidents = [{ id: 'i1', title: 'Slip' }];
      store.dispatch({ type: fetchIncidents.fulfilled.type, payload: incidents });
      expect(store.getState().incidents.incidents).toEqual(incidents);
      expect(store.getState().incidents.loading).toBe(false);
    });
  });

  describe('createIncident', () => {
    it('prepends incident on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidents.fulfilled.type, payload: [{ id: 'i1' }] });
      store.dispatch({ type: createIncident.fulfilled.type, payload: { id: 'i2' } });
      expect(store.getState().incidents.incidents[0].id).toBe('i2');
      expect(store.getState().incidents.incident?.id).toBe('i2');
    });
  });

  describe('updateIncident', () => {
    it('updates incident in list on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidents.fulfilled.type, payload: [{ id: 'i1', title: 'Old' }] });
      store.dispatch({ type: updateIncident.fulfilled.type, payload: { id: 'i1', title: 'New' } });
      expect(store.getState().incidents.incidents[0].title).toBe('New');
    });
  });

  describe('updateIncidentStatus', () => {
    it('updates status in list on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidents.fulfilled.type, payload: [{ id: 'i1', status: 'open' }] });
      store.dispatch({ type: updateIncidentStatus.fulfilled.type, payload: { id: 'i1', status: 'closed' } });
      expect(store.getState().incidents.incidents[0].status).toBe('closed');
    });
  });

  describe('fetchIncidentInjuries', () => {
    it('populates injuries on fulfilled', () => {
      const store = createStore();
      const injuries = [{ id: 'inj1' }];
      store.dispatch({ type: fetchIncidentInjuries.fulfilled.type, payload: injuries });
      expect(store.getState().incidents.injuries).toEqual(injuries);
    });
  });

  describe('createIncidentInjury', () => {
    it('prepends injury on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidentInjuries.fulfilled.type, payload: [{ id: 'inj1' }] });
      store.dispatch({ type: createIncidentInjury.fulfilled.type, payload: { id: 'inj2' } });
      expect(store.getState().incidents.injuries[0].id).toBe('inj2');
    });
  });

  describe('deleteIncidentInjury', () => {
    it('removes injury on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidentInjuries.fulfilled.type, payload: [{ id: 'inj1' }, { id: 'inj2' }] });
      store.dispatch({ type: deleteIncidentInjury.fulfilled.type, payload: { injury_id: 'inj1', message: 'Deleted' } });
      expect(store.getState().incidents.injuries).toHaveLength(1);
    });
  });

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

  describe('uploadIncidentDocument', () => {
    it('prepends document on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidentDocuments.fulfilled.type, payload: [{ id: 'doc1' }] });
      store.dispatch({ type: uploadIncidentDocument.fulfilled.type, payload: { id: 'doc2' } });
      expect(store.getState().incidents.documents[0].id).toBe('doc2');
    });
  });

  describe('deleteIncidentDocument', () => {
    it('removes document on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidentDocuments.fulfilled.type, payload: [{ id: 'doc1' }] });
      store.dispatch({ type: deleteIncidentDocument.fulfilled.type, payload: { document_id: 'doc1', message: 'Deleted' } });
      expect(store.getState().incidents.documents).toHaveLength(0);
    });
  });

  describe('fetchIncidentWitnesses', () => {
    it('populates witnesses on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidentWitnesses.fulfilled.type, payload: [{ id: 'w1' }] });
      expect(store.getState().incidents.witnesses).toHaveLength(1);
    });
  });

  describe('createIncidentWitness', () => {
    it('prepends witness on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidentWitnesses.fulfilled.type, payload: [{ id: 'w1' }] });
      store.dispatch({ type: createIncidentWitness.fulfilled.type, payload: { id: 'w2' } });
      expect(store.getState().incidents.witnesses[0].id).toBe('w2');
    });
  });

  describe('fetchCorrectiveActions', () => {
    it('populates correctiveActions on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchCorrectiveActions.fulfilled.type, payload: [{ id: 'ca1' }] });
      expect(store.getState().incidents.correctiveActions).toHaveLength(1);
    });
  });

  describe('createCorrectiveAction', () => {
    it('prepends action on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchCorrectiveActions.fulfilled.type, payload: [{ id: 'ca1' }] });
      store.dispatch({ type: createCorrectiveAction.fulfilled.type, payload: { id: 'ca2' } });
      expect(store.getState().incidents.correctiveActions[0].id).toBe('ca2');
    });
  });

  describe('fetchRegulatoryReports', () => {
    it('populates regulatoryReports on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchRegulatoryReports.fulfilled.type, payload: [{ id: 'rr1' }] });
      expect(store.getState().incidents.regulatoryReports).toHaveLength(1);
    });
  });

  describe('createRegulatoryReport', () => {
    it('prepends report on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchRegulatoryReports.fulfilled.type, payload: [{ id: 'rr1' }] });
      store.dispatch({ type: createRegulatoryReport.fulfilled.type, payload: { id: 'rr2' } });
      expect(store.getState().incidents.regulatoryReports[0].id).toBe('rr2');
    });
  });

  describe('fetchIncidentTimeline', () => {
    it('populates timeline on fulfilled', () => {
      const store = createStore();
      store.dispatch({ type: fetchIncidentTimeline.fulfilled.type, payload: [{ id: 't1' }] });
      expect(store.getState().incidents.timeline).toHaveLength(1);
    });
  });

  describe('fetchIncidentStats', () => {
    it('populates stats on fulfilled', () => {
      const store = createStore();
      const stats = { total: 5, open: 3 };
      store.dispatch({ type: fetchIncidentStats.fulfilled.type, payload: stats });
      expect(store.getState().incidents.stats).toEqual(stats);
    });
  });
});
