import {
  EmployeeGradeAssignment,
  EmployeeGradeAssignmentResponse,
  UpsertEmployeeGradeAssignmentPayload,
} from '@/interface/EmployeeGradeAssignment';
import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import { apiGet, 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 { EmployeeGradeAssignmentsActions } from './actionTypes';

interface EmployeeGradeAssignmentState {
  assignment: EmployeeGradeAssignment | null;
  history: EmployeeGradeAssignment[];
  historyLoading: boolean;
  loading: boolean;
  saving: boolean;
  error: string | null;
}

const initialState: EmployeeGradeAssignmentState = {
  assignment: null,
  history: [],
  historyLoading: false,
  loading: false,
  saving: false,
  error: null,
};

export const fetchEmployeeGradeAssignment = createAsyncThunk(
  EmployeeGradeAssignmentsActions.FETCH_EMPLOYEE_GRADE_ASSIGNMENT_REQUEST,
  async (employeeId: string) => {
    const response = (await apiGet(
      `/payroll/employees/${employeeId}/grade-assignment`,
    )) as AxiosResponse<EmployeeGradeAssignmentResponse>;

    return response.data.data;
  },
);

export const fetchEmployeeGradeAssignmentHistory = createAsyncThunk(
  EmployeeGradeAssignmentsActions.FETCH_EMPLOYEE_GRADE_ASSIGNMENT_HISTORY_REQUEST,
  async (employeeId: string) => {
    const response = (await apiGet(
      `/payroll/employees/${employeeId}/grade-assignments`,
    )) as AxiosResponse<{ data: EmployeeGradeAssignment[] }>;

    return response.data.data;
  },
);

export const upsertEmployeeGradeAssignment = createAsyncThunk(
  EmployeeGradeAssignmentsActions.UPSERT_EMPLOYEE_GRADE_ASSIGNMENT_REQUEST,
  async (payload: UpsertEmployeeGradeAssignmentPayload, { rejectWithValue }) => {
    try {
      const { employee_id, ...data } = payload;
      const response = (await apiPut(
        `/payroll/employees/${employee_id}/grade-assignment`,
        data,
      )) as AxiosResponse<{ data: EmployeeGradeAssignment }>;

      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }

      throw error;
    }
  },
);

export const EmployeeGradeAssignmentsSlice = createSlice({
  name: 'employeeGradeAssignments',
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchEmployeeGradeAssignment.pending, (state: Draft<EmployeeGradeAssignmentState>) => {
        state.loading = true;
        state.error = null;
        state.assignment = null;
      })
      .addCase(
        fetchEmployeeGradeAssignment.fulfilled,
        (state: Draft<EmployeeGradeAssignmentState>, action: PayloadAction<EmployeeGradeAssignment | null>) => {
          state.assignment = action.payload;
          state.loading = false;
          state.error = null;
        },
      )
      .addCase(fetchEmployeeGradeAssignment.rejected, (state: Draft<EmployeeGradeAssignmentState>, action: RejectedActionPayload) => {
        state.loading = false;
        state.error = 'Failed to load employee grade assignment. Please try again or contact support';
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchEmployeeGradeAssignmentHistory.pending, (state: Draft<EmployeeGradeAssignmentState>) => {
        state.historyLoading = true;
      })
      .addCase(
        fetchEmployeeGradeAssignmentHistory.fulfilled,
        (state: Draft<EmployeeGradeAssignmentState>, action: PayloadAction<EmployeeGradeAssignment[]>) => {
          state.history = action.payload;
          state.historyLoading = false;
        },
      )
      .addCase(fetchEmployeeGradeAssignmentHistory.rejected, (state: Draft<EmployeeGradeAssignmentState>, action: RejectedActionPayload) => {
        state.historyLoading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(upsertEmployeeGradeAssignment.pending, (state: Draft<EmployeeGradeAssignmentState>) => {
        state.saving = true;
        state.error = null;
      })
      .addCase(
        upsertEmployeeGradeAssignment.fulfilled,
        (state: Draft<EmployeeGradeAssignmentState>, action: PayloadAction<EmployeeGradeAssignment>) => {
          state.assignment = action.payload;
          state.saving = false;
          state.error = null;
          message.success('Employee grade assignment saved successfully');
        },
      )
      .addCase(
        upsertEmployeeGradeAssignment.rejected,
        (state: Draft<EmployeeGradeAssignmentState>, action: RejectedActionPayload) => {
          state.saving = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );
  },
});

export default EmployeeGradeAssignmentsSlice;
export type { EmployeeGradeAssignmentState };
