package com.gh.gamecenter.login.view;

import android.content.Intent;
import android.graphics.drawable.StateListDrawable;
import android.os.Bundle;
import android.os.Message;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.alibaba.android.arouter.launcher.ARouter;
import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.constant.RouteConsts;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.retrofit.ApiResponse;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.core.provider.ILogUtilsProvider;
import com.gh.gamecenter.core.provider.IWebProvider;
import com.gh.gamecenter.core.utils.ClickUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.EmptyCallback;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.PatternUtils;
import com.gh.gamecenter.login.HaloApp;
import com.gh.gamecenter.login.R;
import com.gh.gamecenter.login.databinding.FragmentLoginBinding;
import com.gh.gamecenter.login.entity.LoginTokenEntity;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.login.user.LoginTag;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.login.user.UserViewModel;
import com.gh.gamecenter.login.utils.DialogHelper;
import com.gh.gamecenter.login.utils.LoginHelper;
import com.gh.gamecenter.login.utils.LoginUtils;
import com.gh.gamecenter.login.utils.NewFlatLogUtils;
import com.gh.gamecenter.login.utils.QuickLoginHelper;

import org.greenrobot.eventbus.EventBus;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import kotlin.collections.CollectionsKt;

/**
 * Created by khy on 14/08/17.
 */

