import { createAsyncThunk , createSlice , PayloadAction , current } from "@reduxjs/toolkit";
import axios from 'axios'
import { fireAlert } from "./alert-slice";
import { truncate } from "fs";
// set the const variables for the slice
const ACTION_NAME = 'members'
// slice initial value state
type IinitialState = {
    value : IValueState;
}
// state value type
type IValueState = {
    empty: boolean,
    isLoading: boolean,
    loadedFirstTime: boolean,
    total: number,
    currentPage: number,
    searchKeyword: string,
    listContent: {
        // this is not a const so it get different for each list
        _id: string | null,
        firstName: string,
        lastName: string,
        email: string,
        phone: string,
        address: string,
        registerAt: string,
        registerAt_unix: string,
        services: {
            serviceID: String,
            serviceName: String,
        }[],
        payMonth: string,
        planUpdatedAt: string,
        planUpdatedAt_unix: number,
        planDelay: Number,
        planDelay_unix: number,
        planExpAt: String,
        planExpAt_unix: number,
        active: boolean,
        gendre: string, // m or w
        bodyState: {
            startBodyForm: string,
            currentBodyForm: string,
            startWeight: number,
            currentWeight: number,
        }
    }[],
    detailsPopUp: boolean,
    detailsPopUpData: {
        _id: string | null,
        firstName: string | null,
        lastName: string | null,
        email: string | null,
        phone: string | null,
        address: string | null,
        registerAt: string | null,
        registerAt_unix: string | null,
        services: {
            serviceID: string | null,
            serviceName: string | null,
        }[] | null,
        payMonth: string | null,
        planUpdatedAt: string | null,
        planUpdatedAt_unix: number | null,
        planDelay: number | null,
        planDelay_unix: number | null,
        planExpAt: string | null,
        planExpAt_unix: number | null,
        active: boolean | null,
        gendre: string | null, // m or w
        bodyState: {
            startBodyForm: string | null,
            currentBodyForm: string | null,
            startWeight: number | null,
            currentWeight: number | null,
        }
    } | null,
    addPopUp: boolean,
    isAdding: boolean,
    updatePopUp: boolean,
    updatePopUpData: {
        _id: string | null,
        firstName: string | null,
        lastName: string | null,
        email: string | null,
        phone: string | null,
        address: string | null,
        registerAt: string | null,
        registerAt_unix: string | null,
        services: {
            serviceID: string | null,
            serviceName: string | null,
        }[] | null,
        payMonth: string | null,
        planUpdatedAt: string | null,
        planUpdatedAt_unix: number | null,
        planDelay: number | null,
        planDelay_unix: number | null,
        planExpAt: string | null,
        planExpAt_unix: number | null,
        active: boolean | null,
        gendre: string | null, // m or w
        bodyState: {
            startBodyForm: string | null,
            currentBodyForm: string | null,
            startWeight: number | null,
            currentWeight: number | null,
        }
    } | null,
    isUpdating: boolean,
    updateSubPopUp: boolean,
    updateSubPopUpData: {
        _id: string | null,
        services: {
            serviceID: string | null,
            serviceName: string | null,
        }[] | null,
        planDelay: number | null,
        bodyState: {
            currentBodyForm: string | null,
            currentWeight: number | null,
        }
    } | null,
}
// set the initial state
const initialState = {
    value: {
        empty: true,
        isLoading: false,
        loadedFirstTime: false,
        total: 0,
        currentPage: 1,
        searchKeyword: '',
        listContent: [],
        detailsPopUp: false,
        detailsPopUpData: {
            _id: null,
            firstName: null,
            lastName: null,
            email: null,
            phone: null,
            address: null,
            registerAt: null,
            registerAt_unix: null,
            services:null,
            payMonth: null,
            planUpdatedAt: null,
            planUpdatedAt_unix: null,
            planDelay: null,
            planDelay_unix: null,
            planExpAt: null,
            planExpAt_unix: null,
            active: null,
            gendre: null, // m or w
            bodyState: {
                startBodyForm: null,
                currentBodyForm: null,
                startWeight: null,
                currentWeight: null,
            }
        },
        addPopUp: false,
        isAdding: false,
        updatePopUp: false,
        updatePopUpData: {
            _id: null,
            firstName: null,
            lastName: null,
            email: null,
            phone: null,
            address: null,
            registerAt: null,
            registerAt_unix: null,
            services: null,
            payMonth: null,
            planUpdatedAt: null,
            planUpdatedAt_unix: null,
            planDelay: null,
            planDelay_unix: null,
            planExpAt: null,
            planExpAt_unix: null,
            active: null,
            gendre: null, // m or w
            bodyState: {
                startBodyForm: null,
                currentBodyForm: null,
                startWeight: null,
                currentWeight: null,
            }
        },
        isUpdating: false,
        updateSubPopUp: false,
        updateSubPopUpData: {
            _id: null,
            services: null,
            planDelay: null,
            bodyState: {
                currentBodyForm: null,
                currentWeight: null,
            }
        },
        isSubUpdating: false,
    }
} as IinitialState
// thunks
// add ability
const add = createAsyncThunk(
    'members/add',
    async (actionPayload : {
        firstName: string | null,
        lastName: string | null,
        email: string | null,
        phone: string | null,
        address: string | null,
        services: {
            serviceID: string | null,
            serviceName: string | null,
        }[] | null,
        planDelay: string | null,
        gendre: string | null, // m or w
        bodyState: {
            startBodyForm: string | null,
            startWeight: string | null,
        }
    } , thunkAPI) => {
        try{

            let { data } = await axios.post(`/api/user/actions/${ACTION_NAME}` , {
               payload:actionPayload
            })
            if(data.success)
            {
                thunkAPI.dispatch(fireAlert({ 
                    success: true,
                    message: "actionDoneWithSuccess",
                }))
                return data
            }
            else {
                thunkAPI.dispatch(fireAlert({
                    success: false,
                    message: data.message
                }))
                return { success : false }
            }
        }catch(e)
        {
            thunkAPI.dispatch(fireAlert({
                success: false,
                message: "unkownError",
            }))
            return { success : false }
        }
    }
)
// load data ability
const load = createAsyncThunk(
    'members/load',
    async (actionPayload : { page : number }, thunkAPI) => {
        try {
            let { data } = await axios.get(`/api/user/actions/${ACTION_NAME}?type=page&page=`+actionPayload.page)
            if(data.success)
            {
                return data
            }
            else 
            {
                return { success : false }
            }
        }catch(err) {
            return { success : false }
        }
    }
)
// search ability
const search = createAsyncThunk(
    'members/search',
    async (actionPayload : {searchKeyword: string}, thunkAPI) => {
        try {
            let { data } = await axios.get(`/api/user/actions/${ACTION_NAME}?type=search&searchKeyword=`+actionPayload.searchKeyword)
            if(data.success)
            {
                return data
            }
            else 
            {                
                thunkAPI.dispatch(fireAlert({ 
                    success: false,
                    message: data.message,
                }))
                return { success : false }
            }
        }catch(err) {
            return { success : false }
        }
    }
)
// delete ability
const delete_ = createAsyncThunk(
    'members/delete',
    async (actionPayload : {id: string | null}, thunkAPI) => {
        const state : any = thunkAPI.getState()
        try {
            let { data } = await axios.delete(`/api/user/actions/${ACTION_NAME}?_id=${actionPayload.id}&page=${state.membersReducer.value.currentPage}`)
            if(data.success)
            {
                thunkAPI.dispatch(fireAlert({ 
                    success: true,
                    message: "actionDoneWithSuccess",
                }))
                return {
                    success: true,
                    id: actionPayload.id,
                    data: data.data
                }
            }
            else 
            {
                return { success : false }
            }
        }catch(err) {
            return { success : false }
        }
    }
)
// update ability
const update = createAsyncThunk(
    "members/update",
    async (actionPayload : {
        _id: string | null | undefined,
        firstName : string | null | undefined , 
        lastName : string | null | undefined , 
        email : string | null | undefined , 
        phone : string | null | undefined , 
        address : string | null | undefined ,
        active: boolean | null | undefined,
    }, thunkAPI) => {
        try {
            let { data } = await axios.put(`/api/user/actions/${ACTION_NAME}`, {
                payload: actionPayload,
                args: {
                    type: "personal"
                }
            })
            console.log("data #oifd" , data)
            if(data.success)
            {
                thunkAPI.dispatch(fireAlert({ 
                    success: true,
                    message: "actionDoneWithSuccess",
                }))
                return data
            }
            else 
            {
                return { success : false }
            }
        }catch(err) {
            return { success : false }
        }
    }
)
// update subscription ability
const updateSub = createAsyncThunk(
    'services/updateSub',
    async (actionPayload : {
        _id: string | null | undefined,
        services: [string] | [] | undefined,
        planDelay: number | null | undefined,
        bodyState: {
            currentBodyForm: string | null,
            currentWeight: string | null
        } | null;
    }, thunkAPI) => {
        try {
            let { data } = await axios.put(`/api/user/actions/${ACTION_NAME}`, {
                args: {
                    type: "subscription"
                },
                payload: actionPayload
            })
            if(data.success)
            {
                thunkAPI.dispatch(fireAlert({ 
                    success: true,
                    message: "actionDoneWithSuccess",
                }))
                return data
            }
            else 
            {
                return { success : false }
            }
        }catch(err) {
            return { success : false }
        }
    }
)
// init the slice
export const members = createSlice({
    name: ACTION_NAME,
    initialState,
    reducers: {
        // set the current list page
        setCurrentPage: (state , action: PayloadAction<number>) => {
            state.value.currentPage = action.payload
        },
        // set the list search keyword
        setSearchKeyword : (state , action : PayloadAction<string>) => {
            state.value.searchKeyword = action.payload
        },
        // set the details popup status
        setDetailsPopUp: (state , action : PayloadAction<{
            status: boolean,
            data: {
                _id: string | null,
                firstName: string | null,
                lastName: string | null,
                email: string | null,
                phone: string | null,
                address: string | null,
                registerAt: string,
                registerAt_unix: string | null,
                services: {
                    serviceID: string | null,
                    serviceName: string | null,
                }[] | null,
                payMonth: string | null,
                planUpdatedAt: string | null,
                planUpdatedAt_unix: number | null,
                planDelay: number | null,
                planDelay_unix: number | null,
                planExpAt: string | null,
                planExpAt_unix: number | null,
                active: boolean | null,
                gendre: string | null, // m or w
                bodyState: {
                    startBodyForm: string | null,
                    currentBodyForm: string | null,
                    startWeight: number | null,
                    currentWeight: number | null,
                }
            } | null
        }>) => {
            state.value.detailsPopUp = action.payload.status
            if(action.payload.data)
            {
                state.value.detailsPopUpData = action.payload.data
            }
        },
        // set the add popup status
        setAddPopUp: (state , action : PayloadAction<boolean>) => {
            state.value.addPopUp = action.payload
        },
        // set the update popup status
        setUpdatePopUp: (state , action : PayloadAction<{
            status: boolean,
            data: {        
                _id: string | null,
                firstName: string | null,
                lastName: string | null,
                email: string | null,
                phone: string | null,
                address: string | null,
                registerAt: string | null,
                registerAt_unix: string | null,
                services: {
                    serviceID: string | null,
                    serviceName: string | null,
                }[] | null,
                payMonth: string | null,
                planUpdatedAt: string | null,
                planUpdatedAt_unix: number | null,
                planDelay: number | null,
                planDelay_unix: number | null,
                planExpAt: string | null,
                planExpAt_unix: number | null,
                active: boolean | null,
                gendre: string | null, // m or w
                bodyState: {
                    startBodyForm: string | null,
                    currentBodyForm: string | null,
                    startWeight: number | null,
                    currentWeight: number | null,
                }
            } | null
        }>) => {
            state.value.updatePopUp = action.payload.status
            console.log(state.value.updatePopUp , "state.value.updatePopUp")
            if(action.payload.data)
            {
                state.value.updatePopUpData = action.payload.data
            }
        },
        // set the update sub popup status
        setUpdateSubPopUp: (state , action : PayloadAction<{
            status: boolean,
            data: {
                _id: string | null,
                services: {
                    serviceID: string | null,
                    serviceName: string | null,
                }[] | null,
                planDelay: number | null,
                bodyState: {
                    currentBodyForm: string | null,
                    currentWeight: number | null,
                }
            } | null
        }>) => {
            state.value.updateSubPopUp = action.payload.status
            if(action.payload.data)
            {
                state.value.updateSubPopUpData = action.payload.data
            }
        }
    },
    extraReducers: (builder) => {
        // add ability
        builder.addCase(add.pending, (state : IinitialState , action) => {
            state.value.isAdding = true
        })
        builder.addCase(add.fulfilled, (state : IinitialState , action) => {
            if(action.payload.success) state.value.listContent.push(action.payload.data)
            state.value.isAdding = false
        })
        // load ability
        builder.addCase(load.pending, (state : IinitialState , action) => {
            state.value.isLoading = true;
        })
        builder.addCase(load.fulfilled, (state : IinitialState , action) => {
            if(action.payload.success) {
                state.value.listContent = action.payload.data.docs
                state.value.isLoading = false;
                state.value.loadedFirstTime = true;
                state.value.total = action.payload.data.docs_count
            }
        })
        // search ability
        builder.addCase(search.pending, (state : IinitialState , action) => {
            state.value.isLoading = true;
        })
        builder.addCase(search.fulfilled, (state : IinitialState , action) => {
            if(action.payload.success) {
                state.value.listContent = action.payload.data.docs
                state.value.total = action.payload.data.docs_count
            }
            state.value.isLoading = false;
        })
        // delete ability
        builder.addCase(delete_.pending, (state : IinitialState , action) => {
            state.value.isLoading = true;
        })
        builder.addCase(delete_.fulfilled, (state : IinitialState , action) => {
            state.value.isLoading = false;
            if(action.payload.success)
            {                
                state.value.listContent = action.payload.data.docs
                state.value.total = action.payload.data.docs_count
                if(Math.ceil(action.payload.data.totalArrLength / 4) < state.value.currentPage)
                {
                    state.value.currentPage -= 1
                }
            }
        })
        // update ability
        builder.addCase(update.pending, (state : IinitialState , action) => {
            state.value.isUpdating = true;
        })
        builder.addCase(update.fulfilled, (state : IinitialState , action) => {
            state.value.isUpdating = false;
            // update the obj in the ui
            // first we get the obj index
            const indexOfObjectToUpdate = state.value.listContent.findIndex(obj => obj._id === action.payload.data._id);
            // we copie the list content
            const updatedObjects = [...state.value.listContent];
            // we update the obj in the list copie
            updatedObjects[indexOfObjectToUpdate] = action.payload.data;
            // we set the original list value to the copie
            state.value.listContent = updatedObjects
        })
    }
})
// export reducers
export const { setCurrentPage , setSearchKeyword , setDetailsPopUp , setAddPopUp , setUpdatePopUp , setUpdateSubPopUp } = members.actions;
// export extra reducers
export { add , load , search , delete_ , update , updateSub }
// export the slice
export default members.reducer;