package com.example.petstoremobile.repositories;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.example.petstoremobile.api.auth.AuthApi;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.dtos.AuthDTO;
import com.example.petstoremobile.dtos.AvatarUploadResponse;
import com.example.petstoremobile.dtos.UserDTO;
import com.example.petstoremobile.utils.ErrorUtils;
import com.example.petstoremobile.utils.Resource;

import java.util.Map;

import javax.inject.Inject;
import javax.inject.Singleton;

import okhttp3.MultipartBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

@Singleton
public class AuthRepository extends BaseRepository {
    private final AuthApi authApi;
    private final TokenManager tokenManager;

    @Inject
    public AuthRepository(AuthApi authApi, TokenManager tokenManager) {
        super("AuthRepository");
        this.authApi = authApi;
        this.tokenManager = tokenManager;
    }

    /**
     * Authenticates the user and saves login data (token, username, role) upon success.
     */
    public LiveData<Resource<AuthDTO.LoginResponse>> login(AuthDTO.LoginRequest loginRequest) {
        MutableLiveData<Resource<AuthDTO.LoginResponse>> data = new MutableLiveData<>();
        data.setValue(Resource.loading(null));

        authApi.login(loginRequest).enqueue(new Callback<AuthDTO.LoginResponse>() {
            @Override
            public void onResponse(@NonNull Call<AuthDTO.LoginResponse> call, @NonNull Response<AuthDTO.LoginResponse> response) {
                if (response.isSuccessful()) {
                    AuthDTO.LoginResponse result = response.body();
                    if (result != null && result.getToken() != null) {
                        tokenManager.saveLoginData(result.getToken(), result.getUsername(), result.getRole());
                        data.setValue(Resource.success(result));
                    } else {
                        data.setValue(Resource.error("Login failed: Invalid response", null));
                    }
                } else {
                    String errorMsg = ErrorUtils.getErrorMessage(response, "Login failed");
                    data.setValue(Resource.error(errorMsg, null));
                }
            }

            @Override
            public void onFailure(@NonNull Call<AuthDTO.LoginResponse> call, @NonNull Throwable t) {
                data.setValue(Resource.error(ErrorUtils.getFailureMessage(t), null));
            }
        });

        return data;
    }

    /**
     * Retrieves the current user's profile information from the API.
     */
    public LiveData<Resource<UserDTO>> getMe() {
        return executeCall(authApi.getMe());
    }

    /**
     * Updates the current user's profile details.
     */
    public LiveData<Resource<UserDTO>> updateMe(Map<String, String> updates) {
        return executeCall(authApi.updateMe(updates));
    }

    /**
     * Uploads a multipart image to be used as the current user's avatar.
     */
    public LiveData<Resource<AvatarUploadResponse>> uploadAvatar(MultipartBody.Part avatar) {
        return executeCall(authApi.uploadAvatar(avatar));
    }

    /**
     * Sends a request to the API to remove the current user's avatar.
     */
    public LiveData<Resource<Void>> deleteAvatar() {
        return executeCall(authApi.deleteAvatar());
    }

    /**
     * Clears all authentication and login data from storage.
     */
    public void logout() {
        tokenManager.clearLoginData();
    }

    public boolean isLoggedIn() {
        return tokenManager.getToken() != null;
    }
}
