import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
  PerformanceImprovementPlan,
  PipResponse,
  PaginatedPips,
  CreatePipPayload,
  UpdatePipPayload,
  ExtendPipPayload,
  CompletePipPayload,
  AcknowledgePipPayload,
  PipProgress,
  PipProgressResponse,
} from '@/interface/PerformanceImprovementPlan';
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 { PipActions } from './actionTypes';
import { PaginationLinks, PaginationMeta } from '@/interface/Paginated';
import { GetParams, toQueryString } from '@/interface/GetParams';

interface PipState {
  pips: PerformanceImprovementPlan[];
  myPips: PerformanceImprovementPlan[];
  currentPip: PerformanceImprovementPlan | null;
  pipProgress: PipProgress | null;
  links?: PaginationLinks;
  meta?: PaginationMeta;
  loading: boolean;
  error: string | null;
}

const initialState: PipState = {
  pips: [],
  myPips: [],
  currentPip: null,
  pipProgress: null,
  loading: false,
  error: null,
};

export const fetchPips = createAsyncThunk(
  PipActions.FETCH_PIPS_REQUEST,
  async (params?: GetParams) => {
    const query = toQueryString(params);
    const response = (await apiGet(`/pips${query}`)) as AxiosResponse<PaginatedPips>;
    return response.data;
  },
);

export const fetchPip = createAsyncThunk(
  PipActions.FETCH_PIP_REQUEST,
  async (id: string) => {
    const response = (await apiGet(`/pips/${id}`)) as AxiosResponse<PipResponse>;
    return response.data.data;
  },
);

export const fetchMyPips = createAsyncThunk(
  PipActions.FETCH_MY_PIPS_REQUEST,
  async (params?: GetParams) => {
    const query = toQueryString(params);
    const response = (await apiGet(`/pips/my-pips${query}`)) as AxiosResponse<PaginatedPips>;
    return response.data;
  },
);

