package com.ez.ertc.meeting.ui;

import android.content.Context;
import android.content.res.Configuration;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.ez.baselib.utils.LogUtil;
import com.ez.ertc.meeting.ErtcEzmHelper;
import com.ez.ertc.meeting.R;
import com.ez.ertc.meeting.contract.ErtcRoomContract;
import com.ez.ertc.meeting.presenter.ErtcRoomPresenter;
import com.ez.ertc.meeting.utils.ViewUtil;
import com.ez.ertc.meeting.widget.ErtcTextureView;
import com.ez.ertc.meeting.widget.MtTextView;
import com.ez.ertcmeeting.bean.UserAccount;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author xiezuoyuan
 * @time 2020/5/18 17:02
 */
public class ErtcRoomViewHolder implements ErtcRoomContract.GroupView, View.OnClickListener {

    public static final int PAGE_SIZE = 3;
    MtTextView btnLeft;
    MtTextView btnRight;
    LinearLayout llItemParent;
    FrameLayout flSelf;
    FrameLayout fl0;
    FrameLayout fl1;
    FrameLayout fl2;
    ErtcRoomContract.Presenter mPresenter;
    private int mPageSize = PAGE_SIZE;
    private int arrowWidthP;
    private int arrowWidthL;
    private int gap;
    private int itemWidthP;
    private int itemWidthL;
    private int itemHeightP;
    private int itemHeightL;
    private int landscapeTopMargin;
    private Context context;
    private Map<String, ErtcRoomContract.ItemViewHolder> mMap = new HashMap<>();
    private ErtcRoomItemViewHolderSelf roomItemViewHolderSelf;
    private ErtcRoomItemViewHolder0 roomItemViewHolder0;
    private ErtcRoomItemViewHolder1 roomItemViewHolder1;
    private ErtcRoomItemViewHolder2 roomItemViewHolder2;
    private int mPageNo = 0;

    public ErtcRoomViewHolder(View contentView) {
        btnLeft = contentView.findViewById(R.id.btnLeft);
        btnRight = contentView.findViewById(R.id.btnRight);
        llItemParent = contentView.findViewById(R.id.llItemParent);
        flSelf = contentView.findViewById(R.id.flSelf);
        fl0 = contentView.findViewById(R.id.fl0);
        fl1 = contentView.findViewById(R.id.fl1);
        fl2 = contentView.findViewById(R.id.fl2);
        btnLeft.setOnClickListener(this);
        btnRight.setOnClickListener(this);
        flSelf.setOnClickListener(this);
        fl0.setOnClickListener(this);
        fl1.setOnClickListener(this);
        fl2.setOnClickListener(this);

        context = contentView.getContext();
        arrowWidthP = ViewUtil.dp2px(context,24);
        arrowWidthL = ViewUtil.dp2px(context,34);
        gap = ViewUtil.dp2px(context,6);
    }

    @Override
    public void onClick(View v){
        int id = v.getId();
        if (id == R.id.btnLeft){
            mPageNo--;
            notifyDataChanged(ErtcRoomPresenter.sAccountList);
        } else if (id == R.id.btnRight){
            mPageNo++;
            notifyDataChanged(ErtcRoomPresenter.sAccountList);
        } else if (id == R.id.flSelf){
            if (canSwitch())
                notifySwitchToScreen(roomItemViewHolderSelf);
        } else if (id == R.id.fl0){
            if (canSwitch())
                notifySwitchToScreen(roomItemViewHolder0);
        } else if (id == R.id.fl1){
            if (canSwitch())
                notifySwitchToScreen(roomItemViewHolder1);
        } else if (id == R.id.fl2){
            if (canSwitch())
                notifySwitchToScreen(roomItemViewHolder2);
        }
    }

    @Override
    public void setPresenter(ErtcRoomContract.Presenter presenter){
        mPresenter = presenter;
        roomItemViewHolderSelf = new ErtcRoomItemViewHolderSelf(flSelf,mPresenter);
        roomItemViewHolder0 = new ErtcRoomItemViewHolder0(fl0,mPresenter);
        roomItemViewHolder1 = new ErtcRoomItemViewHolder1(fl1,mPresenter);
        roomItemViewHolder2 = new ErtcRoomItemViewHolder2(fl2,mPresenter);
    }

