package io.openim.android.ouiconversation.ui.fragment;


import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.hjq.permissions.Permission;
import com.yanzhenjie.recyclerview.OnItemClickListener;
import com.yanzhenjie.recyclerview.SwipeMenuCreator;
import com.yanzhenjie.recyclerview.SwipeMenuItem;

import java.util.HashSet;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import io.openim.android.ouiconversation.R;
import io.openim.android.ouiconversation.databinding.FragmentContactListBinding;
import io.openim.android.ouiconversation.databinding.LayoutAddActionBinding;
import io.openim.android.ouiconversation.ui.ChatActivity;
import io.openim.android.ouiconversation.ui.NotificationActivity;
import io.openim.android.ouiconversation.ui.SearchActivity;
import io.openim.android.ouiconversation.vm.ChatVM;
import io.openim.android.ouicore.adapter.ViewHol;
import io.openim.android.ouicore.base.BaseApp;
import io.openim.android.ouicore.base.BaseFragment;
import io.openim.android.ouicore.base.vm.injection.Easy;
import io.openim.android.ouicore.entity.MsgConversation;
import io.openim.android.ouicore.ex.MultipleChoice;
import io.openim.android.ouicore.utils.Common;
import io.openim.android.ouicore.utils.Constants;
import io.openim.android.ouicore.utils.HasPermissions;
import io.openim.android.ouicore.utils.Obs;
import io.openim.android.ouicore.utils.OnDedrepClickListener;
import io.openim.android.ouicore.utils.Routes;
import io.openim.android.ouicore.utils.SinkHelper;
import io.openim.android.ouicore.utils.TimeUtil;
import io.openim.android.ouicore.vm.ContactListVM;
import io.openim.android.ouicore.vm.GroupVM;
import io.openim.android.ouicore.vm.SelectTargetVM;
import io.openim.android.ouicore.vm.UserLogic;
import io.openim.android.sdk.OpenIMClient;
import io.openim.android.sdk.enums.ConversationType;
import io.openim.android.sdk.enums.Opt;
import io.openim.android.sdk.models.ConversationInfo;
import io.openim.android.sdk.models.FriendInfo;
import q.rorbin.badgeview.QBadgeView;

/**
 * 聊天列表窗口
 */
@Route(path = Routes.Conversation.CONTACT_LIST)
public class ConversationListFragment extends BaseFragment<ContactListVM> implements ContactListVM.ViewAction, Observer {

    private long mLastClickTime;

    private FragmentContactListBinding view;
    private CustomAdapter adapter;
    private HasPermissions hasScanPermission;
    private ActivityResultLauncher<Intent> resultLauncher;
    private final UserLogic user = Easy.find(UserLogic.class);
    private final HashSet<Integer> slideSet = new HashSet<>();
    private int slideNum = 0;

    public void setResultLauncher(ActivityResultLauncher<Intent> resultLauncher) {
        this.resultLauncher = resultLauncher;
    }

    public static ConversationListFragment newInstance() {

        Bundle args = new Bundle();
        ConversationListFragment fragment = new ConversationListFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        bindVM(ContactListVM.class);
        BaseApp.inst().putVM(vm);
        Obs.inst().addObserver(this);
        Activity activity = getActivity();
        if (null != activity) {
            activity.runOnUiThread(() -> hasScanPermission = new HasPermissions(getContext(), Permission.CAMERA, Permission.READ_EXTERNAL_STORAGE));
        }
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = FragmentContactListBinding.inflate(getLayoutInflater());

        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.header.getLayoutParams();
        lp.setMargins(0, SinkHelper.getStatusBarHeight(), 0, 0);
        view.header.setLayoutParams(lp);
        init();

        return view.getRoot();
    }

