import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
  CheckInActionItem,
  ActionItemResponse,
  CreateActionItemPayload,
} from '@/interface/CheckIn';
import { apiDelete, apiGet, apiPatch, 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 { CheckInActionItemActions } from './actionTypes';

interface CheckInActionItemState {
  actionItems: CheckInActionItem[];
  loading: boolean;
  error: string | null;
}

const initialState: CheckInActionItemState = {
  actionItems: [],
  loading: false,
  error: null,
};

export const fetchActionItems = createAsyncThunk(
  CheckInActionItemActions.FETCH_ACTION_ITEMS_REQUEST,
  async (checkInId: string) => {
    const response = (await apiGet(`/check-ins/${checkInId}/action-items`)) as AxiosResponse<{ data: CheckInActionItem[] }>;
    return response.data.data;
  },
);

export const createActionItem = createAsyncThunk(
  CheckInActionItemActions.CREATE_ACTION_ITEM_REQUEST,
  async ({ checkInId, ...payload }: CreateActionItemPayload & { checkInId: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/check-ins/${checkInId}/action-items`, payload)) as AxiosResponse<ActionItemResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updateActionItem = createAsyncThunk(
  CheckInActionItemActions.UPDATE_ACTION_ITEM_REQUEST,
  async ({ checkInId, id, ...payload }: Partial<CreateActionItemPayload> & { checkInId: string; id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPut(`/check-ins/${checkInId}/action-items/${id}`, payload)) as AxiosResponse<ActionItemResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deleteActionItem = createAsyncThunk(
  CheckInActionItemActions.DELETE_ACTION_ITEM_REQUEST,
  async ({ checkInId, id }: { checkInId: string; id: string }, { rejectWithValue }) => {
    try {
      const response = (await apiDelete(`/check-ins/${checkInId}/action-items/${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 updateActionItemStatus = createAsyncThunk(
  CheckInActionItemActions.UPDATE_ACTION_ITEM_STATUS_REQUEST,
  async ({ checkInId, id, status }: { checkInId: string; id: string; status: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPatch(`/check-ins/${checkInId}/action-items/${id}/status`, { status })) as AxiosResponse<ActionItemResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const CheckInActionItemSlice = createSlice({
  name: 'checkInActionItems',
  initialState,
  reducers: {
    clearActionItems: (state: Draft<CheckInActionItemState>) => {
      state.actionItems = [];
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchActionItems.pending, (state: Draft<CheckInActionItemState>) => {
        state.loading = true;
      })
      .addCase(fetchActionItems.fulfilled, (state: Draft<CheckInActionItemState>, action: PayloadAction<CheckInActionItem[]>) => {
        state.actionItems = action.payload;
        state.loading = false;
      })
      .addCase(fetchActionItems.rejected, (state: Draft<CheckInActionItemState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(createActionItem.pending, (state: Draft<CheckInActionItemState>) => {
        state.loading = true;
      })
      .addCase(createActionItem.fulfilled, (state: Draft<CheckInActionItemState>, action: PayloadAction<CheckInActionItem>) => {
        state.actionItems.push(action.payload);
        state.loading = false;
        message.success('Action item added successfully', 10);
      })
      .addCase(createActionItem.rejected, (state: Draft<CheckInActionItemState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

    builder
      .addCase(updateActionItem.pending, (state: Draft<CheckInActionItemState>) => {
        state.loading = true;
      })
      .addCase(updateActionItem.fulfilled, (state: Draft<CheckInActionItemState>, action: PayloadAction<CheckInActionItem>) => {
        const idx = state.actionItems.findIndex((a) => a.id === action.payload.id);
        if (idx !== -1) state.actionItems[idx] = action.payload;
        state.loading = false;
        message.success('Action item updated successfully', 10);
      })
      .addCase(updateActionItem.rejected, (state: Draft<CheckInActionItemState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });

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

    builder
      .addCase(updateActionItemStatus.pending, (state: Draft<CheckInActionItemState>) => {
        state.loading = true;
      })
      .addCase(updateActionItemStatus.fulfilled, (state: Draft<CheckInActionItemState>, action: PayloadAction<CheckInActionItem>) => {
        const idx = state.actionItems.findIndex((a) => a.id === action.payload.id);
        if (idx !== -1) state.actionItems[idx] = action.payload;
        state.loading = false;
        message.success('Action item status updated', 10);
      })
      .addCase(updateActionItemStatus.rejected, (state: Draft<CheckInActionItemState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 10);
      });
  },
});

export const { clearActionItems } = CheckInActionItemSlice.actions;
export default CheckInActionItemSlice;
export type { CheckInActionItemState };