    @Override
    public void updateSelfDelayLevel(String myUserId, int level) {
        roomItemViewHolderSelf.updateSelfDelayLevel(level);
    }
    /**
     * 设置自己的音频能量，不需要判断是否静音
     * @param level
     */
    @Override
    public void setSelfAudioLevel(int level) {
        roomItemViewHolderSelf.setAudioLevel(level);
    }

    /**
     * 设置别人的音频能量，需要 判断是否静音
     * @param userId
     * @param level
     */
    @Override
    public void setMemberAudioLevel(String userId, int level) {
        ErtcRoomContract.ItemViewHolder viewHolder = mMap.get(userId);
        if (viewHolder != null){
            viewHolder.setAudioLevel(level);
        }
    }

    @Override
    public void showGroupView() {
        if (mPresenter.isPInP()){
            if(ErtcRoomPresenter.sAccountList.size() > 0) {
                notifyDataChanged(ErtcRoomPresenter.sAccountList);
            }
            llItemParent.setVisibility(View.VISIBLE);
        } else {
            llItemParent.setVisibility(View.GONE);
        }
    }

    @Override
    public void hideGroupView() {
        llItemParent.setVisibility(View.GONE);
    }

    @Override
    public Set<String> getCurrentPageAccounts() {
        int size = mMap.size();
        Set<String> extList = new HashSet<>(size);
        extList.addAll(mMap.keySet());
        return extList;
    }

    @Override
    public boolean hasMember(String userId) {
        return mMap.get(userId) != null;
    }

    @Override
    public void showWaterMark(boolean show) {
        roomItemViewHolder0.showWaterMark(show);
        roomItemViewHolder1.showWaterMark(show);
        roomItemViewHolder2.showWaterMark(show);
        roomItemViewHolderSelf.showWaterMark(show);
    }

    @Override
    public void updateWaterMark() {
        roomItemViewHolder0.updateWaterMark();
        roomItemViewHolder1.updateWaterMark();
        roomItemViewHolder2.updateWaterMark();
        roomItemViewHolderSelf.updateWaterMark();
    }

