import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
  PipMilestone,
  PipMilestoneResponse,
  CreatePipMilestonePayload,
  ReviewPipMilestonePayload,
} 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 { PipMilestoneActions } from './actionTypes';

interface PipMilestoneState {
  milestones: PipMilestone[];
  currentMilestone: PipMilestone | null;
  loading: boolean;
  error: string | null;
}

const initialState: PipMilestoneState = {
  milestones: [],
  currentMilestone: null,
  loading: false,
  error: null,
};

export const fetchPipMilestones = createAsyncThunk(
  PipMilestoneActions.FETCH_MILESTONES_REQUEST,
  async (pipId: string) => {
    const response = (await apiGet(`/pips/${pipId}/milestones`)) as AxiosResponse<{ data: PipMilestone[] }>;
    return response.data.data;
  },
);

export const createPipMilestone = createAsyncThunk(
  PipMilestoneActions.CREATE_MILESTONE_REQUEST,
  async ({ pipId, ...payload }: CreatePipMilestonePayload & { pipId: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/pips/${pipId}/milestones`, payload)) as AxiosResponse<PipMilestoneResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updatePipMilestone = createAsyncThunk(
  PipMilestoneActions.UPDATE_MILESTONE_REQUEST,
  async ({ pipId, id, ...payload }: Partial<CreatePipMilestonePayload> & { pipId: string; id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPut(`/pips/${pipId}/milestones/${id}`, payload)) as AxiosResponse<PipMilestoneResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deletePipMilestone = createAsyncThunk(
  PipMilestoneActions.DELETE_MILESTONE_REQUEST,
  async ({ pipId, id }: { pipId: string; id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiDelete(`/pips/${pipId}/milestones/${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 reviewPipMilestone = createAsyncThunk(
  PipMilestoneActions.REVIEW_MILESTONE_REQUEST,
  async ({ pipId, id, ...payload }: ReviewPipMilestonePayload & { pipId: string; id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/pips/${pipId}/milestones/${id}/review`, payload)) as AxiosResponse<PipMilestoneResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const PipMilestoneSlice = createSlice({
  name: 'pipMilestones',
  initialState,
  reducers: {
    clearMilestones: (state: Draft<PipMilestoneState>) => {
      state.milestones = [];
      state.currentMilestone = null;
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchPipMilestones.pending, (state: Draft<PipMilestoneState>) => {
        state.loading = true;
      })
      .addCase(fetchPipMilestones.fulfilled, (state: Draft<PipMilestoneState>, action: PayloadAction<PipMilestone[]>) => {
        state.milestones = action.payload;
        state.loading = false;
      })
      .addCase(fetchPipMilestones.rejected, (state: Draft<PipMilestoneState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(createPipMilestone.pending, (state: Draft<PipMilestoneState>) => {
        state.loading = true;
      })
      .addCase(createPipMilestone.fulfilled, (state: Draft<PipMilestoneState>, action: PayloadAction<PipMilestone>) => {
        state.milestones.push(action.payload);
        state.loading = false;
        message.success('Milestone created successfully', 10);
      })
      .addCase(createPipMilestone.rejected, (state: Draft<PipMilestoneState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(updatePipMilestone.pending, (state: Draft<PipMilestoneState>) => {
        state.loading = true;
      })
      .addCase(updatePipMilestone.fulfilled, (state: Draft<PipMilestoneState>, action: PayloadAction<PipMilestone>) => {
        const idx = state.milestones.findIndex((m) => m.id === action.payload.id);
        if (idx !== -1) state.milestones[idx] = action.payload;
        state.loading = false;
        message.success('Milestone updated successfully', 10);
      })
      .addCase(updatePipMilestone.rejected, (state: Draft<PipMilestoneState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

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

    builder
      .addCase(reviewPipMilestone.pending, (state: Draft<PipMilestoneState>) => {
        state.loading = true;
      })
      .addCase(reviewPipMilestone.fulfilled, (state: Draft<PipMilestoneState>, action: PayloadAction<PipMilestone>) => {
        const idx = state.milestones.findIndex((m) => m.id === action.payload.id);
        if (idx !== -1) state.milestones[idx] = action.payload;
        state.loading = false;
        message.success('Milestone reviewed successfully', 10);
      })
      .addCase(reviewPipMilestone.rejected, (state: Draft<PipMilestoneState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });
  },
});

export const { clearMilestones } = PipMilestoneSlice.actions;
export default PipMilestoneSlice;
export type { PipMilestoneState };
