package com.example.quiz.data.repository;

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

import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.ResponseError;
import com.example.quiz.data.model.Restriction;
import com.example.quiz.data.model.dtos.auth.User;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
import com.google.gson.Gson;

import java.io.IOException;
import java.util.List;

import javax.inject.Inject;

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

public class AgentRepository {
    private ApiService apiService;
    @Inject
    public AgentRepository(ApiService apiService) {
        this.apiService = apiService;
    }

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

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

    public LiveData<Result<List<Course.TypeParis>>> getAvailableBets(String agentId) {
        MutableLiveData<Result<List<Course.TypeParis>>> liveAvailableBets = new MutableLiveData<>();
        liveAvailableBets.setValue(Result.loading());
        apiService.getAvailableBets(agentId).enqueue(new Callback<List<Course.TypeParis>>() {
            @Override
            public void onResponse(@NonNull Call<List<Course.TypeParis>> call, @NonNull Response<List<Course.TypeParis>> response) {
                if (response.isSuccessful()) {
                    liveAvailableBets.postValue(Result.success(response.body()));
                } else {
                    try{
                        String error = response.errorBody().string();
                        Gson gson = new Gson();
                        ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
                        liveAvailableBets.postValue(Result.error(errorResponse.getMessage()));
                    }catch (Exception e){
                        liveAvailableBets.postValue(Result.error(e.getMessage()));
                    }
                }
            }
            @Override
            public void onFailure(@NonNull Call<List<Course.TypeParis>> call, @NonNull Throwable throwable) {
                liveAvailableBets.postValue(Result.error(throwable.getMessage()));
            }
        });
        return liveAvailableBets;
    }

    public LiveData<Result<Void>> setAccess(String masterId, String slaveId, boolean access) {
        MutableLiveData<Result<Void>> liveSetAccess = new MutableLiveData<>();
        liveSetAccess.setValue(Result.loading());
        apiService.setAccess(masterId, slaveId, access).enqueue(new Callback<Void>() {
            @Override
            public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
                if (response.isSuccessful()) {
                    liveSetAccess.postValue(Result.success(null));
                } else {
                    try {
                        String error = response.errorBody().string();
                        Gson gson = new Gson();
                        ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
                        liveSetAccess.postValue(Result.error(errorResponse.getMessage()));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            @Override
            public void onFailure(@NonNull Call<Void> call, @NonNull Throwable throwable) {
                liveSetAccess.postValue(Result.error(throwable.getMessage()));
            }
        });
        return liveSetAccess;
    };

    public LiveData<Result<Void>> setRestrictions(String masterId, String slaveId, Restriction restrictions) {
        MutableLiveData<Result<Void>> liveSetRestrictions = new MutableLiveData<>();
        liveSetRestrictions.setValue(Result.loading());
        apiService.setRestrictions(masterId, slaveId, restrictions).enqueue(new Callback<Void>() {
            @Override
            public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
                if (response.isSuccessful()) {
                    liveSetRestrictions.postValue(Result.success(null));
                } else {
                    try {
                        String error = response.errorBody().string();
                        Gson gson = new Gson();
                        ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
                        liveSetRestrictions.postValue(Result.error(errorResponse.getMessage()));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            @Override
            public void onFailure(@NonNull Call<Void> call, @NonNull Throwable throwable) {
                liveSetRestrictions.postValue(Result.error(throwable.getMessage()));
                }
            });
           return liveSetRestrictions;
        }

}
