import {
  GradeAllowance,
  CreateGradeAllowancePayload,
  UpdateGradeAllowancePayload,
} from '@/interface/GradeAllowance';
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 { GradeAllowancesActions } from './actionTypes';

interface GradeAllowancesState {
  gradeAllowances: GradeAllowance[];
  loading: boolean;
  error: string | null;
}

const initialState: GradeAllowancesState = {
  gradeAllowances: [],
  loading: false,
  error: null,
};

export const fetchGradeAllowances = createSafeThunk<GradeAllowance[], { salary_grade_id?: string; search?: string } | undefined>(
  GradeAllowancesActions.FETCH_GRADE_ALLOWANCES_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-allowances${query}`)) as AxiosResponse<GradeAllowance[]>;
    return response.data;
  },
);

export const createGradeAllowance = createSafeThunk<GradeAllowance, CreateGradeAllowancePayload>(
  GradeAllowancesActions.CREATE_GRADE_ALLOWANCE_REQUEST,
  async (payload) => {
    const response = (await apiPost('/payroll/grade-allowances', payload)) as AxiosResponse<{ data: GradeAllowance }>;
    return response.data.data;
  },
);

export const updateGradeAllowance = createSafeThunk<GradeAllowance, UpdateGradeAllowancePayload>(
  GradeAllowancesActions.UPDATE_GRADE_ALLOWANCE_REQUEST,
  async (payload) => {
    const { id, ...data } = payload;
    const response = (await apiPut(`/payroll/grade-allowances/${id}`, data)) as AxiosResponse<{ data: GradeAllowance }>;
    return response.data.data;
  },
);

export const deleteGradeAllowance = createSafeThunk<string, string>(
  GradeAllowancesActions.DELETE_GRADE_ALLOWANCE_REQUEST,
  async (id) => {
    await apiDelete(`/payroll/grade-allowances/${id}`);
    return id;
  },
);

export const GradeAllowancesSlice = createSlice({
  name: 'gradeAllowances',
  initialState,
  reducers: {
    clearGradeAllowances(state) {
      state.gradeAllowances = [];
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchGradeAllowances.pending, (state: Draft<GradeAllowancesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchGradeAllowances.fulfilled,
        (state: Draft<GradeAllowancesState>, action: PayloadAction<GradeAllowance[]>) => {
          state.gradeAllowances = action.payload;
          state.loading = false;
          state.error = null;
        },
      )
      .addCase(fetchGradeAllowances.rejected, (state: Draft<GradeAllowancesState>, action: RejectedActionPayload) => {
        state.loading = false;
        state.error = 'Failed to load grade allowances';
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(createGradeAllowance.pending, (state: Draft<GradeAllowancesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        createGradeAllowance.fulfilled,
        (state: Draft<GradeAllowancesState>, action: PayloadAction<GradeAllowance>) => {
          state.gradeAllowances.push(action.payload);
          state.loading = false;
          state.error = null;
          message.success('Grade allowance created successfully');
        },
      )
      .addCase(
        createGradeAllowance.rejected,
        (state: Draft<GradeAllowancesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(updateGradeAllowance.pending, (state: Draft<GradeAllowancesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        updateGradeAllowance.fulfilled,
        (state: Draft<GradeAllowancesState>, action: PayloadAction<GradeAllowance>) => {
          const index = state.gradeAllowances.findIndex((a) => a.id === action.payload.id);
          if (index !== -1) state.gradeAllowances[index] = action.payload;
          state.loading = false;
          state.error = null;
          message.success('Grade allowance updated successfully');
        },
      )
      .addCase(
        updateGradeAllowance.rejected,
        (state: Draft<GradeAllowancesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

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

export const { clearGradeAllowances } = GradeAllowancesSlice.actions;
export default GradeAllowancesSlice;
export type { GradeAllowancesState };
