import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
    AppraisalType,
    AppraisalTypeResponse,
    CreateAppraisalTypePayload,
    PaginatedAppraisalTypes
} from '@/interface/AppraisalType';
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 { AppraisalTypeActions } from './actionTypes';
import { PaginationLinks, PaginationMeta } from '@/interface/Paginated';
import { GetParams, toQueryString } from '@/interface/GetParams';


interface AppraisalTypeState {
    appraisalTypes: AppraisalType[];
    links?: PaginationLinks;
    meta?: PaginationMeta;
    loading: boolean;
    error: string | null;
}

const initialState: AppraisalTypeState = {
    appraisalTypes: [],
    loading: false,
    error: null,
};

export const fetchAppraisalTypes = createAsyncThunk(
    AppraisalTypeActions.FETCH_APPRAISAL_TYPE_REQUEST,
    async (params?: GetParams) => {
        const query = toQueryString(params);
        const response = (await apiGet(`/appraisal-types${query}`)) as AxiosResponse<PaginatedAppraisalTypes>;
        return response.data;
    },
);

export const createAppraisalType = createAsyncThunk(
    AppraisalTypeActions.CREATE_APPRAISAL_TYPE_REQUEST,
    async (payload: CreateAppraisalTypePayload, { rejectWithValue }) => {
        try {
            const response = (await apiPost(
                '/appraisal-types',
                payload,
            )) as AxiosResponse<AppraisalTypeResponse>;
            return response.data.data;
        } catch (error) {
            if (axios.isAxiosError(error) && error.response) {
                return rejectWithValue(error.response.data as ServerErrorResponse);
            }
            throw error;
        }
    },
);

export const updateAppraisalType = createAsyncThunk(
    AppraisalTypeActions.UPDATE_APPRAISAL_TYPE_REQUEST,
    async (payload: CreateAppraisalTypePayload & { id: string }, { rejectWithValue }) => {
        try {
            const response = (await apiPut(
                `/appraisal-types/${payload.id}`,
                payload,
            )) as AxiosResponse<AppraisalTypeResponse>;
            return response.data.data;
        } catch (error) {
            if (axios.isAxiosError(error) && error.response) {
                return rejectWithValue(error.response.data as ServerErrorResponse);
            }
            throw error;
        }
    },
);

export const deleteAppraisalType = createAsyncThunk(
    AppraisalTypeActions.DELETE_APPRAISAL_TYPE_REQUEST,
    async (payload: string, { rejectWithValue }) => {
        try {
            const response = (await apiDelete(
                `/appraisal-types/${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 AppraisalTypeSlice = createSlice({
    name: 'appraisalTypes',
    initialState,
    reducers: {},
    extraReducers(builder) {
        builder
            .addCase(fetchAppraisalTypes.pending, (state: Draft<AppraisalTypeState>) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(
                fetchAppraisalTypes.fulfilled,
                (state: Draft<AppraisalTypeState>, action: PayloadAction<AppraisalType[] | PaginatedAppraisalTypes>) => {
                    if (Array.isArray(action.payload)) {
                        state.appraisalTypes = action.payload;
                        state.meta = undefined;
                        state.links = undefined;
                    } else {
                        state.appraisalTypes = action.payload.data;
                        state.meta = action.payload.meta;
                        state.links = action.payload.links;
                    }
                    state.error = null;
                    state.loading = false;
                },
            )
            .addCase(fetchAppraisalTypes.rejected, (state: Draft<AppraisalTypeState>) => {
                state.loading = false;
                message.error(
                    'Failed to load Appraisal Types. Please try again or contact support if the issue persists',
                );
            });

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

        builder
            .addCase(updateAppraisalType.pending, (state: Draft<AppraisalTypeState>) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(
                updateAppraisalType.fulfilled,
                (state: Draft<AppraisalTypeState>, action: PayloadAction<AppraisalType>) => {
                    state.loading = false;
                    state.error = null;
                    message.success('Successfully updated Appraisal Type', 10);
                },
            )
            .addCase(
                updateAppraisalType.rejected,
                (state: Draft<AppraisalTypeState>, action: RejectedActionPayload) => {
                    state.loading = false;
                    message.error(Helpers.handleServerError(action.payload), 10);
                },
            );

        builder
            .addCase(deleteAppraisalType.pending, (state: Draft<AppraisalTypeState>) => { })
            .addCase(
                deleteAppraisalType.fulfilled,
                (state: Draft<AppraisalTypeState>, action: PayloadAction<{ message: string; id: string }>) => {
                    state.appraisalTypes = state.appraisalTypes.filter((unit) => unit.id !== action.payload.id);

                    message.success(action.payload.message, 10);
                },
            )
            .addCase(deleteAppraisalType.rejected, (state: Draft<AppraisalTypeState>, action: RejectedActionPayload) => {
                message.error(Helpers.handleServerError(action.payload), 8);
            });
    },
});

export default AppraisalTypeSlice;
export type { AppraisalTypeState };
