import { handleAuthentication, handleToastError, getFCMToken, removeFCMToken as removeFCMTokenFromStorage } from '@/lib/utils';
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

import api from '@/lib/axios';
import { RootState } from '@/lib/redux/store';

// Interface for user data
interface UserData {
    token: string | null;
    first_name: string | null;
    last_name: string | null;
    email: string | null;
    modules: Array<{
        module_id: number;
        module_type: string;
        permission_id: number;
        permission_name: string;
    }> | null;
}

// Team member profile interface
interface TeamMemberProfile {
    id: number;
    role_id: number;
    user_id: number | null;
    reporting_to_id: number | null;
    profile_photo: string;
    first_name: string;
    last_name: string;
    email: string;
    phone_number: string;
    country_code: string;
    dob: string | null;
    gender: string | null;
    emergency_contact_name: string | null;
    emergency_contact_code: string | null;
    emergency_contact_number: string | null;
    joining_date: string | null;
    employment_type: string;
    status: string;
    current_step: number;
    form_status: string;
    role: {
        id: number;
        name: string;
        status: number;
        description: string;
        parent_role_id: number | null;
    };
    department: any[];
    business_vertical: any[];
    addresses: any[];
    id_proofs: any[];
    reporting_to: any | null;
}

// Initial state interface
interface AuthState {
    id: number | null;
    token: string | null;
    refresh_token?: string | null;
    first_name: string | null;
    last_name: string | null;
    email: string | null;
    profile_pic?: string | null;
    role?: any | null;
    modules: Array<{
        module_id: number;
        module_type: string;
        permission_id: number;
        permission_name: string;
    }> | null;
    team_member_id: any | null;
    team_member_profile: TeamMemberProfile | null;
    isAuthenticated: boolean;
    isLoading: boolean;
    error: string | null;
    forgotPasswordStatus: 'idle' | 'success' | 'error' | null;
    resetPasswordStatus: 'idle' | 'success' | 'error' | null;
}

// Initial state
const initialState: AuthState = {
    id: null,
    token: null,
    refresh_token: null,
    first_name: null,
    last_name: null,
    email: null,
    profile_pic: null,
    role: null,
    modules: null,
    team_member_id: null,
    team_member_profile: null,
    isAuthenticated: false,
    isLoading: false,
    error: null,
    forgotPasswordStatus: null,
    resetPasswordStatus: null,
};

interface LoginResponse {
    id: number;
    token: string;
    first_name: string;
    last_name: string;
    email: string;
    profile_pic: string | null;
    role: any | null;
    team_member_id: number | null;
    modules: Array<{
        module_id: number;
        module_type: string;
        permission_id: number;
        permission_name: string;
    }> | null;
    team_member_profile?: TeamMemberProfile | null;
}

// Login
export const loginUser = createAsyncThunk(
    'auth/login',
    async (
        {
            email,
            password,
            device_id,
            device_type,
            fcm_token,
        }: { email: string; password: string; device_id?: string; device_type?: string; fcm_token?: string },
        { rejectWithValue, dispatch },
    ) => {
        try {
            const response = await api.post(
                '/auth/login',
                {
                    email,
                    password,
                    device_id: device_id ?? 'nuskin_web',
                    device_type: device_type ?? 'web',
                    fcm_token: fcm_token ?? null,
                },
                { headers: { 'Content-Type': 'application/json' } },
            );

            const data = response.data;

            // Check if login was successful
            if (data.success) {
                return {
                    id: data?.data?.id,
                    token: data?.data?.access_token,
                    first_name: data?.data?.first_name,
                    last_name: data?.data?.last_name,
                    email: data?.data?.email,
                    profile_pic: data?.data?.profile_pic || null,
                    role: data?.data?.role || null,
                    team_member_id: data?.data?.team_member_id || null,
                    modules: data?.data?.modules,
                    refresh_token: data?.data?.refresh_token,
                };

                // If we have both token and team_member_id, fetch the profile
            } else {
                return rejectWithValue(data.message || 'Login failed');
            }
        } catch (error: any) {
            if (error.response?.data?.message) {
                return rejectWithValue(error.response.data.message);
            } else if (error.response?.data) {
                return rejectWithValue(error.response.data);
            } else if (error.message) {
                return rejectWithValue(error.message);
            } else {
                return rejectWithValue('Network error. Please try again.');
            }
        }
    },
);

