package co.pixelbeard.theanfieldwrap.settings;


import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import co.pixelbeard.theanfieldwrap.BuildConfig;
import co.pixelbeard.theanfieldwrap.R;
import co.pixelbeard.theanfieldwrap.data.NotificationSetting;
import co.pixelbeard.theanfieldwrap.data.source.DataRepository;
import co.pixelbeard.theanfieldwrap.data.source.local.LocalRepository;
import co.pixelbeard.theanfieldwrap.data.source.remote.RemoteRepository;
import co.pixelbeard.theanfieldwrap.dialog.twoButton.TwoButtonDialogListener;
import co.pixelbeard.theanfieldwrap.home.HomeFragmentListener;
import co.pixelbeard.theanfieldwrap.playerService.MediaPlayerInterface;
import co.pixelbeard.theanfieldwrap.playerService.PodcastStorageUtil;
import co.pixelbeard.theanfieldwrap.utils.BaseFragment;
import co.pixelbeard.theanfieldwrap.utils.ConnectionUtils;
import co.pixelbeard.theanfieldwrap.utils.DialogUtils;
import co.pixelbeard.theanfieldwrap.utils.FontUtils;
import co.pixelbeard.theanfieldwrap.utils.TawController;
import io.realm.Realm;

public class SettingsFragment extends BaseFragment implements SettingsContract.View {

    private static final String TAG = SettingsFragment.class.getSimpleName();

    @BindView(R.id.ll_back)
    LinearLayout llBack;
    @BindView(R.id.txt_settings_title)
    TextView txtSettingsTitle;

    @BindView(R.id.txt_notifications_title)
    TextView txtNotificationsTitle;

    @BindView(R.id.txt_review_app)
    TextView txtReviewApp;
    @BindView(R.id.txt_contact_us)
    TextView txtContactUs;
    @BindView(R.id.txt_terms)
    TextView txtTerms;
    @BindView(R.id.txt_privacy_policy)
    TextView txtPrivacyPolicy;
    @BindView(R.id.txt_logout)
    TextView txtLogout;

    @BindView(R.id.ll_review_app)
    LinearLayout llReviewApp;
    @BindView(R.id.ll_contact_us)
    LinearLayout llContactUs;
    @BindView(R.id.ll_terms)
    LinearLayout llTerms;
    @BindView(R.id.ll_privacy_policy)
    LinearLayout llPrivacyPolicy;
    @BindView(R.id.ll_logout)
    LinearLayout llLogout;

    @BindView(R.id.rv_notification_settings)
    RecyclerView rvNotificationSettings;

    @BindView(R.id.txt_version_num)
    TextView txtVersionNum;

    @BindView(R.id.progressBar)
    ProgressBar progressBar;

    @BindView(R.id.ll_subscription_app)
    LinearLayout llSubscriptionApp;

    private Context mContext;
    private HomeFragmentListener mListener;
    private MediaPlayerInterface mediaPlayerInterface;

    private SettingsContract.Presenter mPresenter;

    private NotificationSettingsAdapter mAdapter;

    private ConnectivityManager cm;
    private ConnectivityManager.NetworkCallback networkCallback;
    private boolean fromLocal;

    public SettingsFragment() {
        // Required empty public constructor
    }

    public static SettingsFragment newInstance() {
        SettingsFragment fragment = new SettingsFragment();
        Bundle args = new Bundle();

        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        mContext = context;
        mListener = (HomeFragmentListener) context;
        mediaPlayerInterface = (MediaPlayerInterface) context;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {

        }

        new SettingsPresenter(this, new DataRepository(new LocalRepository(Realm.getDefaultInstance()), new RemoteRepository()));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_settings, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        setTextViewFont();
        setClickListeners();

        setRecyclerViewLayoutManager();

        if (mAdapter == null) {
            mPresenter.subscribe();
        } else {
            rvNotificationSettings.setAdapter(mAdapter);
        }

        txtVersionNum.setText(String.format(getString(R.string.version), BuildConfig.VERSION_NAME));
    }

    @Override
    public void onStart() {
        super.onStart();


        if (mContext != null) {
            cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        }

        NetworkRequest networkRequest = new NetworkRequest.Builder().build();
        networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                super.onAvailable(network);
                checkForSettings();
            }

