import {
  PensionEnrollment,
  CreatePensionEnrollmentPayload,
  UpdatePensionEnrollmentPayload,
} from '@/interface/PensionEnrollment';
import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import { apiDelete, apiGet, apiPost, apiPut } from '@/services/api/api';
import Helpers from '@/utilities/Helpers';
import { createAsyncThunk, createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';
import { message } from 'antd';
import axios, { AxiosResponse } from 'axios';
import { EmployeePensionEnrollmentsActions } from './actionTypes';

interface EmployeePensionEnrollmentsState {
  enrollments: PensionEnrollment[];
  loading: boolean;
  error: string | null;
}

const initialState: EmployeePensionEnrollmentsState = {
  enrollments: [],
  loading: false,
  error: null,
};

export const fetchPensionEnrollments = createAsyncThunk(
  EmployeePensionEnrollmentsActions.FETCH_ENROLLMENTS_REQUEST,
  async (employeeId: string) => {
    const response = (await apiGet(
      `/payroll/employees/${employeeId}/pension-enrollments`,
    )) as AxiosResponse<PensionEnrollment[]>;
    return response.data;
  },
);

export const createPensionEnrollment = createAsyncThunk(
  EmployeePensionEnrollmentsActions.CREATE_ENROLLMENT_REQUEST,
  async (payload: CreatePensionEnrollmentPayload, { rejectWithValue }) => {
    try {
      const { employee_id, ...data } = payload;
      const response = (await apiPost(
        `/payroll/employees/${employee_id}/pension-enrollments`,
        data,
      )) as AxiosResponse<{ data: PensionEnrollment }>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updatePensionEnrollment = createAsyncThunk(
  EmployeePensionEnrollmentsActions.UPDATE_ENROLLMENT_REQUEST,
  async (payload: UpdatePensionEnrollmentPayload, { rejectWithValue }) => {
    try {
      const { id, ...data } = payload;
      const response = (await apiPut(
        `/payroll/pension-enrollments/${id}`,
        data,
      )) as AxiosResponse<{ data: PensionEnrollment }>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deletePensionEnrollment = createAsyncThunk(
  EmployeePensionEnrollmentsActions.DELETE_ENROLLMENT_REQUEST,
  async (id: string, { rejectWithValue }) => {
    try {
      await apiDelete(`/payroll/pension-enrollments/${id}`);
      return id;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const EmployeePensionEnrollmentsSlice = createSlice({
  name: 'employeePensionEnrollments',
  initialState,
  reducers: {
    clearEnrollments(state) {
      state.enrollments = [];
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchPensionEnrollments.pending, (state: Draft<EmployeePensionEnrollmentsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchPensionEnrollments.fulfilled,
        (
          state: Draft<EmployeePensionEnrollmentsState>,
          action: PayloadAction<PensionEnrollment[]>,
        ) => {
          state.enrollments = action.payload;
          state.loading = false;
          state.error = null;
        },
      )
      .addCase(fetchPensionEnrollments.rejected, (state: Draft<EmployeePensionEnrollmentsState>, action: RejectedActionPayload) => {
        state.loading = false;
        state.error = 'Failed to load pension enrollments';
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(createPensionEnrollment.pending, (state: Draft<EmployeePensionEnrollmentsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        createPensionEnrollment.fulfilled,
        (
          state: Draft<EmployeePensionEnrollmentsState>,
          action: PayloadAction<PensionEnrollment>,
        ) => {
          state.enrollments.push(action.payload);
          state.loading = false;
          state.error = null;
          message.success('Pension enrollment created successfully');
        },
      )
      .addCase(
        createPensionEnrollment.rejected,
        (state: Draft<EmployeePensionEnrollmentsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(updatePensionEnrollment.pending, (state: Draft<EmployeePensionEnrollmentsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        updatePensionEnrollment.fulfilled,
        (
          state: Draft<EmployeePensionEnrollmentsState>,
          action: PayloadAction<PensionEnrollment>,
        ) => {
          const index = state.enrollments.findIndex((e) => e.id === action.payload.id);
          if (index !== -1) state.enrollments[index] = action.payload;
          state.loading = false;
          state.error = null;
          message.success('Pension enrollment updated successfully');
        },
      )
      .addCase(
        updatePensionEnrollment.rejected,
        (state: Draft<EmployeePensionEnrollmentsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(deletePensionEnrollment.pending, (state: Draft<EmployeePensionEnrollmentsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        deletePensionEnrollment.fulfilled,
        (state: Draft<EmployeePensionEnrollmentsState>, action: PayloadAction<string>) => {
          state.enrollments = state.enrollments.filter((e) => e.id !== action.payload);
          state.loading = false;
          state.error = null;
          message.success('Pension enrollment deleted successfully');
        },
      )
      .addCase(
        deletePensionEnrollment.rejected,
        (state: Draft<EmployeePensionEnrollmentsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );
  },
});

export const { clearEnrollments } = EmployeePensionEnrollmentsSlice.actions;
export default EmployeePensionEnrollmentsSlice;