public class LoginFragment
        extends ToolbarFragment
        implements LoginUtils.onCaptchaCallBackListener,
        LoginHelper.LoginCallback,
        View.OnClickListener,
        Observer<ApiResponse<UserInfoEntity>> {

    private FragmentLoginBinding mBinding;
    private WaitingDialogFragment mLoginDialog;

    private UserViewModel mUserViewModel;

    private String mServiceId;

    private boolean mIsFromQuickLogin = false;
    private final int THIRD_PARTY_LOGIN_CLICK_DIFF = 3000;

    @Override
    protected void handleMessage(Message msg) {
        if (msg.what == 0) { // 验证码倒计时
            int arg1 = msg.arg1;
            arg1--;
            if (arg1 >= 0) {
                Message message = new Message();
                message.what = 0;
                message.arg1 = arg1;
                mBaseHandler.sendMessageDelayed(message, 1000);
                mBinding.loginCaptcha.setText(arg1 + "s");
            } else {
                mBinding.loginCaptcha.setText("重新获取");
                mBinding.loginCaptcha.setTextColor(ExtensionsKt.toColor(R.color.theme_font));
                mBinding.loginCaptcha.setEnabled(true);
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == com.tencent.connect.common.Constants.REQUEST_LOGIN) { // QQ Login callback
            LoginHelper.onQQLoginCallback(requestCode, resultCode, data);
        } else if (requestCode == 32973) { // WeiBo Login callback
            LoginHelper.onWeiboLoginCallback(requireActivity(), requestCode, resultCode, data);
        }
    }

    @Override
    protected int getLayoutId() {
        return 0;
    }

    @Override
    protected View getInflatedLayout() {
        mBinding = FragmentLoginBinding.inflate(getLayoutInflater());
        return mBinding.getRoot();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments() != null) {
            mIsFromQuickLogin = getArguments().getBoolean(EntranceConsts.KEY_FROM_QUICK_LOGIN, false);
        }

        final UserViewModel.Factory factory = new UserViewModel.Factory(HaloApp.getInstance());
        mUserViewModel = ViewModelProviders.of(this, factory).get(UserViewModel.class);
        mUserViewModel.getLoginObsUserinfo().observe(this, this);

        ArrayList<View> clickableViewList = CollectionsKt.arrayListOf(
                mBinding.loginCaptcha,
                mBinding.loginPhoneBtn,
                mBinding.loginQqBtn,
                mBinding.loginWeiboBtn,
                mBinding.loginWechatBtn,
                mBinding.loginCloseBtn,
                mBinding.normalToolbarContainer.backContainer,
                mBinding.checkIv,
                mBinding.quickLoginTv
        );
        for (View view : clickableViewList) {
            view.setOnClickListener(this);
        }

        initView();
    }

    private void initView() {
        if (mIsFromQuickLogin) {
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mBinding.titleTv.getLayoutParams();
            params.topMargin = DisplayUtils.dip2px(68F);
            mBinding.titleTv.setLayoutParams(params);
            mBinding.normalToolbarContainer.getRoot().setVisibility(View.VISIBLE);
            mBinding.loginBg.setVisibility(View.GONE);
            mBinding.policyContainerLayout.setVisibility(View.GONE);
            mBinding.loginBottom.setVisibility(View.GONE);
            ExtensionsKt.showKeyBoard(mBinding.loginPhoneEt);
        }

        mBinding.loginPassEt.addTextChangedListener(new LoginTextWatcher(mBinding.loginPassEt));
        mBinding.loginPhoneEt.addTextChangedListener(new LoginTextWatcher(mBinding.loginPhoneEt));

        mBinding.loginPrivacyPolicy.setText(getPrivacyContent());
        mBinding.loginPrivacyPolicy.setHighlightColor(getResources().getColor(R.color.transparent));
        mBinding.loginPrivacyPolicy.setMovementMethod(new LinkMovementMethod());

        setCheckIvSrc();
    }

    private void setCheckIvSrc() {
        mBinding.checkIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(requireContext()));
    }

    private SpannableStringBuilder getPrivacyContent() {
        SpannableStringBuilder privacyContent = new SpannableStringBuilder("阅读并同意《用户协议》和《隐私政策》");
        privacyContent.setSpan(new ClickableSpan() {

            @Override
            public void updateDrawState(@NonNull TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(getResources().getColor(R.color.text_subtitle));
                ds.setUnderlineText(true);
            }

            @Override
            public void onClick(@NonNull View widget) {
                MtaHelper.onEvent("我的光环_新", "登录页面", "隐私政策");
                IWebProvider webActivity = (IWebProvider) ARouter.getInstance().build(RouteConsts.provider.webActivity).navigation();
                Intent intent = webActivity.getWebIntent(requireContext(), requireContext().getString(R.string.privacy_policy_title), requireContext().getString(R.string.privacy_policy_url));
                if (intent != null) {
                    startActivity(intent);
                }
            }
        }, privacyContent.length() - 6, privacyContent.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        privacyContent.setSpan(new ClickableSpan() {

            @Override
            public void updateDrawState(@NonNull TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(getResources().getColor(R.color.text_subtitle));
                ds.setUnderlineText(true);
            }

            @Override
            public void onClick(@NonNull View widget) {
                MtaHelper.onEvent("我的光环_新", "登录页面", "用户协议");
                IWebProvider webActivity = (IWebProvider) ARouter.getInstance().build(RouteConsts.provider.webActivity).navigation();
                Intent intent = webActivity.getWebIntent(requireContext(), requireContext().getString(R.string.disclaimer_title), requireContext().getString(R.string.disclaimer_url));
                if (intent != null) {
                    startActivity(intent);
                }
            }
        }, privacyContent.length() - 13, privacyContent.length() - 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return privacyContent;
    }

    public void onClick(View v) {
        super.onClick(v);
        int id = v.getId();
        if (id == R.id.checkIv) {
            mBinding.checkIv.setChecked(!mBinding.checkIv.isChecked());
        } else if (id == R.id.login_captcha) {
            MtaHelper.onEvent("我的光环_新", "登录页面", "获取验证码");
            final String phoneNum = mBinding.loginPhoneEt.getText().toString().trim().replaceAll(" ", "");
            if (PatternUtils.isPhoneNum(phoneNum) && phoneNum.length() == 11) {
                checkPolicyAndContinue(() -> {
                    mBinding.loginCaptcha.setEnabled(false);
                    ExtensionsKt.showKeyBoard(mBinding.loginPassEt);
                    LoginUtils.getPhoneCaptcha(requireContext(), phoneNum, LoginFragment.this);
                });
            } else {
                toast("请输入正确的手机号");
            }
        } else if (id == R.id.login_phone_btn) {
            MtaHelper.onEvent("我的光环_新", "登录页面", "点击登录");
            loginByMobile();
        } else if (id == R.id.login_qq_btn) {
            if (!ClickUtils.isFastDoubleClick(id, THIRD_PARTY_LOGIN_CLICK_DIFF)) {
                checkPolicyAndContinue(() -> {
                    MtaHelper.onEvent("我的光环_新", "登录页面", "QQ登录");
                    LoginHelper.loginWithQQ(this, requireActivity());
                });
            }
        } else if (id == R.id.login_weibo_btn) {
            if (!ClickUtils.isFastDoubleClick(id, THIRD_PARTY_LOGIN_CLICK_DIFF)) {
                checkPolicyAndContinue(() -> {
                    MtaHelper.onEvent("我的光环_新", "登录页面", "微博登录");
                    LoginHelper.loginWithWeibo(this, requireActivity());
                });
            }
        } else if (id == R.id.login_wechat_btn) {
            if (!ClickUtils.isFastDoubleClick(id, THIRD_PARTY_LOGIN_CLICK_DIFF)) {
                checkPolicyAndContinue(() -> {
                    MtaHelper.onEvent("我的光环_新", "登录页面", "微信登录");
                    LoginHelper.loginWithWechat(this);
                });
            }
        } else if (id == R.id.login_close_btn || id == R.id.backContainer) {
            requireActivity().finish();
        }
    }

    private void checkPolicyAndContinue(EmptyCallback callback) {
        if (mBinding.checkIv.isChecked() || mIsFromQuickLogin) {
            callback.onCallback();
        } else {
            DialogHelper.showLoginPolicyDialog(
                    requireContext(),
                    requireContext(),
                    false,
                    "",
                    () -> {
                        mBinding.checkIv.setChecked(true);
                        callback.onCallback();
                    }
            );
            NewFlatLogUtils.INSTANCE.logFastLoginRelatedShow("login_privacy_policy_pop_show");
        }
    }

    // 登录
    private void loginByMobile() {
        String code = mBinding.loginPassEt.getText().toString().trim();
        String phoneNum = mBinding.loginPhoneEt.getText().toString().trim().replaceAll(" ", "");

        if (TextUtils.isEmpty(phoneNum)) {
            toast("手机号码不能为空");
            return;
        }

        checkPolicyAndContinue(() -> {
            if (TextUtils.isEmpty(code)) {
                toast("验证码不能为空");
                return;
            } else if (TextUtils.isEmpty(mServiceId)) {
                toast("验证码错误，请重新获取");
                return;
            }

            Map<String, String> params = new HashMap<>();
            params.put("mobile", phoneNum);
            params.put("code", code);
            params.put("service_id", mServiceId);

            login(new JSONObject(params), LoginTag.phone);

            String loginSource = getLoginSource();
            if (loginSource != null) {
                NewFlatLogUtils.INSTANCE.logMobileNumberClick(loginSource);
            }
        });
    }

    public String getLoginSource() {
        if (mIsFromQuickLogin) {
            return "一键登录";
        }
        if (mEntrance.contains("立即登录")) {
            return "立即登录";
        }
        if (mEntrance.contains("我的光环")) {
            return "我的光环相关功能按钮";
        }
        if (mEntrance.contains("论坛首页-发布") || mEntrance.contains("论坛详情-发布")) {
            return "社区内容发布按钮";
        }
        if ((mEntrance.contains("社区") || mEntrance.contains("论坛") || mEntrance.contains("帖子") || mEntrance.contains("视频详情"))
                && (mEntrance.contains("点赞") || mEntrance.contains("赞同"))) {
            return "社区Tab点赞功能";
        }
        if ((mEntrance.contains("游戏详情") || mEntrance.contains("安利墙") && mEntrance.contains("点赞"))) {
            return "游戏评价点赞功能";
        }
        if (mEntrance.contains("视频流详情-点赞")) {
            return "视频Tab点赞功能";
        }
        if ((mEntrance.contains("文章详情") || mEntrance.contains("问题详情") || mEntrance.contains("视频详情"))
                && (mEntrance.contains("评论") || mEntrance.contains("回复"))) {
            return "社区内容评论/回复";
        }
        if (mEntrance.contains("视频流")
                && (mEntrance.contains("评论") || mEntrance.contains("回复"))) {
            return "视频流评论/回复";
        }
        if (mEntrance.contains("游戏详情")
                && (mEntrance.contains("我来评论") || mEntrance.contains("我要安利") || mEntrance.contains("评论详情-评论") || mEntrance.contains("评论详情-回复"))) {
            return "游戏评价/回复";
        }
        return null;
    }

    @Override
    public void onCaptcha(String serviceId) {
        if (!TextUtils.isEmpty(serviceId)) {
            mServiceId = serviceId;

            // 启动验证码倒计时
            Message message = new Message();
            message.what = 0;
            message.arg1 = 60; // 倒数时间
            mBaseHandler.sendMessage(message);
            mBinding.loginCaptcha.setTextColor(ExtensionsKt.toColor(R.color.hint));
            mBinding.loginCaptcha.setEnabled(false);
        } else {
            mBinding.loginCaptcha.setEnabled(true);
        }
    }

    @Override
    public void onLoginSuccess(@NotNull LoginTag loginType, @NotNull JSONObject jsonContent) {
        login(jsonContent, loginType);
    }

    @Override
    public void onLoginFailure(@NotNull LoginTag loginType, @NotNull String error) {
        toast(error);
    }

    @Override
    public void onChanged(@Nullable ApiResponse<UserInfoEntity> response) {
        if (mLoginDialog != null) {
            mLoginDialog.dismissAllowingStateLoss();
            mLoginDialog = null;
        }

        if (response != null && response.getData() != null) {
            LoginTokenEntity loginTokenEntity = UserManager.getInstance().getLoginTokenEntity();
            if (loginTokenEntity != null) {

                String loginType = loginTokenEntity.getLoginType();
                ILogUtilsProvider logUtils = (ILogUtilsProvider) ARouter.getInstance().build(RouteConsts.provider.logUtils).navigation();
                if (LoginTag.qq.name().equals(loginType)
                        || LoginTag.wechat.name().equals(loginType)
                        || LoginTag.weibo.name().equals(loginType)
                        || LoginTag.douyin.name().equals(loginType)
                        || LoginTag.oauth.name().equals(loginType)) {
                    logUtils.login("success", loginType, mEntrance);
                } else {
                    logUtils.login("success", "mobile", mEntrance);
                }

                // 第三方登录方式登录后跳转绑定手机页面（https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1206）
                boolean isThirdPartyLogin = LoginTag.qq.name().equals(loginType)
                        || LoginTag.wechat.name().equals(loginType)
                        || LoginTag.weibo.name().equals(loginType)
                        || LoginTag.douyin.name().equals(loginType);
                if (isThirdPartyLogin
                        && TextUtils.isEmpty(response.getData().getLoginMobile())) {
                    ARouter.getInstance().build(RouteConsts.activity.bindPhoneActivity)
                            .withBoolean(EntranceConsts.KEY_FROM_LOGIN, true)
                            .withBoolean(EntranceConsts.KEY_CHANGE_PHONE, false)
                            .navigation();
                }
            }
            // 防止UserManager数据丢失后重复登录
            if (TextUtils.isEmpty(UserManager.getInstance().getToken())) {
                mUserViewModel.retryCheckLogin();
            }

            /*Object videoLinkEntity = HaloApp.get(HOST_UPLOAD_VIDEO, true);
            if (videoLinkEntity instanceof VideoLinkEntity) {
                startActivity(VideoManagerActivity.getIntent(
                        requireContext(),
                        (VideoLinkEntity) videoLinkEntity,
                        EntranceUtils.ENTRANCE_BROWSER, ""));
            }*/

            if (getActivity() != null && UserManager.getInstance().isLoggedIn()) {
                getActivity().finish();
                // 如果是从一键登录页跳转过来的，登录成功后也要finish一键登录页
                if (mIsFromQuickLogin) {
                    QuickLoginHelper.finishAuthActivity();
                }
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mBaseHandler.removeCallbacksAndMessages(null);
        if (!UserManager.getInstance().isLoggedIn()) {
            EventBus.getDefault().post(new EBReuse(Constants.EB_QUIT_LOGIN));
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LoginHelper.unregisterCallback();
    }

    private void login(JSONObject content, LoginTag loginTag) {
        ILogUtilsProvider logUtils = (ILogUtilsProvider) ARouter.getInstance().build(RouteConsts.provider.logUtils).navigation();
        if (loginTag.equals(LoginTag.phone)) {
            logUtils.login("logging", "mobile", mEntrance);
        } else {
            logUtils.login("logging", loginTag.name(), mEntrance);
        }
        if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
            mLoginDialog = WaitingDialogFragment.newInstance(getString(R.string.logging));
            mLoginDialog.show(getChildFragmentManager(), null);
        }
        mUserViewModel.login(content, loginTag);
    }

    @Override
    protected void onDarkModeChanged() {
        super.onDarkModeChanged();
        if (mIsFromQuickLogin) {
            mBinding.normalToolbarContainer.normalToolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.background_white));
            mBinding.normalToolbarContainer.backBtn.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_bar_back));
        }
        setCheckIvSrc();
    }

    private class LoginTextWatcher implements TextWatcher {
        private final EditText mEditText;

        public LoginTextWatcher(EditText e) {
            mEditText = e;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            int tvCount = s.length();
            if (mEditText == mBinding.loginPhoneEt) {
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < s.length(); i++) {
                    if (i != 3 && i != 8 && s.charAt(i) == ' ') {
                        continue;
                    } else {
                        stringBuilder.append(s.charAt(i));
                        if ((stringBuilder.length() == 4 || stringBuilder.length() == 9)
                                && stringBuilder.charAt(stringBuilder.length() - 1) != ' ') {
                            stringBuilder.insert(stringBuilder.length() - 1, ' ');
                        }
                    }
                }

                if (!stringBuilder.toString().equals(s.toString())) {
                    mBinding.loginPhoneEt.setText(stringBuilder.toString());
                    mBinding.loginPhoneEt.setSelection(mBinding.loginPhoneEt.getText().toString().length());
                }
            }

            if (mEditText == mBinding.loginPassEt) {
                if (tvCount > 5) {
                    mBinding.loginPhoneBtn.setEnabled(true);
                    mBinding.loginPhoneBtn.setAlpha(1f);
                } else {
                    mBinding.loginPhoneBtn.setEnabled(false);
                    mBinding.loginPhoneBtn.setAlpha(0.4f);
                }
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
            // Do nothing
        }
    }
}
