package com.daya.live_teaching.ui.fragmnet;


import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.cooleshow.base.ui.fragment.BaseFragment;
import com.daya.live_teaching.R;
import com.daya.live_teaching.databinding.FragmentVideoListBinding;
import com.daya.live_teaching.model.ClassMember;
import com.daya.live_teaching.model.DeviceChange;
import com.daya.live_teaching.model.DeviceType;
import com.daya.live_teaching.model.RequestState;
import com.daya.live_teaching.model.Role;
import com.daya.live_teaching.model.ScreenDisplay;
import com.daya.live_teaching.model.StreamResource;
import com.daya.live_teaching.model.UserInfo;
import com.daya.live_teaching.model.VideoClassMemberData;
import com.daya.live_teaching.ui.adapter.VideoListAdapter;
import com.daya.live_teaching.ui.view.ClassVideoListItem;
import com.daya.live_teaching.ui.view.RadioRtcVideoView;
import com.daya.live_teaching.utils.ToastUtils;
import com.daya.live_teaching.utils.log.SLog;
import com.daya.live_teaching.viewmodel.ClassViewModel;

import java.util.ArrayList;
import java.util.List;

import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import cn.rongcloud.rtc.api.stream.RCRTCVideoView;

/**
 * A simple {@link Fragment} subclass.
 */
public class VideoListFragment extends BaseFragment<FragmentVideoListBinding> {


    RecyclerView videoList;
    private static final String TAG_VIDEO_VIEW = "video_view";
    /**
     * 此字段是动态订阅的开关。
     */
    public static final boolean isDynamicSubscribe = false;
    private ClassViewModel classViewModel;
    private VideoListAdapter classVideoListAdapter;
    private UserInfo userInfoValue;
    private OnVideoViewItemClickListener listener;
    private int firstItemPosition;
    private String roomId;

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

    @Override
    protected FragmentVideoListBinding getLayoutView() {
        return FragmentVideoListBinding.inflate(getLayoutInflater());
    }

