package com.tapjoy.easyapp;

import static com.tapjoy.easyapp.MainFragment.PREFERENCES;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.Fragment;

import com.unity3d.ads.IUnityAdsInitializationListener;
import com.unity3d.ads.IUnityAdsLoadListener;
import com.unity3d.ads.IUnityAdsShowListener;
import com.unity3d.ads.UnityAds;
import com.unity3d.ads.UnityAdsLoadOptions;
import com.unity3d.ads.UnityAdsShowOptions;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class UnityAdsFragment extends Fragment {

    private TextView outputTextView;
    private TextView versionTextView;
    private Button connectButton;
    private Button requestButton;
    private Button showButton;
    private TextView gameIdTextView;
    private EditText gameIdEditText;
    private EditText adUnitIdEditText;
    private LinearLayout gameIdLayout;
    private SwitchCompat testModeSwitch;
    private SwitchCompat debugModeSwitch;

    private final String GAME_ID_NAME = "gameID";
    private final String AD_UNIT_ID_NAME = "adUnitID";
    private final String TEST_MODE_NAME = "testMode";
    private final String DEBUG_MODE_NAME = "debugMode";
    private SharedPreferences preferences;
    private final Map<String, String> objectIdMap = new HashMap<>();


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.unity_ads, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        preferences = requireActivity().getSharedPreferences(PREFERENCES, 0);
        setupUI(view);
    }

    private void setupUI(View currentView) {
        outputTextView = currentView.findViewById(R.id.textViewOutput);
        connectButton = currentView.findViewById(R.id.buttonConnect);
        requestButton = currentView.findViewById(R.id.buttonRequest);
        showButton = currentView.findViewById(R.id.buttonShow);
        versionTextView = currentView.findViewById(R.id.sdkVersion);
        gameIdLayout = currentView.findViewById(R.id.layoutGameId);
        gameIdEditText = currentView.findViewById(R.id.inputGameId);
        adUnitIdEditText = currentView.findViewById(R.id.inputAdUnitId);
        gameIdTextView = currentView.findViewById(R.id.gameIdText);
        testModeSwitch = currentView.findViewById(R.id.switchTestMode);
        debugModeSwitch = currentView.findViewById(R.id.switchDebugMode);

        gameIdEditText.setText(getGameId());
        adUnitIdEditText.setText(getAdUnitId());
        testModeSwitch.setChecked(getTestMode());
        debugModeSwitch.setChecked(getDebugMode());
        UnityAds.setDebugMode(getDebugMode());

        connectButton.setOnClickListener(view ->
                UnityAds.initialize(requireActivity().getApplicationContext(), getGameId(), getTestMode(), new IUnityAdsInitializationListener() {
                    @Override
                    public void onInitializationComplete() {
                        setStatusMessage(getString(R.string.unity_sdk_connected));
                        connectButton.setVisibility(View.GONE);
                        gameIdLayout.setVisibility(View.GONE);
                        gameIdTextView.setVisibility(View.GONE);
                        testModeSwitch.setEnabled(false);
                    }

                    @Override
                    public void onInitializationFailed(UnityAds.UnityAdsInitializationError error, String message) {
                        setStatusMessage("Unity init failed with error: [" + error + "] " + message);
                    }
                })
        );

        requestButton.setOnClickListener(view -> {
                    String objectId = UUID.randomUUID().toString();
                    objectIdMap.put(getAdUnitId(), objectId);
                    UnityAdsLoadOptions loadOptions = new UnityAdsLoadOptions();
                    loadOptions.setObjectId(objectId);

                    UnityAds.load(getAdUnitId(), loadOptions, new IUnityAdsLoadListener() {
                        @Override
                        public void onUnityAdsAdLoaded(String placementId) {
                            setStatusMessage(getString(R.string.unity_ad_loaded));
                            showButton.setEnabled(true);
                        }

                        @Override
                        public void onUnityAdsFailedToLoad(String placementId, UnityAds.UnityAdsLoadError error, String message) {
                            setStatusMessage("Unity Ads failed to load ad for " + placementId + " with error: [" + error + "] " + message);
                            showButton.setEnabled(false);
                        }
                    });
                }
        );

        showButton.setOnClickListener(view -> {
                    UnityAdsShowOptions unityAdsShowOptions = new UnityAdsShowOptions();
                    unityAdsShowOptions.setObjectId(objectIdMap.get(getAdUnitId()));

                    UnityAds.show(requireActivity(), getAdUnitId(), unityAdsShowOptions, new IUnityAdsShowListener() {
                        @Override
                        public void onUnityAdsShowFailure(String placementId, UnityAds.UnityAdsShowError error, String message) {
                            setStatusMessage("Unity Ads failed to show ad for " + placementId + " with error: [" + error + "] " + message);
                        }

                        @Override
                        public void onUnityAdsShowStart(String placementId) {
                            setStatusMessage("onUnityAdsShowStart: " + placementId);
                        }

                        @Override
                        public void onUnityAdsShowClick(String placementId) {
                            setStatusMessage("onUnityAdsShowClick: " + placementId);
                        }

                        @Override
                        public void onUnityAdsShowComplete(String placementId, UnityAds.UnityAdsShowCompletionState state) {
                            setStatusMessage("onUnityAdsShowComplete: " + placementId);
                        }
                    });
                }
        );

        gameIdEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                cacheGameId(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });

        adUnitIdEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                cacheAdUnitId(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });
        testModeSwitch.setOnCheckedChangeListener((compoundButton, checked) -> cacheTestMode(checked));
        debugModeSwitch.setOnCheckedChangeListener((compoundButton, checked) -> {
                    UnityAds.setDebugMode(checked);
                    cacheDebugMode(checked);
                }
        );
        versionTextView.setText(String.format("SDK Version: %s", UnityAds.getVersion()));
    }

    private String getGameId() {
        return preferences.getString(GAME_ID_NAME, "14851");
    }

    private void cacheGameId(String gameId) {
        if (preferences != null) {
            SharedPreferences.Editor editor = preferences.edit();
            editor.putString(GAME_ID_NAME, gameId);
            editor.apply();
        }
    }

    private String getAdUnitId() {
        return preferences.getString(AD_UNIT_ID_NAME, "video");
    }

    private void cacheAdUnitId(String adUnitId) {
        if (preferences != null) {
            SharedPreferences.Editor editor = preferences.edit();
            editor.putString(AD_UNIT_ID_NAME, adUnitId);
            editor.apply();
        }
    }

    private boolean getTestMode() {
        return preferences.getBoolean(TEST_MODE_NAME, false);
    }

    private void cacheTestMode(Boolean testMode) {
        if (preferences != null) {
            SharedPreferences.Editor editor = preferences.edit();
            editor.putBoolean(TEST_MODE_NAME, testMode);
            editor.apply();
        }
    }

    private boolean getDebugMode() {
        return preferences.getBoolean(DEBUG_MODE_NAME, UnityAds.getDebugMode());
    }

    private void cacheDebugMode(Boolean isDebug) {
        if (preferences != null) {
            SharedPreferences.Editor editor = preferences.edit();
            editor.putBoolean(DEBUG_MODE_NAME, isDebug);
            editor.apply();
        }
    }

    private void setStatusMessage(String errorMessage) {
        outputTextView.setText(errorMessage);
        Log.d("UnityAdsExample", errorMessage);
    }
}