export const createPip = createAsyncThunk(
  PipActions.CREATE_PIP_REQUEST,
  async (payload: CreatePipPayload, { rejectWithValue }) => {
    try {
      const response = (await apiPost('/pips', payload)) as AxiosResponse<PipResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updatePip = createAsyncThunk(
  PipActions.UPDATE_PIP_REQUEST,
  async (payload: UpdatePipPayload & { id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPut(`/pips/${payload.id}`, payload)) as AxiosResponse<PipResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deletePip = createAsyncThunk(
  PipActions.DELETE_PIP_REQUEST,
  async (id: string, { rejectWithValue }) => {
    try {
      const response = (await apiDelete(`/pips/${id}`)) as AxiosResponse<{ message: string }>;
      return { message: response.data.message, id };
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const activatePip = createAsyncThunk(
  PipActions.ACTIVATE_PIP_REQUEST,
  async (id: string, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/pips/${id}/activate`)) as AxiosResponse<PipResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const extendPip = createAsyncThunk(
  PipActions.EXTEND_PIP_REQUEST,
  async ({ id, ...payload }: ExtendPipPayload & { id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/pips/${id}/extend`, payload)) as AxiosResponse<PipResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const completePip = createAsyncThunk(
  PipActions.COMPLETE_PIP_REQUEST,
  async ({ id, ...payload }: CompletePipPayload & { id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/pips/${id}/complete`, payload)) as AxiosResponse<PipResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const acknowledgePip = createAsyncThunk(
  PipActions.ACKNOWLEDGE_PIP_REQUEST,
  async ({ id, ...payload }: AcknowledgePipPayload & { id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/pips/${id}/acknowledge`, payload)) as AxiosResponse<PipResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchPipProgress = createAsyncThunk(
  PipActions.FETCH_PIP_PROGRESS_REQUEST,
  async (id: string) => {
    const response = (await apiGet(`/pips/${id}/progress`)) as AxiosResponse<PipProgressResponse>;
    return response.data.data;
  },
);

export const PipSlice = createSlice({
  name: 'pips',
  initialState,
  reducers: {
    clearCurrentPip: (state: Draft<PipState>) => {
      state.currentPip = null;
      state.pipProgress = null;
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchPips.pending, (state: Draft<PipState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchPips.fulfilled, (state: Draft<PipState>, action: PayloadAction<PaginatedPips>) => {
        state.pips = action.payload.data;
        state.meta = action.payload.meta;
        state.links = action.payload.links;
        state.loading = false;
      })
      .addCase(fetchPips.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchPip.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(fetchPip.fulfilled, (state: Draft<PipState>, action: PayloadAction<PerformanceImprovementPlan>) => {
        state.currentPip = action.payload;
        state.loading = false;
      })
      .addCase(fetchPip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchMyPips.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(fetchMyPips.fulfilled, (state: Draft<PipState>, action: PayloadAction<PaginatedPips>) => {
        state.myPips = action.payload.data;
        state.loading = false;
      })
      .addCase(fetchMyPips.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(createPip.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(createPip.fulfilled, (state: Draft<PipState>, action: PayloadAction<PerformanceImprovementPlan>) => {
        state.pips.unshift(action.payload);
        state.loading = false;
        message.success('Performance improvement plan created successfully', 10);
      })
      .addCase(createPip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(updatePip.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(updatePip.fulfilled, (state: Draft<PipState>, action: PayloadAction<PerformanceImprovementPlan>) => {
        state.currentPip = action.payload;
        const idx = state.pips.findIndex((p) => p.id === action.payload.id);
        if (idx !== -1) state.pips[idx] = action.payload;
        state.loading = false;
        message.success('PIP updated successfully', 10);
      })
      .addCase(updatePip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(deletePip.pending, (state: Draft<PipState>) => {})
      .addCase(deletePip.fulfilled, (state: Draft<PipState>, action: PayloadAction<{ message: string; id: string }>) => {
        state.pips = state.pips.filter((p) => p.id !== action.payload.id);
        message.success(action.payload.message, 10);
      })
      .addCase(deletePip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(activatePip.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(activatePip.fulfilled, (state: Draft<PipState>, action: PayloadAction<PerformanceImprovementPlan>) => {
        state.currentPip = action.payload;
        const idx = state.pips.findIndex((p) => p.id === action.payload.id);
        if (idx !== -1) state.pips[idx] = action.payload;
        state.loading = false;
        message.success('PIP activated successfully', 10);
      })
      .addCase(activatePip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(extendPip.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(extendPip.fulfilled, (state: Draft<PipState>, action: PayloadAction<PerformanceImprovementPlan>) => {
        state.currentPip = action.payload;
        const idx = state.pips.findIndex((p) => p.id === action.payload.id);
        if (idx !== -1) state.pips[idx] = action.payload;
        state.loading = false;
        message.success('PIP extended successfully', 10);
      })
      .addCase(extendPip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(completePip.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(completePip.fulfilled, (state: Draft<PipState>, action: PayloadAction<PerformanceImprovementPlan>) => {
        state.currentPip = action.payload;
        const idx = state.pips.findIndex((p) => p.id === action.payload.id);
        if (idx !== -1) state.pips[idx] = action.payload;
        state.loading = false;
        message.success('PIP completed successfully', 10);
      })
      .addCase(completePip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(acknowledgePip.pending, (state: Draft<PipState>) => {
        state.loading = true;
      })
      .addCase(acknowledgePip.fulfilled, (state: Draft<PipState>, action: PayloadAction<PerformanceImprovementPlan>) => {
        state.currentPip = action.payload;
        state.loading = false;
        message.success('PIP acknowledged successfully', 10);
      })
      .addCase(acknowledgePip.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(fetchPipProgress.pending, (state: Draft<PipState>) => {})
      .addCase(fetchPipProgress.fulfilled, (state: Draft<PipState>, action: PayloadAction<PipProgress>) => {
        state.pipProgress = action.payload;
      })
      .addCase(fetchPipProgress.rejected, (state: Draft<PipState>, action: RejectedActionPayload) => {
        message.error(Helpers.handleServerError(action.payload), 8);
      });
  },
});

export const { clearCurrentPip } = PipSlice.actions;
export default PipSlice;
export type { PipState };
