package com.gh.gamecenter.message;

import static com.gh.gamecenter.common.constant.Constants.LOGIN_TAG;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.gh.common.constant.Config;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.ErrorHelper;
import com.gh.common.util.PostCommentUtils;
import com.gh.gamecenter.MessageDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.MessageDetailAdapter;
import com.gh.gamecenter.adapter.OnCommentCallBackListener;
import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.retrofit.OkHttpCache;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.TextHelper;
import com.gh.gamecenter.common.utils.TimestampUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.KeyboardHeightObserver;
import com.gh.gamecenter.core.utils.KeyboardHeightProvider;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.databinding.FragmentMessageDetailBinding;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.CommentnumEntity;
import com.gh.gamecenter.entity.ConcernEntity;
import com.gh.gamecenter.entity.ViewsEntity;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.manager.CommentManager;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.halo.assistant.HaloApp;
import com.lightgame.listeners.OnBackPressedListener;
import com.lightgame.utils.Util_System_Keyboard;
import com.lightgame.utils.Utils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;

/**
 * Created by CsHeng on 18/12/2017.
 * 消息详情界面--评论详情--对话详情
 */
public class MessageDetailFragment extends ToolbarFragment implements OnCommentCallBackListener, OnBackPressedListener, KeyboardHeightObserver {

    public static final int REQUEST_UPDATE_COMMENT = 9; // 刷新文章web页面评论数

    private FragmentMessageDetailBinding mBinding;

    private LinearLayoutManager mLayoutManager;

    private MessageDetailAdapter adapter;

    private Dialog mSendingDialog;

    private ConcernEntity mConcernEntity;
    private CommentEntity mCommentEntity; // 回复评论的实体 用完马上清空

    private UserInfoEntity mUserInfo;

    private String newsId;

    private int commentNum = -1; //区分来源 -1：资讯关注列表 !=-1 :新闻详情

    private KeyboardHeightProvider mKeyboardHeightProvider = null;
    private int mOffset = 0;

    private TextWatcher watcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.toString().trim().length() > 0) {
                mBinding.pieceCommentTypingContainer.answerCommentSendBtn.setEnabled(true);
            } else {
                mBinding.pieceCommentTypingContainer.answerCommentSendBtn.setEnabled(false);
            }
        }

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

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(CommentEntity.TAG, adapter.getConcernEntity());
    }

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

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

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

        Bundle args = getArguments();