    @Override
    protected void initView(View rootView) {
        videoList = mViewBinding.videoList;

        LinearLayoutManager manager = new LinearLayoutManager(getContext());
        videoList.setLayoutManager(manager);

        classVideoListAdapter = new VideoListAdapter(getContext());
        classVideoListAdapter.setOnItemBtnClickListener((type, isChecked, member) -> {
            if (type == ClassVideoListItem.BtnOperate.MIC) {

            } else if (type == ClassVideoListItem.BtnOperate.CAMERA) {

            } else if (type == ClassVideoListItem.BtnOperate.MUSIC_MODE) {

            }
        });
        classVideoListAdapter.setOnUserUpdateListener(new VideoListAdapter.OnUserUpdateListener() {
            @Override
            public void onUpdate(ClassVideoListItem view, int position, ClassMember newMember) {
                updateVideoItem(view, newMember);
            }
        });
        classVideoListAdapter.setHasStableIds(true);
        videoList.setAdapter(classVideoListAdapter);
        ((SimpleItemAnimator) videoList.getItemAnimator()).setSupportsChangeAnimations(false);

        classVideoListAdapter.setOnItemClickListener((VideoListAdapter.OnItemClickListener) member -> {
            if (listener != null) {
                listener.onItemClick(member);
            }
        });
        videoList.addOnScrollListener(new RecyclerView.OnScrollListener() {

            private int lastItemPosition;

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                //判断是当前layoutManager是否为LinearLayoutManager
                // 只有LinearLayoutManager才有查找第一个和最后一个可见view位置的方法
                if (layoutManager instanceof LinearLayoutManager) {
                    LinearLayoutManager linearManager = (LinearLayoutManager) layoutManager;
                    //获取第一个可见view的位置
                    firstItemPosition = linearManager.findFirstVisibleItemPosition();
                    //获取最后一个可见view的位置
                    lastItemPosition = linearManager.findLastVisibleItemPosition();
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });
    }

    //清除当前listview 中的所有信息缓存以及 VideoView。
    public void clearVideoViewInListView() {
        try {
            int firstVisiblePosition = firstItemPosition;
            int childCount = videoList.getChildCount();
            for (int i = firstVisiblePosition; i < firstVisiblePosition + childCount; i++) {
                int index = i - firstVisiblePosition;
                View childAt = videoList.getChildAt(index);
                if (childAt != null) {
                    ClassVideoListItem itemView = (ClassVideoListItem) childAt;
                    itemView.clear();
                }
            }
        } catch (Exception e) {

        }
    }

    //更新列表资源
    public void updateList(List<ClassMember> classMembers, boolean isListNoUpdate, boolean isNotify) {

        if (classVideoListAdapter != null) {
            if (!isListNoUpdate) {
                // 列表里的人没有发生变化， 则不需要清了数据。 但是数据的状态可能改变。
                // 例如摄像头状态等
                clearVideoViewInListView();
            }
            if (classMembers != null) {
                //                classVideoListAdapter.setListData(classMembers, (classViewModel.getDisplay().getValue().getType() != ScreenDisplay.Display.WHITEBOARD));
                classVideoListAdapter.setListData(classMembers, userInfoValue, isNotify);
            }

        }
    }

    // 视频列表布局刷新，此方法用于VideoView 的填充到 list 中的操作。
    private synchronized void updateVideoItem(final ClassVideoListItem view, final ClassMember newMember) {
        // 当前布局要加载的数据
        if (newMember != null) {
            String userId = newMember.getUserId();
            if (userId.equals("-1")) {
                view.removeVideoView();
                view.contentText(R.string.class_video_list_lecturer_comming);
                view.setContentVisibility(View.VISIBLE);
                SLog.d(TAG_VIDEO_VIEW, "Update list item, new member, lecturer is null, return");
                return;
            }
            // 1. 是否有 VideoView
            // 布局展示不负责创建 VideoView， 是根据 RTC 的回调来创建的
            boolean contains = VideoViewManager.getInstance().containsKey(userId);
            // 1.1 存在， 则进行下面流程， 不存在则直接移除
            if (contains) {
                final RadioRtcVideoView videoView = VideoViewManager.getInstance().get(userId);
                if (userInfoValue != null && !userInfoValue.getUserId().equals(userId)) {
                    // 教师控制别的人的摄像头， 刷新摄像头状态
                    if (!newMember.isCamera()) {
                        videoView.clearScreen();
                    }
                    SLog.d(TAG_VIDEO_VIEW, "Update list item, has video view in layout: " + videoView.isHasParent());
                    //2 当 VideoView 没有父容器时， 则可添加到容器中，否则就是被其他容器占用。例如共享区域
                    ScreenDisplay screenDisplay = classViewModel.getDisplay().getValue();
                    ScreenDisplay.Display display = screenDisplay.getType();
                    String screenUserId = screenDisplay.getUserId();
                    if (display != ScreenDisplay.Display.WHITEBOARD && !TextUtils.isEmpty(screenUserId) && screenUserId.equals(userId)) {
                        view.removeVideoView();
                    } else {
                        if (view != null) {
                            if (videoView.isHasParent()) {
                                ((ViewGroup) videoView.getParent()).removeAllViews();
                            }
                            view.addVideoView(videoView, getItemLayoutParams());
                        }
                    }

                } else {
                    if (!newMember.isCamera()) {
                        videoView.clearScreen();
                    }
                    SLog.d(TAG_VIDEO_VIEW, "Update list item, local, has video view in layout: " + videoView.isHasParent());
                    // 1.2 VideoView 存在， 则要看其是否被父类容器使用。如果被使用， 则不添加到布局中。
                    ScreenDisplay screenDisplay = classViewModel.getDisplay().getValue();
                    ScreenDisplay.Display display = screenDisplay.getType();
                    String screenUserId = screenDisplay.getUserId();
                    if (display != ScreenDisplay.Display.WHITEBOARD && !TextUtils.isEmpty(screenUserId) && screenUserId.equals(userId)) {
                        view.removeVideoView();
                    } else {
                        if (view != null) {
                            if (videoView.isHasParent()) {
                                ((ViewGroup) videoView.getParent()).removeAllViews();
                            }
                            // 由于本地用户可能是旁听者， 旁听者是没有音视频聊天权限的，所以就没有 VideoView
                            if (newMember.getRole() != Role.LISTENER) {
                                view.addVideoView(videoView, getItemLayoutParams());
                            } else {
                                view.removeVideoView();
                            }
                        }
                    }
                }
            } else {
                // 1.2 不存在， 直接移除以前的布局。 被移除的布局可以其他的界面容器重写填充
                if (view != null) {
                    view.removeVideoView();
                }
            }

            if (newMember.getRole() == Role.LECTURER) {
                if (view.getVideoViewCount() <= 0) {
                    view.contentText(R.string.class_video_list_lecturer_content);
                    view.setContentVisibility(View.VISIBLE);

                } else {
                    view.contentText("");
                    view.setContentVisibility(View.GONE);
                }
            } else if (newMember.isOnStage() && userInfoValue.getRole() == Role.LECTURER) {
                view.setContentVisibility(View.VISIBLE);
            } else {
                view.setContentVisibility(View.GONE);
            }
        }
    }


    @Override
    public void initData() {

        classViewModel = ViewModelProviders.of(getActivity()).get(ClassViewModel.class);

        // 用户信息
        classViewModel.getUserInfo().observe(this, new Observer<UserInfo>() {
            @Override
            public void onChanged(UserInfo userInfo) {
                userInfoValue = userInfo;
            }
        });
        classViewModel.getRoomId().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                roomId = s;
            }
        });
        // 音视频进入房间后，就已经存在的用户
        classViewModel.getInitVideoList().observe(this, new Observer<List<StreamResource>>() {
            @Override
            public void onChanged(List<StreamResource> resources) {
                if (classViewModel.getGongGe()) {
                    return;
                }
                if (resources == null || resources.size() <= 0) {
                    return;
                }
                for (StreamResource resource : resources) {
                    String userId = resource.userId;
                    createVideoView(userId);
                    RadioRtcVideoView videoView = VideoViewManager.getInstance().get(userId);
                    // 非动态订阅视频
                    // 人员一加入就立即订阅
                    //只管创建视频videoview， 并订阅音视频流， 不管布局加载
                    if (resource.isHasVideo && resource.isHasScreen) { // 既有视频流， 又有桌面共享流
                        if (!videoView.isBindVideo()) {
                            videoView.setBindVideo(true); // 标记已经绑定了流
                            // 桌面共享的 VideoView 是否存在， 没有则创建
                            RadioRtcVideoView shareScreenVideoView = VideoViewManager.getInstance().getShareScreenVideoView();
                            if (shareScreenVideoView != null && !shareScreenVideoView.isBindVideo()) {
                                subscribe(userId, videoView, shareScreenVideoView);
                            } else {
                                subscribe(userId, videoView);
                            }
                        }
                    } else if (resource.isHasVideo) { // 有视频流
                        if (!videoView.isBindVideo()) {
                            videoView.setBindVideo(true); // 标记已经绑定了流
                            subscribe(userId, videoView);
                        }
                    } else if (resource.isHasScreen) { // 有桌面流
                        RadioRtcVideoView shareScreenRtcVideoView = VideoViewManager.getInstance().getShareScreenVideoView();
                        if (shareScreenRtcVideoView == null) {
                            shareScreenRtcVideoView = new RadioRtcVideoView(getActivity());
                            final RadioRtcVideoView finalShareScreenVideoView = shareScreenRtcVideoView;
                            shareScreenRtcVideoView.setOnSizeChangedListener(new RCRTCVideoView.OnSizeChangedListener() {
                                @Override
                                public void onChanged(RCRTCVideoView.Size size) {
                                    if (size != null) {
                                        float radio = (float) size.with / (float) size.height;
                                        SLog.d("video_size", "size == " + size.with + ", " + size.height + ", " + radio);
                                        // 设置显示区比例
                                        finalShareScreenVideoView.setRadio(radio);
                                    }
                                }
                            });
                            VideoViewManager.getInstance().setShareScreenVideoView(shareScreenRtcVideoView);
                        }
                        if (!shareScreenRtcVideoView.isBindVideo()) {
                            subscribeScreen(userId, shareScreenRtcVideoView);
                        }
                    }

                }

                // 通知布局刷新
                if (classVideoListAdapter != null) { // 通知布局重写加载订阅
                    List<String> userIds = new ArrayList<>();
                    for (StreamResource resource : resources) {
                        userIds.add(resource.userId);
                    }
                    refershUserVideoView(userIds);
                }
            }
        });

        // 有新用户加入音视频房间
        classViewModel.getVideoAddedUser().observe(this, new Observer<StreamResource>() {
            @Override
            public void onChanged(final StreamResource resource) {
                if (classViewModel.getGongGe()) {
                    return;
                }
                //只管创建视频videoview， 并订阅音频流， 不管布局加载和视频流的订阅
                String userId = resource.userId;
                createVideoView(userId);
                RadioRtcVideoView videoView = VideoViewManager.getInstance().get(userId);

                ScreenDisplay screenDisplay = classViewModel.getDisplay().getValue();

                if (null != screenDisplay && !TextUtils.isEmpty(screenDisplay.getUserId()) && screenDisplay.getUserId().equals(userId) && resource.isHasVideo) {
                    classViewModel.setDisplay(classViewModel.getDisplayWithClassMember(screenDisplay));
                }

                // 非动态订阅视频
                // 人员一加入就立即订阅
                //只管创建视频videoview， 并订阅音视频流， 不管布局加载
                if (resource.isHasVideo && resource.isHasScreen) {
                    if (!videoView.isBindVideo()) {
                        videoView.setBindVideo(true); // 标记已经绑定了流
                        RadioRtcVideoView shareScreenVideoView = VideoViewManager.getInstance().getShareScreenVideoView();
                        if (shareScreenVideoView != null && !shareScreenVideoView.isBindVideo()) {
                            subscribe(userId, videoView, shareScreenVideoView);
                        } else {
                            subscribe(userId, videoView);
                        }
                    }
                } else if (resource.isHasVideo) {
                    if (!videoView.isBindVideo()) {
                        videoView.setBindVideo(true); // 标记已经绑定了流
                        subscribe(userId, videoView);
                    }
                } else if (resource.isHasScreen) {
                    RadioRtcVideoView shareScreenRtcVideoView = VideoViewManager.getInstance().getShareScreenVideoView();
                    if (shareScreenRtcVideoView == null) {
                        shareScreenRtcVideoView = new RadioRtcVideoView(getActivity());
                        final RadioRtcVideoView finalShareScreenVideoView = shareScreenRtcVideoView;
                        shareScreenRtcVideoView.setOnSizeChangedListener(new RCRTCVideoView.OnSizeChangedListener() {
                            @Override
                            public void onChanged(RCRTCVideoView.Size size) {
                                if (size != null) {
                                    float radio = (float) size.with / (float) size.height;
                                    SLog.d("video_size", "size == " + size.with + ", " + size.height + ", " + radio);
                                    finalShareScreenVideoView.setRadio(radio);
                                }
                            }
                        });
                        VideoViewManager.getInstance().setShareScreenVideoView(shareScreenRtcVideoView);
                    }
                    if (!shareScreenRtcVideoView.isBindVideo()) {
                        subscribeScreen(userId, shareScreenRtcVideoView);
                    }
                }

                List<String> userIds = new ArrayList<>();
                userIds.add(userId);
                if (classVideoListAdapter != null) { // 通知布局重写加载订阅
                    refershUserVideoView(userIds);
                }
                //                ScreenDisplay display = classViewModel.getDisplay().getValue();
                //                if (display != null) {
                //                    classViewModel.switchDisplay(roomId, display.getType(), display.getUserId(), false);
                //                }
            }
        });

        // 有用户退出音视频房间
        classViewModel.getVideoRemovedUser().observe(this, new Observer<StreamResource>() {
            @Override
            public void onChanged(StreamResource resource) {
                if (classViewModel.getGongGe()) {
                    return;
                }
                SLog.d(SLog.TAG_RTC, "Video User remove, userId = " + resource);
                // 加入音视频离开， 则取消音视频的订阅， 并清理 VideoView。 视频列表布局由 成员列表控制刷新
                if (!resource.isHasVideo && !resource.isHasAudio) {
                    unSubscribe(resource.userId);
                    removeVideoView(resource.userId);
                } else if (!resource.isHasScreen) {
                    VideoViewManager.getInstance().getShareScreenVideoView().setBindVideo(false);
                    unSubscribeScreen(resource.userId);
                }
            }
        });

        // 视频用户列表
        classViewModel.getVideoMembersList().observe(this, new Observer<VideoClassMemberData>() {
            @Override
            public void onChanged(VideoClassMemberData videoClassMemberData) {
                if (classViewModel.getGongGe() && !videoClassMemberData.isRefreshData()) {
                    updateList(videoClassMemberData.getMember(), videoClassMemberData.isNoUpdate(), false);
                    return;
                }
                if (userInfoValue != null && !videoClassMemberData.isRefreshData()) {
                    updateList(videoClassMemberData.getMember(), videoClassMemberData.isNoUpdate(), true);
                } else {
                    SLog.e(TAG_VIDEO_VIEW, " Members List, userinfo is" + userInfoValue + videoClassMemberData.isRefreshData() + " no update list ");
                }
            }
        });

        // 设备状态变化
        classViewModel.getDeviceChange().observe(this, new Observer<DeviceChange>() {
            @Override
            public void onChanged(DeviceChange deviceChange) {
                if (classViewModel.getGongGe()) {
                    return;
                }
                RadioRtcVideoView videoView = VideoViewManager.getInstance().get(deviceChange.userId);
                if (deviceChange.deviceType == DeviceType.Camera && videoView != null) {
                    if (!deviceChange.isEnable) {
                        // 清了最后一帧
                        videoView.setAllowRenderer(false);
                        videoView.clearScreen();
                    } else {
                        videoView.setAllowRenderer(true);
                    }
                }
            }
        });

    }

    // 创建 VideoView
    private void createVideoView(String userId) {
        if (!VideoViewManager.getInstance().containsKey(userId)) {
            RadioRtcVideoView videoView = new RadioRtcVideoView(getContext());
            VideoViewManager.getInstance().put(userId, videoView);
        }
    }

    // 移除videoView
    private void removeVideoView(String userId) {
        if (VideoViewManager.getInstance().containsKey(userId)) {
            RadioRtcVideoView remoteVideoView = VideoViewManager.getInstance().remove(userId);
            remoteVideoView.setBindVideo(false);
            remoteVideoView.clearScreen();

        }
    }


    // 视频订阅
    private synchronized void subscribeVideo(String userId, final RadioRtcVideoView videoView) {
        if (classViewModel != null) {
            classViewModel.subscribeVideo(userId, videoView).observe(this, new Observer<RequestState>() {
                @Override
                public void onChanged(RequestState requestState) {
                    if (requestState.getState() == RequestState.State.FAILED) {
                        videoView.setBindVideo(false);
                        ToastUtils.showToast("远端资源获取失败");
                    }
                }
            });
        }
    }

    // 取消订阅视频
    private synchronized void unSubscribeVideo(String userId) {
        if (classViewModel != null) {
            classViewModel.unSubscribeVideo(userId);
        }
    }

    // 音频订阅
    private synchronized void subscribeAudio(String userId) {
        if (classViewModel != null) {
            classViewModel.subscribeAudio(userId);
        }
    }

    // 取消音频订阅
    private synchronized void unSubscribeAudio(String userId) {
        if (classViewModel != null) {
            classViewModel.unSubscribeAudio(userId);
        }
    }

    // 订阅
    private synchronized void subscribe(String userId, final RadioRtcVideoView videoView) {
        if (classViewModel != null) {
            classViewModel.subscribeResource(userId, videoView).observe(this, new Observer<RequestState>() {
                @Override
                public void onChanged(RequestState requestState) {
                    if (requestState.getState() == RequestState.State.FAILED) {
                        videoView.setBindVideo(false);
                        ToastUtils.showToast("远端资源获取失败");
                    } else if (requestState.getState() == RequestState.State.SUCCESS) {
                        SLog.d(TAG_VIDEO_VIEW, "Update list item, subVideo , has video view in layout: " + videoView.isHasParent() + ", videoview = " + videoView);
                    }
                }
            });
        }
    }

    // 订阅
    private synchronized void subscribe(String userId, final RadioRtcVideoView videoView, RadioRtcVideoView screenShareView) {
        if (classViewModel != null) {
            classViewModel.subscribeResource(userId, videoView, screenShareView).observe(this, new Observer<RequestState>() {
                @Override
                public void onChanged(RequestState requestState) {
                    if (requestState.getState() == RequestState.State.FAILED) {
                        videoView.setBindVideo(false);
                        ToastUtils.showToast("远端资源获取失败");
                    } else if (requestState.getState() == RequestState.State.SUCCESS) {
                        SLog.d(TAG_VIDEO_VIEW, "Update list item, subVideo , has video view in layout: " + videoView.isHasParent() + ", videoview = " + videoView);
                    }
                }
            });
        }
    }

    // 取消订阅
    private synchronized void unSubscribe(String userId) {
        if (classViewModel != null) {
            classViewModel.unSubscribeResource(userId);
        }
    }

    // 订阅共享桌面
    private void subscribeScreen(String userId, final RadioRtcVideoView videoView) {
        if (classViewModel != null) {
            classViewModel.subscribeScreen(userId, videoView).observe(this, new Observer<RequestState>() {
                @Override
                public void onChanged(RequestState requestState) {
                    if (requestState.getState() == RequestState.State.FAILED) {
                        videoView.setBindVideo(false);
                        ToastUtils.showToast("远端资源获取失败");
                    } else if (requestState.getState() == RequestState.State.SUCCESS) {

                    }
                }
            });
        }

    }

    // 取消订阅共享桌面
    private void unSubscribeScreen(String userId) {
        if (classViewModel != null) {
            classViewModel.unSubscribeScreen(userId);
        }
    }

    private LinearLayout.LayoutParams getItemLayoutParams() {
        //        int width = DisplayUtils.dip2px(getContext(), Math.round(84 * 1.333));
        //        int height = DisplayUtils.dip2px(getContext(), 84);
        //        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        return params;
    }


    /**
     * 刷新 listView ， 其他布局联动视频列表更新
     *
     * @param member
     */
    public void refershUserVideoView(ClassMember member) {
        if (classVideoListAdapter != null && member != null) {
            List<String> userIds = new ArrayList<>();
            userIds.add(member.getUserId());
            classVideoListAdapter.notifyDataSetChanged(userIds);
        }
    }

    /**
     * 刷新 listView ， 其他布局联动视频列表更新
     *
     * @param userIds
     */
    public void refershUserVideoView(List<String> userIds) {
        if (classVideoListAdapter != null && userIds != null && userIds.size() > 0) {
            classVideoListAdapter.notifyDataSetChanged(userIds);
        }
    }

    /**
     * 刷新 listView ， 其他布局联动视频列表更新
     */
    public void removeUserVideoView(ClassMember member) {
        if (classVideoListAdapter != null) {
            classVideoListAdapter.removeItemSetChanged(member);
        }
    }

    /**
     * 添加已删除的item
     *
     * @param
     */
    public void addRemoveItemNotifyChanged() {
        if (classVideoListAdapter != null) {
            classVideoListAdapter.addRemoveItemNotifyChanged();
        }
    }

    /**
     * 设置 Item 点击回调
     *
     * @param listener
     */
    public void setOnVideoViewItemClickListener(OnVideoViewItemClickListener listener) {
        this.listener = listener;
    }


    /**
     * 点击监听回调
     */
    public interface OnVideoViewItemClickListener {
        void onItemClick(ClassMember member);
    }


}
