import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import {
    Competency,
    CompetencyResponse,
    CreateCompetencyPayload,
    PaginatedCompetencies
} from '@/interface/Competency';
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 { CompetencyActions } from './actionTypes';
import { PaginationLinks, PaginationMeta } from '@/interface/Paginated';
import { GetParams, toQueryString } from '@/interface/GetParams';

interface CompetencyState {
    competencies: Competency[];
    links?: PaginationLinks;
    meta?: PaginationMeta;
    loading: boolean;
    error: string | null;
}

const initialState: CompetencyState = {
    competencies: [],
    loading: false,
    error: null,
};

export const fetchCompetencies = createAsyncThunk(
    CompetencyActions.FETCH_COMPETENCY_REQUEST,
    async (params?: GetParams) => {
        const query = toQueryString(params);
        const response = (await apiGet(`/competencies${query}`)) as AxiosResponse<PaginatedCompetencies>;
        return response.data;
    },
);

export const createCompetency = createAsyncThunk(
    CompetencyActions.CREATE_COMPETENCY_REQUEST,
    async (payload: CreateCompetencyPayload, { rejectWithValue }) => {
        try {
            const response = (await apiPost(
                '/competencies',
                payload,
            )) as AxiosResponse<CompetencyResponse>;
            return response.data.data;
        } catch (error) {
            if (axios.isAxiosError(error) && error.response) {
                return rejectWithValue(error.response.data as ServerErrorResponse);
            }
            throw error;
        }
    },
);

export const updateCompetency = createAsyncThunk(
    CompetencyActions.UPDATE_COMPETENCY_REQUEST,
    async (payload: CreateCompetencyPayload & { id: string }, { rejectWithValue }) => {
        try {
            const response = (await apiPut(
                `/competencies/${payload.id}`,
                payload,
            )) as AxiosResponse<CompetencyResponse>;
            return response.data.data;
        } catch (error) {
            if (axios.isAxiosError(error) && error.response) {
                return rejectWithValue(error.response.data as ServerErrorResponse);
            }
            throw error;
        }
    },
);

export const deleteCompetency = createAsyncThunk(
    CompetencyActions.DELETE_COMPETENCY_REQUEST,
    async (payload: string, { rejectWithValue }) => {
        try {
            const response = (await apiDelete(
                `/competencies/${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 CompetencySlice = createSlice({
    name: 'competencies',
    initialState,
    reducers: {},
    extraReducers(builder) {
        builder
            .addCase(fetchCompetencies.pending, (state: Draft<CompetencyState>) => {
                state.loading = true;
                state.error = null;
            })
            .addCase(
                fetchCompetencies.fulfilled,
                (state: Draft<CompetencyState>, action: PayloadAction<Competency[] | PaginatedCompetencies>) => {
                    if (Array.isArray(action.payload)) {
                        state.competencies = action.payload;
                        state.meta = undefined;
                        state.links = undefined;
                    } else {
                        state.competencies = action.payload.data;
                        state.meta = action.payload.meta;
                        state.links = action.payload.links;
                    }
                    state.error = null;
                    state.loading = false;
                },
            )
            .addCase(fetchCompetencies.rejected, (state: Draft<CompetencyState>) => {
                state.loading = false;
                message.error(
                    'Failed to load Competencies. Please try again or contact support if the issue persists',
                );
            });

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

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

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

export default CompetencySlice;
export type { CompetencyState };
