import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { profileService } from "@/features/profile/services/profile.service";
import type { ProfileUser, UpdateProfilePayload } from "@/types/api/profile.types";

interface ProfileState {
  user: ProfileUser | null;
  isLoading: boolean;
  isUpdating: boolean;
  error: string | null;
}

const initialState: ProfileState = {
  user: null,
  isLoading: false,
  isUpdating: false,
  error: null,
};

function extractMessage(err: unknown, fallback: string): string {
  const errMsg = (err as Error)?.message;
  const httpMsg = (err as { response?: { data?: { message?: string } } })
    ?.response?.data?.message;
  return httpMsg ?? errMsg ?? fallback;
}

export const fetchProfile = createAsyncThunk(
  "profile/fetch",
  async (_, { rejectWithValue }) => {
    try {
      const data = await profileService.getProfile();
      return data.result[0];
    } catch (err) {
      return rejectWithValue(extractMessage(err, "Failed to load profile."));
    }
  },
);

export const updateProfile = createAsyncThunk(
  "profile/update",
  async (payload: UpdateProfilePayload | FormData, { rejectWithValue }) => {
    try {
      const data = await profileService.updateProfile(payload);
      return data.result[0];
    } catch (err) {
      return rejectWithValue(extractMessage(err, "Failed to update profile."));
    }
  },
);

const profileSlice = createSlice({
  name: "profile",
  initialState,
  reducers: {
    clearProfileError: (state) => {
      state.error = null;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchProfile.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(fetchProfile.fulfilled, (state, action) => {
        state.isLoading = false;
        state.user = action.payload;
      })
      .addCase(fetchProfile.rejected, (state, action) => {
        state.isLoading = false;
        state.error = (action.payload as string) ?? "Something went wrong.";
      })
      .addCase(updateProfile.pending, (state) => {
        state.isUpdating = true;
        state.error = null;
      })
      .addCase(updateProfile.fulfilled, (state, action) => {
        state.isUpdating = false;
        state.user = action.payload;
      })
      .addCase(updateProfile.rejected, (state, action) => {
        state.isUpdating = false;
        state.error = (action.payload as string) ?? "Something went wrong.";
      });
  },
});

export const { clearProfileError } = profileSlice.actions;
export default profileSlice.reducer;