    private final OnItemClickListener onItemClickListener = (view, position) -> {
        long nowTime = System.currentTimeMillis();
        long timeInterval = 700;
        if (nowTime - mLastClickTime < timeInterval) return;
        mLastClickTime = nowTime;

        slideSet.remove(position);
        MsgConversation msgConversation = vm.conversations.getValue().get(position);
        if (msgConversation.conversationInfo.getConversationType() == ConversationType.NOTIFICATION) {
            //系统通知
            Intent intent = new Intent(getContext(), NotificationActivity.class)
                    .putExtra(Constants.K_NAME, msgConversation.conversationInfo.getShowName())
                    .putExtra(Constants.K_ID, msgConversation.conversationInfo.getConversationID());
            startActivity(intent);
            return;
        }

        Intent intent = new Intent(getContext(), ChatActivity.class)
                .putExtra(Constants.K_NAME, msgConversation.conversationInfo.getShowName())
                // 拉黑后从会话列表隐藏用户，传一个会话id进去
                /*.putExtra(Constants.CONVERSATION_ID, msgConversation.conversationInfo.getConversationID())*/;
        if (msgConversation.conversationInfo.getConversationType() == ConversationType.SINGLE_CHAT)
            intent.putExtra(Constants.K_ID, msgConversation.conversationInfo.getUserID());

        if (msgConversation.conversationInfo.getConversationType() == ConversationType.GROUP_CHAT
                || msgConversation.conversationInfo.getConversationType() == ConversationType.SUPER_GROUP_CHAT)
            intent.putExtra(Constants.K_GROUP_ID, msgConversation.conversationInfo.getGroupID());

        if (msgConversation.conversationInfo.getGroupAtType() == ConversationType.NOTIFICATION)
            intent.putExtra(Constants.K_NOTICE, msgConversation.notificationMsg);
        startActivity(intent);

        //重置强提醒
        OpenIMClient.getInstance().conversationManager.resetConversationGroupAtType(null, msgConversation.conversationInfo.getConversationID());
    };

    @SuppressLint("NewApi")
    private void init() {
        view.setLifecycleOwner(this);
        view.setUser(user);

        initHeader();
        view.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        SwipeMenuCreator mSwipeMenuCreator = (leftMenu, rightMenu, position) -> {
            SwipeMenuItem delete = new SwipeMenuItem(getContext());
            delete.setText(io.openim.android.ouicore.R.string.remove);
            delete.setHeight(MATCH_PARENT);
            delete.setWidth(Common.dp2px(73));
            delete.setTextSize(16);
            delete.setTextColor(getContext().getColor(android.R.color.white));
            delete.setBackgroundColor(getResources().getColor(io.openim.android.ouicore.R.color.txt_warning));

            MsgConversation conversationInfo = vm.conversations.getValue().get(position);
            SwipeMenuItem top = new SwipeMenuItem(getContext());
            top.setText(conversationInfo.conversationInfo.isPinned() ? io.openim.android.ouicore.R.string.cancel_top : io.openim.android.ouicore.R.string.top);
            top.setHeight(MATCH_PARENT);
            top.setWidth(Common.dp2px(73));
            top.setTextSize(16);
            top.setTextColor(getContext().getColor(android.R.color.white));
            top.setBackgroundColor(getResources().getColor(io.openim.android.ouicore.R.color.theme));

            SwipeMenuItem martRead = new SwipeMenuItem(getContext());
            martRead.setText(io.openim.android.ouicore.R.string.mark_read);
            martRead.setHeight(MATCH_PARENT);
            martRead.setWidth(Common.dp2px(73));
            martRead.setTextSize(16);
            martRead.setTextColor(getContext().getColor(android.R.color.white));
            martRead.setBackgroundColor(getResources().getColor(io.openim.android.ouicore.R.color.txt_shallow));

            //右侧添加菜单
            rightMenu.addMenuItem(top);
            if (conversationInfo.conversationInfo.getUnreadCount() > 0)
                rightMenu.addMenuItem(martRead);
            rightMenu.addMenuItem(delete);
        };
        view.recyclerView.setSwipeMenuCreator(mSwipeMenuCreator);
        ChatVM chatVM = new ChatVM();
        view.recyclerView.setOnItemMenuClickListener((menuBridge, adapterPosition) -> {
            int menuPosition = menuBridge.getPosition();
            MsgConversation conversationInfo = vm.conversations.getValue().get(adapterPosition);
            if (menuPosition == 0) {
                vm.pinConversation(conversationInfo.conversationInfo, !conversationInfo.conversationInfo.isPinned());
            } else if (menuPosition == 1 && conversationInfo.conversationInfo.getUnreadCount() > 0) {
                chatVM.markReadedByConID(conversationInfo.conversationInfo.getConversationID(), null);
            } else {
                vm.conversations.getValue().remove(conversationInfo);
                adapter.notifyItemRemoved(adapterPosition);
                vm.deleteConversationAndDeleteAllMsg(conversationInfo.conversationInfo.getConversationID());
            }
            menuBridge.closeMenu();
        });

        adapter = new CustomAdapter(onItemClickListener);
        view.recyclerView.setAdapter(adapter);
        view.recyclerView.setItemAnimator(null);

        vm.conversations.observe(getActivity(), v -> {
            if (null == v || v.size() == 0) return;
            int unreadCount = 0;
            slideSet.clear();
            for (int i = 0; i < v.size(); i++) {
                ConversationInfo con = v.get(i).conversationInfo;
                if (con.getRecvMsgOpt() == 0 && con.getUnreadCount() != 0) {
                    unreadCount += con.getUnreadCount();
                    slideSet.add(i);
                }
            }
            String str = unreadCount > 0 ? getString(io.openim.android.ouicore.R.string.app_name) + "(" + unreadCount + ")"
                    : getString(io.openim.android.ouicore.R.string.app_name);
            view.title.setText(str);
            adapter.setConversationInfos(v);
            adapter.notifyDataSetChanged();
        });

        Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.animation_repeat_spinning);
        Easy.find(UserLogic.class).connectStatus.observe(getActivity(), connectStatus -> {
            if (connectStatus == UserLogic.ConnectStatus.CONNECTING || connectStatus == UserLogic.ConnectStatus.SYNCING) {
                view.status.startAnimation(animation);
            } else {
                view.status.clearAnimation();
            }
        });


