import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
  PeerReview,
  PeerReviewResponse,
  PaginatedPeerReviews,
  SubmitPeerReviewPayload,
} from '@/interface/PeerReviewAssignment';
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 { PeerReviewActions } from './actionTypes';
import { PaginationLinks, PaginationMeta } from '@/interface/Paginated';
import { GetParams, toQueryString } from '@/interface/GetParams';

interface PeerReviewState {
  peerReviews: PeerReview[];
  currentPeerReview: PeerReview | null;
  links?: PaginationLinks;
  meta?: PaginationMeta;
  loading: boolean;
  error: string | null;
}

const initialState: PeerReviewState = {
  peerReviews: [],
  currentPeerReview: null,
  loading: false,
  error: null,
};

export const fetchPeerReviews = createAsyncThunk(
  PeerReviewActions.FETCH_PEER_REVIEWS_REQUEST,
  async (params?: GetParams) => {
    const query = toQueryString(params);
    const response = (await apiGet(`/peer-reviews${query}`)) as AxiosResponse<PaginatedPeerReviews>;
    return response.data;
  },
);

export const fetchPeerReview = createAsyncThunk(
  PeerReviewActions.FETCH_PEER_REVIEW_REQUEST,
  async (id: string) => {
    const response = (await apiGet(`/peer-reviews/${id}`)) as AxiosResponse<PeerReviewResponse>;
    return response.data.data;
  },
);

export const submitPeerReview = createAsyncThunk(
  PeerReviewActions.SUBMIT_PEER_REVIEW_REQUEST,
  async ({ assignmentId, ...payload }: SubmitPeerReviewPayload & { assignmentId: string }, { rejectWithValue }) => {
    try {
      const response = (await apiPost(`/peer-reviews/${assignmentId}/submit`, payload)) as AxiosResponse<PeerReviewResponse>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deletePeerReview = createAsyncThunk(
  PeerReviewActions.DELETE_PEER_REVIEW_REQUEST,
  async (id: string, { rejectWithValue }) => {
    try {
      const response = (await apiDelete(`/peer-reviews/${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 PeerReviewSlice = createSlice({
  name: 'peerReviews',
  initialState,
  reducers: {
    clearCurrentPeerReview: (state: Draft<PeerReviewState>) => {
      state.currentPeerReview = null;
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchPeerReviews.pending, (state: Draft<PeerReviewState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchPeerReviews.fulfilled,
        (state: Draft<PeerReviewState>, action: PayloadAction<PaginatedPeerReviews>) => {
          state.peerReviews = action.payload.data;
          state.meta = action.payload.meta;
          state.links = action.payload.links;
          state.loading = false;
        },
      )
      .addCase(fetchPeerReviews.rejected, (state: Draft<PeerReviewState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchPeerReview.pending, (state: Draft<PeerReviewState>) => {
        state.loading = true;
      })
      .addCase(
        fetchPeerReview.fulfilled,
        (state: Draft<PeerReviewState>, action: PayloadAction<PeerReview>) => {
          state.currentPeerReview = action.payload;
          state.loading = false;
        },
      )
      .addCase(fetchPeerReview.rejected, (state: Draft<PeerReviewState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(submitPeerReview.pending, (state: Draft<PeerReviewState>) => {
        state.loading = true;
      })
      .addCase(
        submitPeerReview.fulfilled,
        (state: Draft<PeerReviewState>, action: PayloadAction<PeerReview>) => {
          state.peerReviews.unshift(action.payload);
          state.loading = false;
          message.success('Peer review submitted successfully', 10);
        },
      )
      .addCase(
        submitPeerReview.rejected,
        (state: Draft<PeerReviewState>, action: RejectedActionPayload) => {
          state.loading = false;
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

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

export const { clearCurrentPeerReview } = PeerReviewSlice.actions;
export default PeerReviewSlice;
export type { PeerReviewState };
