import {
  CreateEmploymentStatusPayload,
  DeleteEmploymentStatusResponse,
  EmploymentStatus,
} from '@/interface/EmploymentStatus';
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 { EmploymentStatusActions } from './actionTypes';

interface EmploymentStatusState {
  employmentStatuses: EmploymentStatus[];
  loading: boolean;
  error: string | null;
}

const initialState: EmploymentStatusState = {
  employmentStatuses: [],
  loading: false,
  error: null,
};

export const fetchEmploymentStatuses = createAsyncThunk(
  EmploymentStatusActions.FETCH_EMPLOYMENT_STATUS_REQUEST,
  async () => {
    const response = (await apiGet(
      '/hr/employment-statuses',
    )) as AxiosResponse<EmploymentStatus[]>;
    return response.data;
  },
);

export const createEmploymentStatus = createAsyncThunk(
  EmploymentStatusActions.CREATE_EMPLOYMENT_STATUS_REQUEST,
  async (payload: CreateEmploymentStatusPayload, { rejectWithValue }) => {
    try {
      const response = (await apiPost(
        '/hr/employment-statuses',
        payload,
      )) as AxiosResponse<EmploymentStatus>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updateEmploymentStatus = createAsyncThunk(
  EmploymentStatusActions.UPDATE_EMPLOYMENT_STATUS_REQUEST,
  async (payload: CreateEmploymentStatusPayload, { rejectWithValue }) => {
    try {
      const response = (await apiPut(
        `/hr/employment-statuses/${payload.id}`,
        payload,
      )) as AxiosResponse<EmploymentStatus>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deleteEmploymentStatus = createAsyncThunk(
  EmploymentStatusActions.DELETE_EMPLOYMENT_STATUS_REQUEST,
  async (payload: string) => {
    const response = (await apiDelete(
      `/hr/employment-statuses/${payload}`,
    )) as AxiosResponse<DeleteEmploymentStatusResponse>;
    const responseData = response.data;
    responseData.id = payload;
    return responseData;
  },
);

export const EmploymentStatusSlice = createSlice({
  name: 'employmentStatuses',
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchEmploymentStatuses.pending, (state: Draft<EmploymentStatusState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchEmploymentStatuses.fulfilled,
        (state: Draft<EmploymentStatusState>, action: PayloadAction<EmploymentStatus[]>) => {
          state.employmentStatuses = action.payload;
          state.error = null;
          state.loading = false;
        },
      )
      .addCase(fetchEmploymentStatuses.rejected, (state: Draft<EmploymentStatusState>) => {
        state.loading = false;
        message.error(
          'Failed to load Employment Statuses. Please try again or contact support if the issue persists',
        );
      });

    builder
      .addCase(createEmploymentStatus.pending, (state: Draft<EmploymentStatusState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        createEmploymentStatus.fulfilled,
        (state: Draft<EmploymentStatusState>, action: PayloadAction<EmploymentStatus>) => {
          state.employmentStatuses.unshift(action.payload);
          state.error = null;
          state.loading = false;
        },
      )
      .addCase(
        createEmploymentStatus.rejected,
        (state: Draft<EmploymentStatusState>, action: RejectedActionPayload) => {
          state.loading = false;
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(updateEmploymentStatus.pending, (state: Draft<EmploymentStatusState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        updateEmploymentStatus.fulfilled,
        (state: Draft<EmploymentStatusState>, action: PayloadAction<EmploymentStatus>) => {
          state.loading = false;
          state.error = null;
          message.success('Successfully updated Employment Status', 10);
        },
      )
      .addCase(
        updateEmploymentStatus.rejected,
        (state: Draft<EmploymentStatusState>, action: RejectedActionPayload) => {
          state.loading = false;
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(deleteEmploymentStatus.pending, (state: Draft<EmploymentStatusState>) => {})
      .addCase(
        deleteEmploymentStatus.fulfilled,
        (
          state: Draft<EmploymentStatusState>,
          action: PayloadAction<DeleteEmploymentStatusResponse>,
        ) => {
          state.employmentStatuses = state.employmentStatuses.filter(
            (status) => status.id !== action.payload.id,
          );
          message.success(action.payload.message, 10);
        },
      )
      .addCase(deleteEmploymentStatus.rejected, (state: Draft<EmploymentStatusState>) => {
        message.error(
          'Failed to delete Employment Status. Please try again or contact support',
          10,
        );
      });
  },
});

export default EmploymentStatusSlice;
export type { EmploymentStatusState };