        view.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (Common.mShouldScroll && RecyclerView.SCROLL_STATE_IDLE == newState) {
                    Common.mShouldScroll = false;
                    Common.smoothMoveToPosition(view.recyclerView, Common.mToPosition);
                }
            }
        });
    }

    private void initHeader() {
        user.info.observe(getActivity(), v -> {
            view.avatar.load(v.getFaceURL(), v.getNickname());
            view.name.setText(v.getNickname());
        });
        view.addFriend.setOnClickListener(this::showPopupWindow);
        view.callRecord.setOnClickListener(view -> {
            ARouter.getInstance().build(Routes.Main.CALL_HISTORY).navigation();
        });

        view.search.setOnClickListener(v -> startActivity(new Intent(getActivity(), SearchActivity.class)));
    }


    private void showPopupWindow(View v) {
        //初始化一个PopupWindow，width和height都是WRAP_CONTENT
        PopupWindow popupWindow = new PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        LayoutAddActionBinding view = LayoutAddActionBinding.inflate(getLayoutInflater());
        view.scan.setOnClickListener(c -> {
            popupWindow.dismiss();
            hasScanPermission.safeGo(() -> Common.jumpScan(getActivity(), resultLauncher));
        });
        view.addFriend.setOnClickListener(c -> {
            popupWindow.dismiss();
            ARouter.getInstance().build(Routes.Main.ADD_CONVERS).navigation();
        });
        view.addGroup.setOnClickListener(c -> {
            popupWindow.dismiss();
            ARouter.getInstance().build(Routes.Main.ADD_CONVERS).withBoolean(Constants.K_RESULT, false).navigation();
        });
        view.createGroup.setOnClickListener(c -> {
            popupWindow.dismiss();

            SelectTargetVM targetVM = Easy.installVM(SelectTargetVM.class).setIntention(SelectTargetVM.Intention.isCreateGroup);
            targetVM.setOnFinishListener(() -> {
                GroupVM groupVM = BaseApp.inst().getVMByCache(GroupVM.class);
                if (null == groupVM)
                    groupVM = new GroupVM();
                groupVM.selectedFriendInfo.getValue().clear();
                List<MultipleChoice> multipleChoices = targetVM.metaData.getValue();
                for (int i = 0; i < multipleChoices.size(); i++) {
                    MultipleChoice us = multipleChoices.get(i);
                    FriendInfo friendInfo = new FriendInfo();
                    friendInfo.setUserID(us.key);
                    friendInfo.setNickname(us.name);
                    friendInfo.setFaceURL(us.icon);
                    groupVM.selectedFriendInfo.getValue().add(friendInfo);
                }
                BaseApp.inst().putVM(groupVM);
                //发起群聊
                ARouter.getInstance().build(Routes.Group.CREATE_GROUP2).navigation();
            });
            ARouter.getInstance().build(Routes.Group.SELECT_TARGET).navigation();
        });
        view.videoMeeting.setOnClickListener(c -> {
            popupWindow.dismiss();
            ARouter.getInstance().build(Routes.Meeting.LAUNCH).navigation();
        });
        //设置PopupWindow的视图内容
        popupWindow.setContentView(view.getRoot());
        //点击空白区域PopupWindow消失，这里必须先设置setBackgroundDrawable，否则点击无反应
        popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
        popupWindow.setOutsideTouchable(true);

        //PopupWindow在targetView下方弹出
        popupWindow.showAsDropDown(v);
    }


    @Override
    public void onErr(String msg) {
        try {
            Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
        } catch (Exception ignored) {
        }

    }

    public void clickSlideSet() {
        if (slideSet.isEmpty()) return;
        if (slideNum > slideSet.size() - 1)
            slideNum = 0;
        Common.smoothMoveToPosition(view.recyclerView, (int) slideSet.toArray()[slideNum++]);
    }

    @Override
    public void onSuccess(Object body) {
        super.onSuccess(body);
    }

    class CustomAdapter extends RecyclerView.Adapter<ViewHol.ContactListItemHolder> {

        private List<MsgConversation> conversationInfos;
        private OnItemClickListener itemClickListener;

        public CustomAdapter(OnItemClickListener itemClickListener) {
            this.itemClickListener = itemClickListener;
        }

        public void setConversationInfos(List<MsgConversation> conversationInfos) {
            this.conversationInfos = conversationInfos;
            notifyItemChanged(1);
        }

        @Override
        public ViewHol.ContactListItemHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
            return new ViewHol.ContactListItemHolder(viewGroup);
        }

        @Override
        public void onBindViewHolder(ViewHol.ContactListItemHolder viewHolder, int position) {
            final int index = position;
            viewHolder.viewBinding.getRoot().setOnClickListener(new OnDedrepClickListener() {
                @Override
                public void click(View v) {
                    if (null != itemClickListener)
                        itemClickListener.onItemClick(v, index);
                }
            });
            MsgConversation msgConversation = conversationInfos.get(position);
            boolean isGroup = msgConversation.conversationInfo.getConversationType() != ConversationType.SINGLE_CHAT;
            if (msgConversation.conversationInfo.getConversationType() == ConversationType.NOTIFICATION) {
//                viewHolder.viewBinding.avatar.getRoundImageView().setImageResource(io.openim.android.ouicore.R.mipmap.icon_notification);
                viewHolder.viewBinding.avatar.loadNotice(msgConversation.conversationInfo.getFaceURL());
                viewHolder.viewBinding.tips.setVisibility(View.VISIBLE);
            } else {
                viewHolder.viewBinding.tips.setVisibility(View.GONE);
//                viewHolder.viewBinding.avatar.load(msgConversation.conversationInfo.getFaceURL(), isGroup);
                viewHolder.viewBinding.avatar.load(msgConversation.conversationInfo.getFaceURL(), isGroup,msgConversation.conversationInfo.getShowName());
            }
            viewHolder.viewBinding.nickName.setText(msgConversation.conversationInfo.getShowName());
            int count = msgConversation.conversationInfo.getUnreadCount();
            if (msgConversation.conversationInfo.getRecvMsgOpt() != Opt.NORMAL) {
                buildBadgeView(ConversationListFragment.this.getContext(), viewHolder.viewBinding.avatar, count);
                viewHolder.viewBinding.noDisturbIc.setVisibility(View.VISIBLE);
            } else {
                viewHolder.viewBinding.noDisturbIc.setVisibility(View.GONE);
                buildBadgeView(ConversationListFragment.this.getContext(), viewHolder.viewBinding.avatar, count);
            }
            viewHolder.viewBinding.time.setText(TimeUtil.getTimeString(msgConversation.conversationInfo.getLatestMsgSendTime()));

            viewHolder.viewBinding.setTop.setVisibility(msgConversation.conversationInfo.isPinned() ? View.VISIBLE : View.GONE);

            CharSequence lastMsg = msgConversation.lastMsg;
            viewHolder.viewBinding.lastMsg.setText(lastMsg);
        }

        @Override
        public int getItemCount() {
            return null == conversationInfos ? 0 : conversationInfos.size();
        }
    }

    public void buildBadgeView(Context context, View target, int badgeNumber) {
        QBadgeView badgeView = (QBadgeView) target.getTag();
        if (null != badgeView) {
            badgeView.setBadgeNumber(badgeNumber);
            return;
        }
        target.setTag(new QBadgeView(context)
                .bindTarget(target)
                .setBadgeNumber(badgeNumber)
                .setGravityOffset(-1, 0, true)
                .setBadgeTextSize(8, true).setShowShadow(false));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        BaseApp.inst().removeCacheVM(vm.getClass());
        Obs.inst().deleteObserver(this);

        Animation animation = view.status.getAnimation();
        if (null != animation) animation.cancel();
    }

    @Override
    public void update(Observable observable, Object o) {
        Obs.Message message = (Obs.Message) o;
        if (message.tag == Constants.Event.USER_INFO_UPDATE) {
            initHeader();
        }
    }
}
