import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
    RatingScale,
    RatingScaleResponse,
    CreateRatingScalePayload,
    PaginatedRatingScales
} from '@/interface/RatingScale';
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 { RatingScaleActions } from './actionTypes';
import { PaginationLinks, PaginationMeta } from '@/interface/Paginated';
import { GetParams, toQueryString } from '@/interface/GetParams';

interface RatingScaleState {
    ratingScales: RatingScale[];
    links?: PaginationLinks;
    meta?: PaginationMeta;
    loading: boolean;
    error: string | null;
}

const initialState: RatingScaleState = {
    ratingScales: [],
    loading: false,
    error: null,
};

export const fetchRatingScales = createAsyncThunk(
    RatingScaleActions.FETCH_RATING_SCALE_REQUEST,
    async (params?: GetParams) => {
        const query = toQueryString(params);
        const response = (await apiGet(`/rating-scales${query}`)) as AxiosResponse<PaginatedRatingScales>;
        return response.data;
    },
);

export const createRatingScale = createAsyncThunk(
    RatingScaleActions.CREATE_RATING_SCALE_REQUEST,
    async (payload: CreateRatingScalePayload, { rejectWithValue }) => {
        try {
            const response = (await apiPost(
                '/rating-scales',
                payload,
            )) as AxiosResponse<RatingScaleResponse>;
            return response.data.data;
        } catch (error) {
            if (axios.isAxiosError(error) && error.response) {
                return rejectWithValue(error.response.data as ServerErrorResponse);
            }
            throw error;
        }
    },
);

export const updateRatingScale = createAsyncThunk(
    RatingScaleActions.UPDATE_RATING_SCALE_REQUEST,
    async (payload: CreateRatingScalePayload & { id: string }, { rejectWithValue }) => {
        try {
            const response = (await apiPut(
                `/rating-scales/${payload.id}`,
                payload,
            )) as AxiosResponse<RatingScaleResponse>;
            return response.data.data;
        } catch (error) {
            if (axios.isAxiosError(error) && error.response) {
                return rejectWithValue(error.response.data as ServerErrorResponse);
            }
            throw error;
        }
    },
);

export const deleteRatingScale = createAsyncThunk(
    RatingScaleActions.DELETE_RATING_SCALE_REQUEST,
    async (payload: string, { rejectWithValue }) => {
        try {
            const response = (await apiDelete(
                `/rating-scales/${payload}`,
            )) as AxiosResponse<{ message: string }>;
            return {
                message: response.data.message,
                id: payload
            };
        } catch (error) {
            if (axios.isAxiosError(error) && error.response) {
                return rejectWithValue(error.response.data as ServerErrorResponse);
            }
            throw error;
        }
    },
);

export const RatingScaleSlice = createSlice({
    name: 'ratingScales',
    initialState,
    reducers: {},
    extraReducers(builder) {
        builder
            .addCase(fetchRatingScales.pending, (state: Draft<RatingScaleState>) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(
                fetchRatingScales.fulfilled,
                (state: Draft<RatingScaleState>, action: PayloadAction<RatingScale[] | PaginatedRatingScales>) => {
                    if (Array.isArray(action.payload)) {
                        state.ratingScales = action.payload;
                        state.meta = undefined;
                        state.links = undefined;
                    } else {
                        state.ratingScales = action.payload.data;
                        state.meta = action.payload.meta;
                        state.links = action.payload.links;
                    }
                    state.error = null;
                    state.loading = false;
                },
            )
            .addCase(fetchRatingScales.rejected, (state: Draft<RatingScaleState>) => {
                state.loading = false;
                message.error(
                    'Failed to load Rating Scales. Please try again or contact support if the issue persists',
                );
            });

        builder
            .addCase(createRatingScale.pending, (state: Draft<RatingScaleState>) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(
                createRatingScale.fulfilled,
                (state: Draft<RatingScaleState>, action: PayloadAction<RatingScale>) => {
                    state.ratingScales.unshift(action.payload);
                    state.error = null;
                    state.loading = false;
                },
            )
            .addCase(
                createRatingScale.rejected,
                (state: Draft<RatingScaleState>, action: RejectedActionPayload) => {
                    state.loading = false;
                    message.error(Helpers.handleServerError(action.payload), 10);
                },
            );

        builder
            .addCase(updateRatingScale.pending, (state: Draft<RatingScaleState>) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(
                updateRatingScale.fulfilled,
                (state: Draft<RatingScaleState>, action: PayloadAction<RatingScale>) => {
                    state.loading = false;
                    state.error = null;
                    message.success('Successfully updated Rating Scale', 10);
                },
            )
            .addCase(
                updateRatingScale.rejected,
                (state: Draft<RatingScaleState>, action: RejectedActionPayload) => {
                    state.loading = false;
                    message.error(Helpers.handleServerError(action.payload), 10);
                },
            );

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

export default RatingScaleSlice;
export type { RatingScaleState };
