package com.example.tampopo_client.viewmodels;

import android.util.Log;

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

import com.example.tampopo_client.models.User;
import com.example.tampopo_client.resources.UserResource;

import java.io.IOException;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/*userだけなのでサーバーから情報を取ってくることは名前の変更
viewModelはviewからrequestをもらってmodelに流す
88行目にviewからviewmodelをとる
viewmodelのインスタンスは1個しかなし
128 観測するという宣言をする
observeは2つ引数をもち、一つ目は固定、2つ目は 無名クラスで長い　new observerとあるがこれはインスタンスを作っているわけではないここでしかない使わないローカルなクラス
observerの子クラスである。　observerの無名子クラスと生成するのとインスタンスを作成する　画面の変更をlistenしている

viewModel側　
viewModelからsetValueで値を変えていく
updateUserName、updateEmail、login、createUserもある。それらを書いていく。viewから必要なものを出していく

viewとviewModels
イベントパターン
1.画面を表示するごとに値を取る
2.ボタンを押した際の通信をする
3.画面の途中で更新する

view側がviewModelを使うための方法
1.最初にUserViewModel userViewModelで宣言　88行目 userViewModelのインスタンスを作る

*/

public class UserViewModel extends ViewModel {

    private final Retrofit retrofit;
    private static UserResource userResource;
    private static final MutableLiveData<User> user   = new MutableLiveData<>();
    private final MutableLiveData<String> token  = new MutableLiveData<>();
    private final MutableLiveData<String> icon  = new MutableLiveData<>();
    private final MutableLiveData<Boolean>loading = new MutableLiveData<>(false);
    private static final MutableLiveData<String> error  = new MutableLiveData<>();


    //コンストラクタ
    public UserViewModel(){
        this.retrofit = new Retrofit.Builder()
                .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo/")
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        this.userResource = retrofit.create(UserResource.class);
    }

    public LiveData<User> getUser()   { return user;   }
    public LiveData<String> getToken()  { return token;  }
    public LiveData<String> getIcon()  { return icon;  }
    public LiveData<Boolean>isLoading() { return loading;}
    public static LiveData<String> getError()  { return error;  }

    //新規登録　enqueueで非同期処理、Callbackで成功失敗の処理、LiveDataに反映
    //サーバーから返ってきた型と合わせないとFailureに流れる
    //tokenはログイン処理後に発行されるため削除しました。
    public void createUser(String id, String password) {
        loading.setValue(true);
        userResource.createUser(id, password).enqueue(new Callback<User>() {
            @Override public void onResponse(Call<User> c, Response<User> res) {
                loading.setValue(false);
                if (res.isSuccessful()) {
                    User u = res.body();
                    user.setValue(u);
                } else {
                    error.setValue("登録失敗: " + res.code());
                }
            }
            @Override public void onFailure(Call<User> c, Throwable t) {
                loading.setValue(false);
                error.setValue("エラー: " + t.getMessage());
            }
        });
    }

    //ログイン
    public void login(String id, String password) {
        loading.setValue(true);
        userResource.login(id, password).enqueue(new Callback<String>() {
            @Override public void onResponse(Call<String> c, Response<String> res) {
                loading.setValue(false);
                if (res.isSuccessful()) {
                    userResource.getUser(id);
                    token.setValue(res.body());

                } else {
                    error.setValue("ログイン失敗: " + res.code());
                }
            }
            @Override public void onFailure(Call<String> c, Throwable t) {
                loading.setValue(false);
                error.setValue("エラー: " + t.getMessage());
            }
        });
    }
    //ニックネーム
    public String getNickname(String id) {
        Call<String> call = userResource.getName(id);
        try {
            Response<String> response = call.execute();

            if (response.isSuccessful()) {
                System.out.println(response.code());
                return response.body();
            } else {
                System.out.println(response.code());
                return null;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
//
    }

    //アイコン
    public String getIcon(String id) {
        Call<String> call = userResource.getIcon(id);
        try {
            Response<String> response = call.execute();

            if (response.isSuccessful()) {
                System.out.println(response.code());
                String iconUrl = response.body();
                icon.postValue(iconUrl);
                return iconUrl;
            } else {
                System.out.println(response.code());
                return null;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
//        call.enqueue(new Callback<String>() {
//            @Override
//            public void onResponse(Call<String> call, Response<String> response) {
//                if (response.isSuccessful()) {
//                    icon.setValue(response.body());
//                    System.out.println(response.code());
//                } else {
//                    System.out.println(response.code());
//                }
//            }
//            @Override public void onFailure(Call<String> call, Throwable t) {
//                System.out.println("エラー: " + t.getMessage());
//            }
//        });
    }

    //アイコン（非同期）
    public void getIconAsync(String id) {
        Call<String> call = userResource.getIcon(id);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                if (response.isSuccessful()) {
                    String iconUrl = response.body();
                    icon.postValue(iconUrl);
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Log.e("UserViewModel", "Error");
            }
        });
    }


    public void updateIcon(String id, String newIcon, String token) {
        Call<String> call = userResource.updateIcon(id, newIcon, token);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                if (response.isSuccessful()) {
                    icon.setValue(response.body());
                    System.out.println(response.code());

                } else {
                    System.out.println(response.code());
                }
            }
            @Override public void onFailure(Call<String> call, Throwable t) {
                System.out.println("エラー: " + t.getMessage());
            }
        });
    }

    //ニックネームの変更（市井）
    public void updateName(String userId, String newName, String tokenValue) {
        loading.setValue(true);

        userResource.updateName(userId, newName, tokenValue).enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                loading.setValue(false);
                if (response.isSuccessful()) {
                    // LiveData に更新
                    User currentUser = user.getValue();
                    if (currentUser != null) {
                        currentUser.setName(response.body());
                        user.setValue(currentUser);
                    }
                } else {
                    error.setValue("ニックネーム変更失敗: " + response.code());
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                loading.setValue(false);
                error.setValue("通信エラー: " + t.getMessage());
            }
        });
    }
    //パスワードの変更（市井）
    public void updatePassword(String userId, String newPassword ,String tokenValue) {
        loading.setValue(true);

        userResource.updatePassword(userId, newPassword ,tokenValue).enqueue(new Callback<Void>() {
            @Override
            public void onResponse(Call<Void> call, Response<Void> response) {
                loading.setValue(false);
                if (response.isSuccessful()) {
                    // LiveData に更新
                    User currentUser = user.getValue();
                    if (currentUser != null) {
                        currentUser.setPassword(newPassword);
                        user.setValue(currentUser);
                    }
                } else {
                    error.setValue("パスワード変更失敗: " + response.code());
                }
            }


            @Override
            public void onFailure(Call<Void> call, Throwable t) {
                loading.setValue(false);
                error.setValue("通信エラー: " + t.getMessage());
            }
        });
    }


    //emailの変更（市井）
    public void updateEmail(String userId, String newEmale, String tokenValue) {
        loading.setValue(true);

        userResource.updateEmail(userId, newEmale, tokenValue).enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                loading.setValue(false);
                if (response.isSuccessful()) {
                    // LiveData に更新
                    User currentUser = user.getValue();
                    if (currentUser != null) {
                        currentUser.setEmail(newEmale);
                        user.setValue(currentUser);
                    }
                } else {
                    error.setValue("メールアドレス変更失敗: " + response.code());
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                loading.setValue(false);
                error.setValue("通信エラー: " + t.getMessage());
            }
        });
    }




    //viewModelのところでを呼び出すがフレンド系は西村さんの方で管理する

}