// Forgot Password
export const forgotPassword = createAsyncThunk('auth/forgotPassword', async (email: string, { rejectWithValue }) => {
    try {
        const response = await api.post(`/auth/forgot-password`, { email }, { headers: { 'Content-Type': 'application/json' } });

        return response.data;
    } catch (error: any) {
        if (error.response) {
            return rejectWithValue(error.response.data.message || 'Password reset request failed');
        } else if (error.request) {
            return rejectWithValue('No response from server');
        } else {
            return rejectWithValue('Error in processing your request');
        }
    }
});

// Reset Password

export const resetPassword = createAsyncThunk(
    'auth/resetPassword',
    async ({ token, email, password }: { token: string; email: string; password: string }, { rejectWithValue }) => {
        try {
            const response = await api.post(
                `/auth/reset-password?token=${token}`,
                { email, password },
                { headers: { 'Content-Type': 'application/json' } },
            );

            return response.data;
        } catch (error: any) {
            if (error.response) {
                return rejectWithValue(error.response.data.message || 'Password reset failed');
            } else if (error.request) {
                return rejectWithValue('No response from server');
            } else {
                return rejectWithValue('Error in processing your password reset');
            }
        }
    },
);

export const changePassword = createAsyncThunk(
    'auth/changePassword',
    async ({ old_password, new_password }: { old_password: string; new_password: string }, { rejectWithValue }) => {
        try {
            const response = await api.post(
                `/auth/change-password`,
                { old_password, new_password },
                {
                    headers: {
                        'Content-Type': 'application/json',
                    },
                },
            );

            return response.data;
        } catch (error: any) {
            if (error.response) {
                return rejectWithValue(error.response.data.message || 'Password change failed');
            } else if (error.request) {
                return rejectWithValue('No response from server');
            } else {
                return rejectWithValue('Error in processing your password change');
            }
        }
    },
);

// Fetch team member profile
export const fetchTeamMemberProfile = createAsyncThunk('auth/fetchTeamMemberProfile', async (id: number, { rejectWithValue }) => {
    try {
        const response = await api.get(`/team-member/list/${id}`);
        return response.data.data;
    } catch (error: any) {
        return rejectWithValue(error.message || 'Failed to fetch team member profile');
    }
});

// Update team member profile
export const updateProfile = createAsyncThunk(
    'auth/updateProfile',
    async (
        { id, data }: { id: number; data: Partial<TeamMemberProfile> & { profile_photo?: File } },
        { rejectWithValue, getState },
    ) => {
        try {
            const formData = new FormData();

            // Handle profile photo separately
            if (data.profile_photo) {
                formData.append('profile_photo', data.profile_photo);
            }

            // Handle other fields
            Object.entries(data).forEach(([key, value]) => {
                if (key !== 'profile_photo' && value !== undefined && value !== null) {
                    formData.append(key, value.toString());
                }
            });

            const response = await api.put(`/team-member/update/${id}`, formData, {
                headers: {
                    'Content-Type': 'multipart/form-data',
                },
            });

            // After successful update, fetch the latest profile data
            const profileResponse = await api.get(`/team-member/list/${id}`);

            // Update the state immediately with the new data
            const state = getState() as RootState;
            if (state.auth.team_member_profile) {
                return {
                    ...state.auth.team_member_profile,
                    ...profileResponse.data,
                };
            }

            return profileResponse.data;
        } catch (error: any) {
            return rejectWithValue(error.message || 'Failed to update profile');
        }
    },
);

export const removeFCMToken = createAsyncThunk('auth/removeFCMToken', async (fcm_token: string, { rejectWithValue }) => {
    try {
        const response = await api.post('/auth/remove-fcm-token', {
            fcm_token,
        });
        return response.data;
    } catch (error: any) {
        if (error?.response?.data?.message) return rejectWithValue(error.response.data.message);
        if (error?.message) return rejectWithValue(error.message);
        return rejectWithValue('Failed to remove FCM token');
    }
});

export const logOutUser = createAsyncThunk('auth/logout', async (_, { rejectWithValue }) => {
    try {
        const response = await api.post('/auth/logout');
        return response.data;
    } catch (error: any) {
        if (error?.response?.data?.message) return rejectWithValue(error.response.data.message);
        if (error?.message) return rejectWithValue(error.message);
        return rejectWithValue('Failed to remove FCM token');
    }
});