            @Override
            public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
                super.onLinkPropertiesChanged(network, linkProperties);
                checkForSettings();
            }

            @Override
            public void onLost(Network network) {
                super.onLost(network);
                checkForSettings();
            }

            @Override
            public void onCapabilitiesChanged(Network network, NetworkCapabilities
                    networkCapabilities) {
                super.onCapabilitiesChanged(network, networkCapabilities);
                checkForSettings();
            }

            @Override
            public void onUnavailable() {
                super.onUnavailable();
                checkForSettings();
            }

            @Override
            public void onLosing(Network network, int maxMsToLive) {
                super.onLosing(network, maxMsToLive);
                checkForSettings();
            }
        };

        if (cm != null) {
            cm.registerNetworkCallback(networkRequest, networkCallback);
        }
    }


    @Override
    public void onStop() {
        super.onStop();
        try {
            cm.unregisterNetworkCallback(networkCallback);
        } catch (Exception e) {
            Log.d("NETWORK CALLBACK", "NetworkCallback for Wi-fi was not registered or already unregistered");
        }

    }

    @Override
    public void onResume() {
        super.onResume();
        TawController.setCurrentPage(TAG);
    }

    private void checkForSettings() {
        if (checkConnection() && !fromLocal) {
            enableSettings();
        } else {
            disableSettings();
        }
    }

    private void setTextViewFont() {

        txtSettingsTitle.setTypeface(FontUtils.getInstance().getDinProBlack());
        txtNotificationsTitle.setTypeface(FontUtils.getInstance().getDinProBlack());

        txtReviewApp.setTypeface(FontUtils.getInstance().getDinAlternateBold());
        txtContactUs.setTypeface(FontUtils.getInstance().getDinAlternateBold());
        txtTerms.setTypeface(FontUtils.getInstance().getDinAlternateBold());
        txtPrivacyPolicy.setTypeface(FontUtils.getInstance().getDinAlternateBold());
        txtLogout.setTypeface(FontUtils.getInstance().getDinAlternateBold());

        txtVersionNum.setTypeface(FontUtils.getInstance().getDinProBlack());
    }

    private void setClickListeners() {
        llBack.setOnClickListener(v -> mListener.goBack());

        llReviewApp.setOnClickListener(v -> {
            try {
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=co.pixelbeard.theanfieldwrap")));
            } catch (Exception e) {
                e.printStackTrace();
                String url = "https://play.google.com/store/apps/details?id=co.pixelbeard.theanfieldwrap";
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                startActivity(i);
            }

        });

        llContactUs.setOnClickListener(v -> {
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("plain/text");
            intent.putExtra(Intent.EXTRA_EMAIL, new String[]{getString(R.string.email_contact_us)});
            intent.putExtra(Intent.EXTRA_SUBJECT, "The Anfield Wrap - App Enquiry");
            startActivity(Intent.createChooser(intent, "Email The Anfield Wrap"));
        });

        llTerms.setOnClickListener(v -> {
            mListener.startTermsActivity();
        });

        llPrivacyPolicy.setOnClickListener(v -> {
            mListener.startPrivacyPolicyActivity();
        });

        llLogout.setOnClickListener(v -> {
            DialogUtils.showTwoButtonDialog(getString(R.string.are_you_sure), getString(R.string.are_you_sure_logout), mContext, new TwoButtonDialogListener() {
                @Override
                public void onYesClicked() {
                    logoutUser();

                }

                @Override
                public void onNoClicked() {
                }
            });
        });
        llSubscriptionApp.setOnClickListener(v -> {
            try {
                String playStoreSubscriptionLink = "https://play.google.com/store/account/subscriptions?package="+getActivity().getPackageName();
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(playStoreSubscriptionLink)));
            } catch (ActivityNotFoundException exception) {
            }
        });
    }

    private void setRecyclerViewLayoutManager() {
        rvNotificationSettings.setLayoutManager(new LinearLayoutManager(mContext, RecyclerView.VERTICAL, false));
    }

    @Override
    public void setNotificationSettingsAdapter(List<NotificationSetting> settings, boolean fromLocal) {
        this.fromLocal = fromLocal;
        mAdapter = new NotificationSettingsAdapter(settings, setting -> {
            mPresenter.updateUserSetting(setting.getKey(), setting.getValue());
        });
        rvNotificationSettings.setAdapter(mAdapter);
    }

    @Override
    public void disableSettings() {
        if (mAdapter != null && isAdded()) {
            mAdapter.disableSettings();
            rvNotificationSettings.setAlpha(0.4f);
        }
    }

    @Override
    public void enableSettings() {
        if (mAdapter != null && isAdded()) {
            mAdapter.enableSettings();
            rvNotificationSettings.setAlpha(1f);
        }
    }

    @Override
    public void showSingleButtonDialog(String error, String message) {
        if (mListener != null)
            mListener.showSingleButtonDialog(error, message, null);
    }

    @Override
    public void setPresenter(SettingsContract.Presenter presenter) {
        if (presenter != null) {
            this.mPresenter = presenter;
        } else {
            throw new RuntimeException("Presenter is null");
        }
    }

    @Override
    public void goBack() {
        if (mListener != null && isAdded()) {
            mListener.goBack();
        }
    }

    @Override
    public void showLoader(String text) {
        if (mListener != null && isAdded()) {

            progressBar.setVisibility(View.VISIBLE);


//            mListener.showLoader("");
        }
    }

    @Override
    public void hideLoader() {
        new Handler().postDelayed(() -> {
            if (mListener != null && isAdded()) {
//                mListener.hideLoader();
                progressBar.setVisibility(View.GONE);
            }
        }, 1000);

    }

    @Override
    public void onUnknownError(String error) {
        if (mListener != null && isAdded()) {
            mListener.showSingleButtonDialog(getString(R.string.error), error, null);
        }
    }

    @Override
    public void onTimeout() {
        if (mListener != null && isAdded()) {
            mListener.showSingleButtonDialog(getString(R.string.timeout_title), getString(R.string.timeout_body), null);
        }
    }

    @Override
    public void onNetworkError() {
        if (mListener != null && isAdded()) {
            mListener.showSingleButtonDialog(getString(R.string.network_error_title), getString(R.string.network_error_body), null);
        }
    }

    @Override
    public void onConnectionError() {
        if (mListener != null && isAdded()) {
            mListener.showNoInternetHeader();
        }
    }

    @Override
    public void logoutUser() {
        mPresenter.clearUserData(mContext);
        if (mediaPlayerInterface.isPlaying()) {
            mediaPlayerInterface.stop();
        }
        PodcastStorageUtil.getInstance().clearStoredPodcast();
        mListener.startWalkThroughActivity();
    }

    @Override
    public boolean checkConnection() {
        return ConnectionUtils.userHasConnection(mContext);
    }
}