package com.example.quiz.data.repository;

import android.util.Log;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.example.quiz.data.model.ResponseError;
import com.example.quiz.data.model.dtos.auth.ChangePin;
import com.example.quiz.data.model.dtos.auth.LoginPayload;
import com.example.quiz.data.model.dtos.auth.LoginResponse;
import com.example.quiz.data.model.dtos.auth.User;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.data.remote.TokenManager;
import com.example.quiz.utils.Result;
import com.google.gson.Gson;

import java.io.IOException;

import javax.inject.Inject;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class LoginRepository {
    private ApiService apiService;
    private TokenManager tokenManager;

    @Inject
    public LoginRepository(ApiService apiService, TokenManager tokenManager) {
        this.tokenManager = tokenManager;
        this.apiService = apiService;
    }

    public LiveData<Result<LoginResponse>> login(LoginPayload loginPayload){
        MutableLiveData<Result<LoginResponse>> liveLogin = new MutableLiveData<Result<LoginResponse>>();
        liveLogin.setValue(Result.loading());
        apiService.login(loginPayload).enqueue(new Callback<LoginResponse>() {
            @Override
            public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                if(response.isSuccessful()){
                    liveLogin.postValue(Result.success(response.body()));
                    tokenManager.saveToken(response.body().getToken());
                }else{
                    try {
                        String error = response.errorBody().string();
                        if(!error.startsWith("{")){
                            liveLogin.postValue(Result.error(error));
                            return;
                        }
                        Gson gson = new Gson();
                        ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
                        liveLogin.postValue(Result.error(errorResponse.getMessage()));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }

            @Override
            public void onFailure(Call<LoginResponse> call, Throwable throwable) {
                liveLogin.postValue(Result.error(throwable.toString()));
            }
        });
        return liveLogin;
    }

    public LiveData<Result<User>> changePin(String oldPin, String newPin){
        MutableLiveData<Result<User>> liveUser = new MutableLiveData<Result<User>>();
        liveUser.setValue(Result.loading());
        ChangePin changePin = new ChangePin();
        changePin.setOldPin(oldPin);
        changePin.setNewPin(newPin);
        apiService.changePin(changePin).enqueue(new Callback<User>(){
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                if(response.isSuccessful()) {
                    liveUser.postValue(Result.success(response.body()));
                }else {
                    try {
                        String error = response.errorBody().string();
                        Gson gson = new Gson();
                        ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
                        liveUser.postValue(Result.error(errorResponse.getMessage()));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            @Override
            public void onFailure(Call<User> call, Throwable throwable) {
                liveUser.postValue(Result.error(throwable.getMessage()));
            }
        });
        return liveUser;
    }
}