//        mConcernEntity = args.getParcelable(ConcernEntity.TAG);
        mConcernEntity = (ConcernEntity) HaloApp.get(ConcernEntity.TAG, true);
        mCommentEntity = args.getParcelable(CommentEntity.TAG);

        newsId = args.getString(EntranceConsts.KEY_NEWSID);
        commentNum = args.getInt("commentNum", -1);

        //复用问题 mConcernEntity对应的文章有可能和跳转之前的文章不一致
        if (mConcernEntity != null && newsId != null && !newsId.equals(mConcernEntity.getId())) {
            mConcernEntity = null;
        }

        setNavigationTitle(getString(R.string.title_message_detail));

        adapter = new MessageDetailAdapter(getActivity(), this, mBinding.messageDetailRv, mConcernEntity, mEntrance);
        mLayoutManager = new LinearLayoutManager(getContext());
        mBinding.messageDetailRv.setLayoutManager(mLayoutManager);
        mBinding.messageDetailRv.setAdapter(adapter);

        mBinding.pieceCommentTypingContainer.answerCommentEt.addTextChangedListener(watcher);
        mBinding.pieceCommentTypingContainer.answerCommentEt.setFilters(new InputFilter[]{TextHelper.getFilter(140, "评论不能多于140字")});
        mBinding.pieceCommentTypingContainer.answerCommentSendBtn.setEnabled(false);
        mKeyboardHeightProvider = new KeyboardHeightProvider(requireActivity());
        mBinding.messageDetailRv.post(mKeyboardHeightProvider::start);
        mBinding.pieceCommentTypingContainer.answerCommentEt.setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus) {
                mBinding.pieceCommentTypingContainer.answerCommentEt.setHintTextColor(ContextCompat.getColor(getContext(), R.color.hint));
            } else {
                mBinding.pieceCommentTypingContainer.answerCommentEt.setHintTextColor(ContextCompat.getColor(getContext(), R.color.theme_font));
            }
        });

        mBinding.messageDetailRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if (newState == RecyclerView.SCROLL_STATE_IDLE
                        && !adapter.isOver() && !adapter.isLoading() && mConcernEntity != null
                        && mLayoutManager.findLastVisibleItemPosition() == adapter.getItemCount() - 1) {
                    int offset = adapter.getItemCount() - adapter.getHotCommentListSize() - 3;
                    if (offset >= 10) { // 防止自动上滑时触发
                        adapter.addNormalComment();
                    }
                }
            }
        });

        mUserInfo = UserManager.getInstance().getUserInfoEntity();

        if (newsId != null && mConcernEntity == null) {
            getConcernDigest();
        }

        if (args.getBoolean("openSoftInput", false)) {//新闻详情的发表评论
            setSoftInput(true);
        }

        mBinding.reuseNoConnection.getRoot().setOnClickListener(v -> {
            if (newsId != null && mConcernEntity == null) {
                showNoConnection(false);
            }
        });
        mBinding.pieceCommentTypingContainer.answerCommentSendBtn.setOnClickListener(this);
        mBinding.shadowView.setOnClickListener(this);
    }

    public void getCommentNum() {
        RetrofitManager.getInstance().getApi()
                .getNewsCommentnum(newsId, Utils.getTime(getContext()))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<List<CommentnumEntity>>() {

                    @Override
                    public void onResponse(List<CommentnumEntity> response) {
                        super.onResponse(response);
                        if (response.size() > 0) {
                            if (!TextUtils.isEmpty(mConcernEntity.getId())) {
                                commentNum = response.get(0).getNum();
                                mConcernEntity.setCommentnum(commentNum);
                                adapter.notifyItemChanged(0);
                            }
                        }
                    }
                });
    }

    private void getConcernDigest() {
        RetrofitManager.getInstance().getApi().getNewsRichDigest(newsId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<ConcernEntity>() {
                    @Override
                    public void onResponse(ConcernEntity response) {
                        mConcernEntity = response;
                        if (commentNum == -1) {
                            getCommentNum();
                        } else {
                            mConcernEntity.setCommentnum(commentNum);
                        }

                        adapter.addConcernEntity(mConcernEntity);
                        adapter.notifyDataSetChanged();
                        adapter.addHotComment();
                        getNewsViews();

                        if (commentNum == 0) {
                            setSoftInput(true);
                        }
                    }

                    @Override
                    public void onFailure(HttpException e) {
                        showNoConnection(true);
                    }
                });
    }

    private void getNewsViews() {
        RetrofitManager.getInstance().getApi()
                .getArticlesVisits(UrlFilterUtils.getFilterQuery("article_ids", newsId))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<List<ViewsEntity>>() {
                    @Override
                    public void onResponse(List<ViewsEntity> viewsEntities) {
                        if (viewsEntities.size() > 0) {
                            mConcernEntity.setViews(viewsEntities.get(0).getViews());
                            adapter.notifyItemChanged(0);
                        }
                    }
                });
    }

    //软键盘控制
    private void setSoftInput(boolean isShow) {
        if (isShow) {
            String entrance = "资讯文章详情-评论详情-回复";
            if (mCommentEntity == null) {
                entrance = "资讯文章详情-评论详情-评论数";
            }
            CheckLoginUtils.checkLogin(getContext(), entrance, () -> {
                Util_System_Keyboard.showSoftKeyboard(getContext(), mBinding.pieceCommentTypingContainer.answerCommentEt);
                mBinding.pieceCommentTypingContainer.answerCommentEt.setFocusable(true);
                mBinding.pieceCommentTypingContainer.answerCommentEt.setFocusableInTouchMode(true);
                mBinding.pieceCommentTypingContainer.answerCommentEt.requestFocus();

                if (mCommentEntity != null && mCommentEntity.getUser() != null) {
                    mBinding.pieceCommentTypingContainer.answerCommentEt.setHint(getString(R.string.comment_repty_hint, mCommentEntity.getUser().getName()));
                } else {
                    mBinding.pieceCommentTypingContainer.answerCommentEt.setHint(getString(R.string.message_detail_comment_hint));
                }
            });
        } else {
            Util_System_Keyboard.hideSoftKeyboard(getActivity());

            if (mCommentEntity != null) {
                mCommentEntity = null; // 清空当前评论实体
                mBinding.pieceCommentTypingContainer.answerCommentEt.setHint(getString(R.string.message_detail_comment_hint));
                mBinding.pieceCommentTypingContainer.answerCommentEt.setText("");
            }
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.answer_comment_send_btn:
                final String content = mBinding.pieceCommentTypingContainer.answerCommentEt.getText().toString();

                if (content.length() == 0) {
                    Utils.toast(getContext(), "评论内容不能为空！");
                    return;
                }

                CheckLoginUtils.checkLogin(requireContext(), "资讯文章详情-评论详情-写评论", () -> {
                    mSendingDialog = DialogUtils.showWaitDialog(getActivity(), getString(R.string.post_dialog_hint));

                    JSONObject jsonObject = new JSONObject();
                    try {
                        jsonObject.put("content", content);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    if (newsId == null && mConcernEntity == null || newsId == null && mConcernEntity.getId() == null) {
                        Utils.toast(getContext(), "评论异常 id null");
                        mSendingDialog.cancel();
                        return;
                    } else if (newsId == null) {
                        newsId = mConcernEntity.getId();
                    }

                    PostCommentUtils.addCommentData(getContext(), newsId, jsonObject, mCommentEntity, new PostCommentUtils.PostCommentListener() {
                        @Override
                        public void postSuccess(JSONObject response) {
                            mSendingDialog.dismiss();
                            toast("发表成功");
                            mBinding.pieceCommentTypingContainer.answerCommentEt.setText("");

                            try {
                                JSONObject cacheObject = new JSONObject();
                                JSONObject cacheUser = new JSONObject();
                                JSONObject userData = new JSONObject();
                                JSONObject badgeData = new JSONObject();
                                cacheUser.put("_id", mUserInfo.getUserId());
                                cacheUser.put("icon", mUserInfo.getIcon());
                                cacheUser.put("name", mUserInfo.getName());

                                if (mUserInfo.getBadge() != null) {
                                    badgeData.put("name", mUserInfo.getBadge().getName());
                                    badgeData.put("icon", mUserInfo.getBadge().getIcon());
                                    cacheUser.put("badge", badgeData);
                                }

                                userData.put("is_comment_own", true);
                                cacheObject.put("_id", response.getString("_id"));
                                cacheObject.put("content", content);
                                cacheObject.put("time", System.currentTimeMillis() / 1000);
                                cacheObject.put("vote", 0);
                                cacheObject.put("user", cacheUser);
                                cacheObject.put("me", userData);

                                if (mCommentEntity != null) {
                                    JSONObject cacheParent = new JSONObject();
                                    cacheParent.put("user", new JSONObject(GsonUtils.toJson(mCommentEntity.getUser())));
                                    cacheParent.put("comment", mCommentEntity.getContent());
                                    cacheObject.put("parent", cacheParent);
                                }

                                adapter.addNormalComment(true);

                                modifyNewsCommentOkhttpCache(adapter.findTheLastPriorComment(), cacheObject, newsId);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            if (mConcernEntity != null) {
                                // 完成评论操作,添加评论数
                                adapter.addCommentCount();
                                //修改评论缓存
                                CommentManager.updateOkhttpCacheForId(getContext(), newsId);
                                CommentManager.updateOkhttpCache(getContext(), newsId);
                                adapter.notifyItemInserted(adapter.getHotCommentListSize() + 2);
                                adapter.notifyItemChanged(adapter.getItemCount() - 1); //刷新脚布局高度
                            } else {
                                showNoConnection(false);
                            }

                            setSoftInput(false);

                        }

                        @Override
                        public void postFailed(Throwable e) {
                            mSendingDialog.dismiss();
                            String errorString = null;
                            if (e instanceof HttpException) {
                                try {
                                    errorString = ((HttpException) e).response().errorBody().string();
                                } catch (Exception e1) {
                                    e1.printStackTrace();
                                }
                            }
                            ErrorHelper.handleError(requireContext(), errorString, false, mBinding.pieceCommentTypingContainer.answerCommentSendBtn::performClick, "文章及帖子的评论和回复");
                        }
                    });
                });
                break;
            case R.id.shadowView:
                Util_System_Keyboard.hideSoftKeyboard(getActivity());
                break;
        }

    }

    private void modifyNewsCommentOkhttpCache(int offset, JSONObject commentData, String id) {
        String key = TimestampUtils.addTimestamp(Config.API_HOST + "article/" + id + "/comment?limit=10&offset=" + offset);
        byte[] data = OkHttpCache.getCache(getContext(), key);
        if (data != null) {
            try {
                JSONArray jsonArray = new JSONArray(new String(data));
                JSONArray newComment = new JSONArray();
                newComment.put(commentData);
                for (int i = 0, size = jsonArray.length() > 9 ? 9 : jsonArray.length(); i < size; i++) {
                    newComment.put(jsonArray.get(i));
                }
                OkHttpCache.updateCache(getContext(), key, newComment.toString().getBytes());
                if (jsonArray.length() == 10) {
                    modifyNewsCommentOkhttpCache(offset + 10, jsonArray.getJSONObject(9), id);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    private void showNoConnection(boolean isShow) {
        if (isShow) {
            mBinding.reuseNoConnection.getRoot().setVisibility(View.VISIBLE);
            mBinding.messageDetailRv.setVisibility(View.GONE);
        } else {
            mBinding.reuseNoConnection.getRoot().setVisibility(View.GONE);
            mBinding.messageDetailRv.setVisibility(View.VISIBLE);

            if (newsId != null) {
                getConcernDigest();
            }
        }
    }

    // 登录事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EBReuse reuse) {
        if (reuse.getType().equals(LOGIN_TAG)) { // 登入
            mUserInfo = UserManager.getInstance().getUserInfoEntity();
        }
    }

    @Override
    public void onCommentCallback(CommentEntity entity) {
        mCommentEntity = entity;
        setSoftInput(true);
    }

    @Override
    public void onResume() {
        super.onResume();
        mKeyboardHeightProvider.setKeyboardHeightObserver(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        mKeyboardHeightProvider.setKeyboardHeightObserver(null);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mKeyboardHeightProvider.close();
    }

    @Override
    public void onKeyboardHeightChanged(int height, int orientation) {
        popInputLayout(height > 0, height);
    }

    private void popInputLayout(boolean isPopup, int height) {
        if (requireActivity() instanceof MessageDetailActivity) {
            View shadowView = ((MessageDetailActivity) requireActivity()).getShadowView();
            shadowView.setVisibility(isPopup ? View.VISIBLE : View.GONE);
            shadowView.setOnClickListener(v -> Util_System_Keyboard.hideSoftKeyboard(getActivity()));
        }
        mBinding.pieceCommentTypingContainer.commentLine.setVisibility(isPopup ? View.GONE : View.VISIBLE);
        mBinding.shadowView.setVisibility(isPopup ? View.VISIBLE : View.GONE);
        mBinding.pieceCommentTypingContainer.answerContent.setOrientation(isPopup ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
        if (isPopup) {
            mBinding.pieceCommentTypingContainer.answerContent.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.bg_shape_white_radius_10_top_only));
        } else {
            mBinding.pieceCommentTypingContainer.answerContent.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.background_white));
            mOffset = Math.abs(height);
        }

        mBinding.pieceCommentTypingContainer.placeholderView.setVisibility(isPopup ? View.VISIBLE : View.GONE);

        LinearLayout.LayoutParams mScrollViewParams = (LinearLayout.LayoutParams) mBinding.pieceCommentTypingContainer.scrollView.getLayoutParams();
        mScrollViewParams.width = isPopup ? LinearLayout.LayoutParams.MATCH_PARENT : 0;
        mScrollViewParams.height = isPopup ? DisplayUtils.dip2px(76f) : DisplayUtils.dip2px(28f);
        mScrollViewParams.topMargin = isPopup ? DisplayUtils.dip2px(8f) : 0;
        mBinding.pieceCommentTypingContainer.scrollView.setLayoutParams(mScrollViewParams);

        RelativeLayout.LayoutParams mLayoutParams = (RelativeLayout.LayoutParams) mBinding.pieceCommentTypingContainer.answerCommentContentContainer.getLayoutParams();
        mLayoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
        mLayoutParams.bottomMargin = isPopup ? height + mOffset : 0;
        mBinding.pieceCommentTypingContainer.answerCommentContentContainer.setLayoutParams(mLayoutParams);
    }

    @Override
    public boolean onHandleBackPressed() {
        if (commentNum != -1 && adapter.getConcernEntity() != null
                && commentNum != adapter.getConcernEntity().getCommentnum()) {
            Intent intent = new Intent();
            intent.putExtra("commentNum", adapter.getConcernEntity().getCommentnum());
            if (getActivity() != null) {
                getActivity().setResult(Activity.RESULT_OK, intent);
                getActivity().finish();
            }
            return true;
        }
        return false;
    }

    @Override
    protected void onDarkModeChanged() {
        super.onDarkModeChanged();
        if (adapter != null) {
            adapter.notifyItemRangeChanged(0, adapter.getItemCount());
        }
    }
}
