import {
  GradeDeduction,
  CreateGradeDeductionPayload,
  UpdateGradeDeductionPayload,
} from '@/interface/GradeDeduction';
import { RejectedActionPayload } from '@/interface/Shared';
import { apiDelete, apiGet, apiPost, apiPut } from '@/services/api/api';
import Helpers from '@/utilities/Helpers';
import { createSafeThunk } from '@/utilities/createSafeThunk';
import { createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';
import { message } from 'antd';
import { AxiosResponse } from 'axios';
import { GradeDeductionsActions } from './actionTypes';

interface GradeDeductionsState {
  gradeDeductions: GradeDeduction[];
  loading: boolean;
  error: string | null;
}

const initialState: GradeDeductionsState = {
  gradeDeductions: [],
  loading: false,
  error: null,
};

export const fetchGradeDeductions = createSafeThunk<GradeDeduction[], { salary_grade_id?: string; search?: string } | undefined>(
  GradeDeductionsActions.FETCH_GRADE_DEDUCTIONS_REQUEST,
  async (params) => {
    const queryParams = new URLSearchParams();
    if (params?.salary_grade_id) queryParams.append('salary_grade_id', params.salary_grade_id);
    if (params?.search) queryParams.append('search', params.search);
    const query = queryParams.toString() ? `?${queryParams.toString()}` : '';
    const response = (await apiGet(`/payroll/grade-deductions${query}`)) as AxiosResponse<GradeDeduction[]>;
    return response.data;
  },
);

export const createGradeDeduction = createSafeThunk<GradeDeduction, CreateGradeDeductionPayload>(
  GradeDeductionsActions.CREATE_GRADE_DEDUCTION_REQUEST,
  async (payload) => {
    const response = (await apiPost('/payroll/grade-deductions', payload)) as AxiosResponse<{ data: GradeDeduction }>;
    return response.data.data;
  },
);

export const updateGradeDeduction = createSafeThunk<GradeDeduction, UpdateGradeDeductionPayload>(
  GradeDeductionsActions.UPDATE_GRADE_DEDUCTION_REQUEST,
  async (payload) => {
    const { id, ...data } = payload;
    const response = (await apiPut(`/payroll/grade-deductions/${id}`, data)) as AxiosResponse<{ data: GradeDeduction }>;
    return response.data.data;
  },
);

export const deleteGradeDeduction = createSafeThunk<string, string>(
  GradeDeductionsActions.DELETE_GRADE_DEDUCTION_REQUEST,
  async (id) => {
    await apiDelete(`/payroll/grade-deductions/${id}`);
    return id;
  },
);

export const GradeDeductionsSlice = createSlice({
  name: 'gradeDeductions',
  initialState,
  reducers: {
    clearGradeDeductions(state) {
      state.gradeDeductions = [];
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchGradeDeductions.pending, (state: Draft<GradeDeductionsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchGradeDeductions.fulfilled,
        (state: Draft<GradeDeductionsState>, action: PayloadAction<GradeDeduction[]>) => {
          state.gradeDeductions = action.payload;
          state.loading = false;
          state.error = null;
        },
      )
      .addCase(fetchGradeDeductions.rejected, (state: Draft<GradeDeductionsState>, action: RejectedActionPayload) => {
        state.loading = false;
        state.error = 'Failed to load grade deductions';
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(createGradeDeduction.pending, (state: Draft<GradeDeductionsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        createGradeDeduction.fulfilled,
        (state: Draft<GradeDeductionsState>, action: PayloadAction<GradeDeduction>) => {
          state.gradeDeductions.push(action.payload);
          state.loading = false;
          state.error = null;
          message.success('Grade deduction created successfully');
        },
      )
      .addCase(
        createGradeDeduction.rejected,
        (state: Draft<GradeDeductionsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(updateGradeDeduction.pending, (state: Draft<GradeDeductionsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        updateGradeDeduction.fulfilled,
        (state: Draft<GradeDeductionsState>, action: PayloadAction<GradeDeduction>) => {
          const index = state.gradeDeductions.findIndex((d) => d.id === action.payload.id);
          if (index !== -1) state.gradeDeductions[index] = action.payload;
          state.loading = false;
          state.error = null;
          message.success('Grade deduction updated successfully');
        },
      )
      .addCase(
        updateGradeDeduction.rejected,
        (state: Draft<GradeDeductionsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(deleteGradeDeduction.pending, (state: Draft<GradeDeductionsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        deleteGradeDeduction.fulfilled,
        (state: Draft<GradeDeductionsState>, action: PayloadAction<string>) => {
          state.gradeDeductions = state.gradeDeductions.filter((d) => d.id !== action.payload);
          state.loading = false;
          state.error = null;
          message.success('Grade deduction removed successfully');
        },
      )
      .addCase(
        deleteGradeDeduction.rejected,
        (state: Draft<GradeDeductionsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );
  },
});

export const { clearGradeDeductions } = GradeDeductionsSlice.actions;
export default GradeDeductionsSlice;
export type { GradeDeductionsState };