    private void updateView(int orientation){
        //横竖屏切换时情空一下画布
        roomItemViewHolder0.clearPixels();
        roomItemViewHolder1.clearPixels();
        roomItemViewHolder2.clearPixels();
        roomItemViewHolder0.updateView(orientation,landscapeTopMargin);
        roomItemViewHolder1.updateView(orientation,landscapeTopMargin);
        roomItemViewHolder2.updateView(orientation,landscapeTopMargin);
        roomItemViewHolderSelf.updateView(orientation,landscapeTopMargin);
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) llItemParent.getLayoutParams();
        if (orientation == Configuration.ORIENTATION_PORTRAIT){
            btnLeft.getLayoutParams().width = arrowWidthP;
            btnRight.getLayoutParams().width = arrowWidthP;
            layoutParams.height = itemHeightP;
        } else {
            btnLeft.getLayoutParams().width = arrowWidthL;
            btnRight.getLayoutParams().width = arrowWidthL;
            layoutParams.height = itemHeightL;
        }
    }

    @Override
    public void init(Configuration newConfig,int screenWidth,int screenHeight) {
        if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
            itemWidthP = (screenWidth - arrowWidthP * 2 - gap * 3) / 4;
            itemHeightP = 16 * itemWidthP / 9;
            itemWidthL = (screenHeight - arrowWidthL * 2 - gap * 3) / 4;
            itemHeightL = 9 * itemWidthL / 16;
        } else {
            itemWidthL = (screenWidth - arrowWidthL * 2 - gap * 3) / 4;
            itemHeightL = 9 * itemWidthL / 16;
            itemWidthP = (screenHeight - arrowWidthP * 2 - gap * 3) / 4;
            itemHeightP = 16 * itemWidthP / 9;
        }
        int bottomHeight = ViewUtil.dp2px(ErtcEzmHelper.getContext(), 22);
        int avatarHeight = ViewUtil.dp2px(ErtcEzmHelper.getContext(),50);
        landscapeTopMargin = Math.max(0,(itemHeightL - bottomHeight - avatarHeight) / 2);
        updateView(newConfig.orientation);
    }

    @Override
    public void onConfigurationChanged(int orientation) {
        updateView(orientation);
    }

    /**
     * 【默认显示规则】：
     *
     * 1、所有人（包括自己）按进入时间排序，如图1、2、3、4、5……位置示意
     *
     * （但是第1的自己和第2小图进行交换）
     *
     * 【“1+4+N”显示规则】：
     *
     * 1、小于1+4，每屏幕只显示当前视频数量，没视频的窗口显示默认图；
     *
     * 2、大于1+4，用左右翻页按钮，当点击翻页时，窗口位置不变，显示第二页视频；
     *
     * 3、若大图离开，全局的第一个小图变成大图，其他小图往前移动；
     *
     * 4、当我在1屏时：若1屏有人离开，此时2屏和之后的屏依次往前补充；
     *
     * 5、当我在2屏时：若1屏或3屏有人离开，此时2屏不变；只有2屏自身变动时，3屏往前补充到2屏；
     *
     * 6、当我在3屏时：若1屏或2屏有人离开，此时3屏不变，只有当我翻页到2屏时，才显示动态排列后的第6-9个小图；
     *
     * 交互说明
     *
     * 【大图-小图切换规则】：
     *
     * 1、手动将小图切换到大图，此时大图回到该小图位置；
     * @param mAccountList
     */
    @Override
    public void notifyDataChanged(List<UserAccount> mAccountList) {
        mMap.clear();
        int size = mAccountList.size();
        if (size <= mPageSize){
            mPageNo = 0;
        } else {
            if (mPageNo < 0) {
                mPageNo = 0;
            }
        }
        int beginIndex = mPageNo * mPageSize;
        int endIndex = Math.min(beginIndex + mPageSize, size);
        LogUtil.d("EZRTCImpl", "notifyDataChanged size:" + size + " beginIndex:" + beginIndex + " endIndex:" + endIndex);

        if(endIndex - beginIndex == 2) {
            roomItemViewHolder2.unbind();
        } else if(endIndex - beginIndex == 1) {
            roomItemViewHolder1.unbind();
            roomItemViewHolder2.unbind();
        } else if(endIndex - beginIndex == 0){
            roomItemViewHolder0.unbind();
            roomItemViewHolder1.unbind();
            roomItemViewHolder2.unbind();
        }

        if(mAccountList.size() > beginIndex) {
            if (roomItemViewHolder0.getAccount() != null && !roomItemViewHolder0.getAccount().getUserId().equals(mAccountList.get(beginIndex).getUserId())) {
                roomItemViewHolder0.unbind();
            }
        }
        if(mAccountList.size() > beginIndex + 1) {
            if (roomItemViewHolder1.getAccount() != null && !roomItemViewHolder1.getAccount().getUserId().equals(mAccountList.get(beginIndex + 1).getUserId())) {
                roomItemViewHolder1.unbind();
            }
        }
        if(mAccountList.size() > beginIndex + 2) {
            if (roomItemViewHolder2.getAccount() != null && !roomItemViewHolder2.getAccount().getUserId().equals(mAccountList.get(beginIndex + 2).getUserId())) {
                roomItemViewHolder2.unbind();
            }
        }
        if (size == 0){
            mPageNo = 0;
            roomItemViewHolderSelf.unbind();
        } else if (size <= mPageSize){
            roomItemViewHolderSelf.bindView(mPresenter.getMyAccount());
            mPageNo = 0;
            synchronized (mAccountList){
                for (int i = 0; i < size; i++) {
                    UserAccount account = mAccountList.get(i);
                    switch (i){
                        case 0:
                            mMap.put(account.getUserId(),roomItemViewHolder0);
                            roomItemViewHolder0.bindView(account);
                            break;
                        case 1:
                            mMap.put(account.getUserId(),roomItemViewHolder1);
                            roomItemViewHolder1.bindView(account);
                            break;
                        case 2:
                            mMap.put(account.getUserId(),roomItemViewHolder2);
                            roomItemViewHolder2.bindView(account);
                            break;
                    }
                }
            }
        } else {
            roomItemViewHolderSelf.bindView(mPresenter.getMyAccount());
            if (mPageNo < 0){
                mPageNo = 0;
            }
            mPresenter.disableReceiveStreamAll();
            synchronized (mAccountList){
                for (int i = beginIndex; i < endIndex; i++) {
                    UserAccount account = mAccountList.get(i);
                    switch (i%mPageSize){
                        case 0:
                            mMap.put(account.getUserId(),roomItemViewHolder0);
                            roomItemViewHolder0.bindView(account);
                            break;
                        case 1:
                            mMap.put(account.getUserId(),roomItemViewHolder1);
                            roomItemViewHolder1.bindView(account);
                            break;
                        case 2:
                            mMap.put(account.getUserId(),roomItemViewHolder2);
                            roomItemViewHolder2.bindView(account);
                            break;
                    }
                }
            }
        }
        updateBtnVisibility();
    }

    @Override
    public void notifyItemChanged(UserAccount account) {
        if(account == null) return;
        if (roomItemViewHolderSelf.getAccount() != null && account.getUserId() == roomItemViewHolderSelf.getAccount().getUserId()){
            roomItemViewHolderSelf.bindView(account);
            return;
        }
        List<UserAccount> list = ErtcRoomPresenter.sAccountList;
        synchronized (list){
            int index = -1;
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).getUserId() == account.getUserId()){
                    index = i;
                    break;
                }
            }
            if (index != -1){
                list.set(index,account);
                ErtcRoomContract.ItemViewHolder holder = mMap.get(account.getUserId());
                if (holder != null){
                    holder.bindView(account);
                }
            }
        }
    }

    @Override
    public void notifyExit(UserAccount account) {
        synchronized (ErtcRoomPresenter.sAccountList){
            Iterator<UserAccount> iterator = ErtcRoomPresenter.sAccountList.iterator();
            while (iterator.hasNext()){
                UserAccount a = iterator.next();
                if (account.getUserId() == a.getUserId()){
                    iterator.remove();
                    break;
                }
            }
        }
        int size = ErtcRoomPresenter.sAccountList.size();
        //离开的是大图
        if (mPresenter.getScreenAccount() != null && mPresenter.getScreenAccount().getUserId() == account.getUserId()){
            if (size > 0){
                notifySwitchToScreen(ErtcRoomPresenter.sAccountList.get(0));
            } else {
                notifySwitchToScreen(roomItemViewHolderSelf);
            }
        } else if (size == 0){
            notifySwitchToScreen(roomItemViewHolderSelf);
        }
        if (size <= mPageSize){
            //只有1页，直接更新
            notifyDataChanged(ErtcRoomPresenter.sAccountList);
        } else if (size % mPageSize == 0){
            mPageNo = size / mPageSize - 1;
            notifyDataChanged(ErtcRoomPresenter.sAccountList);
            return;
        } else {
            notifyDataChanged(ErtcRoomPresenter.sAccountList);
        }
        //更新左右翻页按钮
        updateBtnVisibility();
    }

    private void notifySwitchToScreen(ErtcRoomContract.ItemViewHolder viewHolder) {
        if (viewHolder.getAccount() != null){
            notifySwitchToScreen(viewHolder.getAccount());
        }
    }
    @Override
    public void notifySwitchToScreen(UserAccount account) {
        //如果大屏的成员目前在本页，切换到小流，否则不接收
        UserAccount accountOld = mPresenter.getScreenAccount();
        if (accountOld != null && accountOld.getUserId() != account.getUserId()){
            if (mMap.get(accountOld.getUserId()) != null){
                mPresenter.setLowStreamForce(accountOld);
            } else {
                mPresenter.disableReceiveStream(accountOld.getUserId());
            }
        }
        if (accountOld == null || accountOld.getUserId() != account.getUserId())
            mPresenter.setScreenAccount(account);
    }

    @Override
    public void updateBtnVisibility(){
        if (mPageNo > 0){
            btnLeft.setVisibility(View.VISIBLE);
        } else {
            btnLeft.setVisibility(View.INVISIBLE);
        }
        int beginIndex = mPageNo * mPageSize;
        if (beginIndex + mPageSize < ErtcRoomPresenter.sAccountList.size()){
            btnRight.setVisibility(View.VISIBLE);
        } else {
            btnRight.setVisibility(View.INVISIBLE);
        }
    }

    @Override
    public ErtcTextureView findTextureView(String userId) {
        if (roomItemViewHolderSelf.getAccount() != null && roomItemViewHolderSelf.getAccount().getUserId() == userId){
            return roomItemViewHolderSelf.textureViewSelf;
        } else {
            ErtcRoomContract.ItemViewHolder holder = mMap.get(userId);
            if (holder != null){
                return holder.getTextureView();
            }
            return null;
        }
    }

    private boolean canSwitch(){
        return mPresenter.getSharingDesktopUserId().isEmpty();
    }
}