// Auth slice
const authSlice = createSlice({
    name: 'auth',
    initialState,
    reducers: {
        logout: (state) => {
            removeFCMTokenFromStorage();

            state.id = null;
            state.token = null;
            state.refresh_token = null;
            state.first_name = null;
            state.last_name = null;
            state.email = null;
            state.modules = null;
            state.team_member_profile = null;
            state.isAuthenticated = false;
            state.error = null;
        },
        // Set tokens (access + refresh) — used by axios after successful refresh
        setTokens: (state, action) => {
            const { token, refresh_token } = action.payload || {};
            if (token) state.token = token;
            if (refresh_token) state.refresh_token = refresh_token;
            state.isAuthenticated = !!state.token;
        },
        clearError: (state) => {
            state.error = null;
        },
        resetForgotPasswordStatus: (state) => {
            state.forgotPasswordStatus = null;
        },
        resetResetPasswordStatus: (state) => {
            state.resetPasswordStatus = null;
        },
        // Add a new reducer to manually update profile data
        updateProfileData: (state, action) => {
            if (state.team_member_profile) {
                state.team_member_profile = {
                    ...state.team_member_profile,
                    ...action.payload,
                };
            } else {
                state.team_member_profile = action.payload;
            }
        },
        // Add a new reducer to force refresh profile data
        refreshProfile: (state) => {
            state.team_member_profile = null;
        },
    },
    extraReducers: (builder) => {
        builder
            // Login reducers
            .addCase(loginUser.pending, (state) => {
                state.isLoading = true;
                state.error = null;
            })
            .addCase(loginUser.fulfilled, (state, action) => {
                state.isLoading = false;
                state.id = action.payload.id;
                state.token = action.payload.token;
                state.first_name = action.payload.first_name;
                state.last_name = action.payload.last_name;
                state.email = action.payload.email;
                state.role = action.payload.role;
                state.profile_pic = action.payload.profile_pic || null;
                state.team_member_id = action.payload.team_member_id;
                state.modules = action.payload.modules;
                const payload: any = action.payload;
                state.team_member_profile = payload.team_member_profile || null;
                state.isAuthenticated = true;
                state.refresh_token = payload.refresh_token;
                state.error = null;
            })
            .addCase(loginUser.rejected, (state, action) => {
                state.isLoading = false;
                state.error = action.payload as string;
                state.isAuthenticated = false;
            })
            // Forgot Password reducers
            .addCase(forgotPassword.pending, (state) => {
                state.isLoading = true;
                state.forgotPasswordStatus = null;
                state.error = null;
            })
            .addCase(forgotPassword.fulfilled, (state) => {
                state.isLoading = false;
                state.forgotPasswordStatus = 'success';
            })
            .addCase(forgotPassword.rejected, (state, action) => {
                state.isLoading = false;
                state.forgotPasswordStatus = 'error';
                state.error = action.payload as string;
            })

            // Reset Password reducers
            .addCase(resetPassword.pending, (state) => {
                state.isLoading = true;
                state.resetPasswordStatus = null;
                state.error = null;
            })
            .addCase(resetPassword.fulfilled, (state) => {
                state.isLoading = false;
                state.resetPasswordStatus = 'success';
            })
            .addCase(resetPassword.rejected, (state, action) => {
                state.isLoading = false;
                state.resetPasswordStatus = 'error';
                state.error = action.payload as string;
            })
            .addCase(changePassword.pending, (state) => {
                state.isLoading = true;
                state.error = null;
            })
            .addCase(changePassword.fulfilled, (state) => {
                state.isLoading = false;
                state.error = null;
            })
            .addCase(changePassword.rejected, (state, action) => {
                state.isLoading = false;
                state.error = action.payload as string;
            })
            // Team member profile cases
            .addCase(fetchTeamMemberProfile.pending, (state) => {
                state.isLoading = true;
                state.error = null;
            })
            .addCase(fetchTeamMemberProfile.fulfilled, (state, action) => {
                state.isLoading = false;
                if (state.team_member_profile) {
                    state.team_member_profile = {
                        ...state.team_member_profile,
                        ...action.payload,
                    };
                } else {
                    state.team_member_profile = action.payload;
                }
                state.error = null;
            })
            .addCase(fetchTeamMemberProfile.rejected, (state, action) => {
                state.isLoading = false;
                state.error = action.payload as string;
            })
            .addCase(updateProfile.pending, (state) => {
                state.isLoading = true;
                state.error = null;
            })
            .addCase(updateProfile.fulfilled, (state, action) => {
                state.isLoading = false;
                state.team_member_profile = action.payload;
                state.error = null;
            })
            .addCase(updateProfile.rejected, (state, action) => {
                state.isLoading = false;
                state.error = action.payload as string;
            });
    },
});

export const {
    logout,
    clearError,
    resetForgotPasswordStatus,
    resetResetPasswordStatus,
    updateProfileData,
    refreshProfile,
    setTokens,
} = authSlice.actions;

export default authSlice.reducer;
