import {
  CreateEmergencyContactPayload,
  DeleteEmergencyContactPayload,
  DeleteEmergencyContactResponse,
  EmergencyContact,
  UpdateEmergencyContactPayload,
} from '@/interface/EmergencyContact';
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 { EmergencyContactActions } from './actionTypes';

interface EmergencyContactState {
  contacts: EmergencyContact[];
  relationshipTypes: any;
  loading: boolean;
  error: string | null;
  loadingRelationshipTypes: boolean;
  deleting: boolean;
}

const initialState: EmergencyContactState = {
  contacts: [],
  loading: false,
  error: null,
  relationshipTypes: undefined,
  loadingRelationshipTypes: false,
  deleting: false,
};

export const fetchEmergencyContacts = createAsyncThunk(
  EmergencyContactActions.FETCH_EMERGENCY_CONTACTS_REQUEST,
  async (payload: string) => {
    const response = (await apiGet(
      `/hr/employees/${payload}/emergency-contacts`,
    )) as AxiosResponse<EmergencyContact[]>;
    return response.data;
  },
);

export const createEmergencyContact = createAsyncThunk(
  EmergencyContactActions.CREATE_EMERGENCY_CONTACT_REQUEST,
  async (
    payload: CreateEmergencyContactPayload & { employee_id: string },
    { rejectWithValue },
  ) => {
    try {
      const response = (await apiPost(
        `/hr/employees/${payload.employee_id}/emergency-contacts`,
        payload,
      )) as AxiosResponse<EmergencyContact>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updateEmergencyContact = createAsyncThunk(
  EmergencyContactActions.UPDATE_EMERGENCY_CONTACT_REQUEST,
  async (payload: UpdateEmergencyContactPayload, { rejectWithValue }) => {
    try {
      const response = (await apiPut(
        `/hr/employees/${payload.employee_id}/emergency-contacts/${payload.id}`,
        payload,
      )) as AxiosResponse<EmergencyContact>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deleteEmergencyContact = createAsyncThunk(
  EmergencyContactActions.DELETE_EMERGENCY_CONTACT_REQUEST,
  async (payload: DeleteEmergencyContactPayload) => {
    const response = (await apiDelete(
      `/hr/employees/${payload.employee_id}/emergency-contacts/${payload.contact_id}`,
    )) as AxiosResponse<DeleteEmergencyContactResponse>;
    const responseData = response.data;
    responseData.id = payload.contact_id;
    return responseData;
  },
);

export const fetchEmergencyContactRelationshipTypes = createAsyncThunk(
  EmergencyContactActions.FETCH_RELATIONSHIP_TYPES_REQUEST,
  async () => {
    const response = (await apiGet(
      '/hr/employees/emergency-contacts/relationship-types',
    )) as AxiosResponse<any>;
    return response.data;
  },
);

export const EmergencyContactSlice = createSlice({
  name: 'emergencyContacts',
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchEmergencyContacts.pending, (state: Draft<EmergencyContactState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchEmergencyContacts.fulfilled,
        (state: Draft<EmergencyContactState>, action: PayloadAction<EmergencyContact[]>) => {
          state.contacts = action.payload;
          state.error = null;
          state.loading = false;
        },
      )
      .addCase(fetchEmergencyContacts.rejected, (state: Draft<EmergencyContactState>) => {
        state.loading = false;
        message.error(
          'Failed to load Emergency Contacts. Please try again or contact support if the issue persists',
        );
      });

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

    builder
      .addCase(updateEmergencyContact.pending, (state: Draft<EmergencyContactState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        updateEmergencyContact.fulfilled,
        (state: Draft<EmergencyContactState>) => {
          state.loading = false;
          state.error = null;
          message.success('Successfully updated Emergency Contact', 10);
        },
      )
      .addCase(
        updateEmergencyContact.rejected,
        (state: Draft<EmergencyContactState>, action: RejectedActionPayload) => {
          state.loading = false;
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(deleteEmergencyContact.pending, (state: Draft<EmergencyContactState>) => {
        state.deleting = true;
        state.error = null;
      })
      .addCase(
        deleteEmergencyContact.fulfilled,
        (
          state: Draft<EmergencyContactState>,
          action: PayloadAction<DeleteEmergencyContactResponse>,
        ) => {
          state.contacts = state.contacts.filter((contact) => contact.id !== action.payload.id);
          state.deleting = false;
          state.error = null;
          message.success(action.payload.message, 10);
        },
      )
      .addCase(deleteEmergencyContact.rejected, (state: Draft<EmergencyContactState>, action) => {
        state.error = action.error.message!;
        state.deleting = false;
        message.error(
          'Failed to delete Emergency Contact. Please try again or contact support',
          10,
        );
      });

    builder
      .addCase(
        fetchEmergencyContactRelationshipTypes.pending,
        (state: Draft<EmergencyContactState>) => {
          state.loadingRelationshipTypes = true;
          state.error = null;
        },
      )
      .addCase(
        fetchEmergencyContactRelationshipTypes.fulfilled,
        (state: Draft<EmergencyContactState>, action: PayloadAction<any>) => {
          state.relationshipTypes = action.payload;
          state.error = null;
          state.loadingRelationshipTypes = false;
        },
      )
      .addCase(
        fetchEmergencyContactRelationshipTypes.rejected,
        (state: Draft<EmergencyContactState>) => {
          state.loadingRelationshipTypes = false;
          message.error(
            'Failed to load Relationship Types. Please try again or contact support if the issue persists',
          );
        },
      );
  },
});

export default EmergencyContactSlice;
export type { EmergencyContactState };
