import {
  DeleteWorkExperiencePayload,
  DeleteWorkExperienceResponse,
  UpdateWorkExperiencePayload,
  WorkExperience,
} from '@/interface/WorkExperience';
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 { WorkExperienceActions } from './actionTypes';

interface WorkExperienceState {
  workExperiences: WorkExperience[];
  loading: boolean;
  error: string | null;
  deleting: boolean;
}

const initialState: WorkExperienceState = {
  workExperiences: [],
  loading: false,
  error: null,
  deleting: false,
};

export const fetchWorkExperiences = createAsyncThunk(
  WorkExperienceActions.FETCH_WORK_EXPERIENCES_REQUEST,
  async (payload: string) => {
    const response = (await apiGet(
      `/hr/employees/${payload}/work-experiences`,
    )) as AxiosResponse<WorkExperience[]>;
    return response.data;
  },
);

export const createWorkExperience = createAsyncThunk(
  WorkExperienceActions.CREATE_WORK_EXPERIENCE_REQUEST,
  async (
    payload: { employee_id: string } & Record<string, any>,
    { rejectWithValue },
  ) => {
    try {
      const response = (await apiPost(
        `/hr/employees/${payload.employee_id}/work-experiences`,
        payload,
      )) as AxiosResponse<WorkExperience>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updateWorkExperience = createAsyncThunk(
  WorkExperienceActions.UPDATE_WORK_EXPERIENCE_REQUEST,
  async (payload: UpdateWorkExperiencePayload, { rejectWithValue }) => {
    try {
      const response = (await apiPut(
        `/hr/employees/${payload.employee_id}/work-experiences/${payload.id}`,
        payload,
      )) as AxiosResponse<WorkExperience>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deleteWorkExperience = createAsyncThunk(
  WorkExperienceActions.DELETE_WORK_EXPERIENCE_REQUEST,
  async (payload: DeleteWorkExperiencePayload) => {
    const response = (await apiDelete(
      `/hr/employees/${payload.employee_id}/work-experiences/${payload.experience_id}`,
    )) as AxiosResponse<DeleteWorkExperienceResponse>;
    const responseData = response.data;
    responseData.id = payload.experience_id;
    return responseData;
  },
);

export const WorkExperienceSlice = createSlice({
  name: 'workExperiences',
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchWorkExperiences.pending, (state: Draft<WorkExperienceState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchWorkExperiences.fulfilled,
        (state: Draft<WorkExperienceState>, action: PayloadAction<WorkExperience[]>) => {
          state.workExperiences = action.payload;
          state.error = null;
          state.loading = false;
        },
      )
      .addCase(fetchWorkExperiences.rejected, (state: Draft<WorkExperienceState>) => {
        state.loading = false;
        message.error(
          'Failed to load Work Experiences. Please try again or contact support if the issue persists',
        );
      });

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

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

    builder
      .addCase(deleteWorkExperience.pending, (state: Draft<WorkExperienceState>) => {
        state.deleting = true;
        state.error = null;
      })
      .addCase(
        deleteWorkExperience.fulfilled,
        (
          state: Draft<WorkExperienceState>,
          action: PayloadAction<DeleteWorkExperienceResponse>,
        ) => {
          state.workExperiences = state.workExperiences.filter(
            (experience) => experience.id !== action.payload.id,
          );
          state.deleting = false;
          state.error = null;
          message.success(action.payload.message, 10);
        },
      )
      .addCase(deleteWorkExperience.rejected, (state: Draft<WorkExperienceState>, action) => {
        state.error = action.error.message!;
        state.deleting = false;
        message.error(
          'Failed to delete Work Experience. Please try again or contact support',
          10,
        );
      });
  },
});

export default WorkExperienceSlice;
export type { WorkExperienceState };
