import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
  Quiz,
  QuizDetail,
  CreateQuizPayload,
  UpdateQuizPayload,
  DeleteQuizPayload,
  PaginationMeta,
} from '@/interface/Assessment';
import Helpers from '@/utilities/Helpers';
import { createAsyncThunk, createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';
import { message } from 'antd';
import { QuizzesActions } from './actionTypes';
import { apiDelete, apiGet, apiPost, apiPut } from '@/services/api/api';
import axios, { AxiosResponse } from 'axios';

interface QuizzesState {
  quizzes: Quiz[];
  selectedQuiz: QuizDetail | null;
  meta: PaginationMeta | null;
  loading: boolean;
  error: string | null;
}

const initialState: QuizzesState = {
  quizzes: [],
  selectedQuiz: null,
  meta: null,
  loading: false,
  error: null,
};

export const fetchQuizzes = createAsyncThunk(
  QuizzesActions.FETCH_QUIZZES_REQUEST,
  async (params?: { status?: string; type?: string; search?: string; page?: number }) => {
    const queryParams = new URLSearchParams();
    if (params?.status) queryParams.append('status', params.status);
    if (params?.type) queryParams.append('type', params.type);
    if (params?.search) queryParams.append('search', params.search);
    if (params?.page) queryParams.append('page', params.page.toString());
    const query = queryParams.toString() ? `?${queryParams.toString()}` : '';
    const response = (await apiGet(`/assessment/quizzes${query}`)) as AxiosResponse<{
      data: Quiz[];
      meta: PaginationMeta;
    }>;
    return response.data;
  },
);

export const fetchQuiz = createAsyncThunk(
  QuizzesActions.FETCH_QUIZ_REQUEST,
  async (id: string) => {
    const response = (await apiGet(`/assessment/quizzes/${id}`)) as AxiosResponse<QuizDetail>;
    return response.data;
  },
);

export const createQuiz = createAsyncThunk(
  QuizzesActions.CREATE_QUIZ_REQUEST,
  async (payload: CreateQuizPayload, { rejectWithValue }) => {
    try {
      const response = (await apiPost('/assessment/quizzes', payload)) as AxiosResponse<{
        data: QuizDetail;
      }>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updateQuiz = createAsyncThunk(
  QuizzesActions.UPDATE_QUIZ_REQUEST,
  async (payload: UpdateQuizPayload, { rejectWithValue }) => {
    try {
      const { id, ...data } = payload;
      const response = (await apiPut(`/assessment/quizzes/${id}`, data)) as AxiosResponse<{
        data: QuizDetail;
      }>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deleteQuiz = createAsyncThunk(
  QuizzesActions.DELETE_QUIZ_REQUEST,
  async (id: string, { rejectWithValue }) => {
    try {
      const response = (await apiDelete(
        `/assessment/quizzes/${id}`,
      )) as AxiosResponse<DeleteQuizPayload>;
      const responseData = response.data;
      responseData.id = id;
      return responseData;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const publishQuiz = createAsyncThunk(
  QuizzesActions.PUBLISH_QUIZ_REQUEST,
  async (id: string, { rejectWithValue }) => {
    try {
      const response = (await apiPost(
        `/assessment/quizzes/${id}/publish`,
        {},
      )) as AxiosResponse<{ data: QuizDetail }>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const archiveQuiz = createAsyncThunk(
  QuizzesActions.ARCHIVE_QUIZ_REQUEST,
  async (id: string, { rejectWithValue }) => {
    try {
      const response = (await apiPost(
        `/assessment/quizzes/${id}/archive`,
        {},
      )) as AxiosResponse<{ data: QuizDetail }>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const reorderQuizQuestions = createAsyncThunk(
  QuizzesActions.REORDER_QUESTIONS_REQUEST,
  async (payload: { quizId: string; question_ids: string[] }, { rejectWithValue }) => {
    try {
      const response = (await apiPut(`/assessment/quizzes/${payload.quizId}/reorder`, {
        question_ids: payload.question_ids,
      })) as AxiosResponse<{ data: QuizDetail }>;
      return response.data.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const QuizzesSlice = createSlice({
  name: 'quizzes',
  initialState,
  reducers: {
    clearSelectedQuiz: (state: Draft<QuizzesState>) => {
      state.selectedQuiz = null;
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchQuizzes.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchQuizzes.fulfilled,
        (
          state: Draft<QuizzesState>,
          action: PayloadAction<{ data: Quiz[]; meta: PaginationMeta }>,
        ) => {
          state.quizzes = action.payload.data;
          state.meta = action.payload.meta;
          state.error = null;
          state.loading = false;
        },
      )
      .addCase(fetchQuizzes.rejected, (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
        state.loading = false;
        state.error = 'Failed to load quizzes';
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchQuiz.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchQuiz.fulfilled,
        (state: Draft<QuizzesState>, action: PayloadAction<QuizDetail>) => {
          state.selectedQuiz = action.payload;
          state.error = null;
          state.loading = false;
        },
      )
      .addCase(fetchQuiz.rejected, (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
        state.loading = false;
        state.error = 'Failed to load quiz';
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(createQuiz.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        createQuiz.fulfilled,
        (state: Draft<QuizzesState>, action: PayloadAction<QuizDetail>) => {
          state.selectedQuiz = action.payload;
          state.error = null;
          state.loading = false;
          message.success('Quiz created successfully');
        },
      )
      .addCase(
        createQuiz.rejected,
        (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(updateQuiz.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        updateQuiz.fulfilled,
        (state: Draft<QuizzesState>, action: PayloadAction<QuizDetail>) => {
          state.selectedQuiz = action.payload;
          const index = state.quizzes.findIndex((q) => q.id === action.payload.id);
          if (index !== -1) {
            state.quizzes[index] = action.payload;
          }
          state.loading = false;
          state.error = null;
          message.success('Quiz updated successfully');
        },
      )
      .addCase(
        updateQuiz.rejected,
        (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(deleteQuiz.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        deleteQuiz.fulfilled,
        (state: Draft<QuizzesState>, action: PayloadAction<DeleteQuizPayload>) => {
          state.quizzes = state.quizzes.filter((q) => q.id !== action.payload.id);
          state.loading = false;
          message.success(action.payload.message);
        },
      )
      .addCase(
        deleteQuiz.rejected,
        (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(publishQuiz.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        publishQuiz.fulfilled,
        (state: Draft<QuizzesState>, action: PayloadAction<QuizDetail>) => {
          state.selectedQuiz = action.payload;
          const index = state.quizzes.findIndex((q) => q.id === action.payload.id);
          if (index !== -1) {
            state.quizzes[index] = action.payload;
          }
          state.loading = false;
          state.error = null;
          message.success('Quiz published successfully');
        },
      )
      .addCase(
        publishQuiz.rejected,
        (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(archiveQuiz.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        archiveQuiz.fulfilled,
        (state: Draft<QuizzesState>, action: PayloadAction<QuizDetail>) => {
          state.selectedQuiz = action.payload;
          const index = state.quizzes.findIndex((q) => q.id === action.payload.id);
          if (index !== -1) {
            state.quizzes[index] = action.payload;
          }
          state.loading = false;
          state.error = null;
          message.success('Quiz archived successfully');
        },
      )
      .addCase(
        archiveQuiz.rejected,
        (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(reorderQuizQuestions.pending, (state: Draft<QuizzesState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        reorderQuizQuestions.fulfilled,
        (state: Draft<QuizzesState>, action: PayloadAction<QuizDetail>) => {
          state.selectedQuiz = action.payload;
          state.loading = false;
          state.error = null;
          message.success('Questions reordered successfully');
        },
      )
      .addCase(
        reorderQuizQuestions.rejected,
        (state: Draft<QuizzesState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );
  },
});

export const { clearSelectedQuiz } = QuizzesSlice.actions;
export default QuizzesSlice;
export type { QuizzesState };
