package com.tencent.gme.audio.apiexample;


import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.appcompat.app.ActionBar;
import com.gme.TMG.ITMGContext;
import com.gme.TMG.ITMGRoom;
import com.gme.av.sdk.AVError;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

public class RealTimeVoiceActivity extends BaseActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener, TMGDispatcherBase, RadioGroup.OnCheckedChangeListener {
    private static final String sRoomId = "2018060";
    private EditText mRoomIdView;
    private TextView mLogMonitorView;
    private RadioGroup mRoomTypeView;
    private SurfaceView mGlSurView;
    private CheckBox mEnableMicView;
    private CheckBox mEnableSpeakerView;
    private ScrollView mLogHostView;

    private Map<String, TagUserInfo> mMapUserInfo = new HashMap<>();

    private static class TagUserInfo
    {
        public boolean listen;
        public String name;
        public int volume;
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_real_time_voice);

        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setTitle("Real Time Voice");
        }

        initViews();
        mRoomIdView.setText(sRoomId);
        mRoomTypeView.check(R.id.rbRoomType1);
        TMGCallbackDispatcher.getInstance().registerSubDispatcher(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ITMGContext.GetInstance(this).ExitRoom();
        TMGCallbackDispatcher.getInstance().unregisterSubDispatcher(this);
    }

    private void initViews() {
        findViewById(R.id.ll_root).setOnClickListener(this);
        findViewById(R.id.btnEnterRoom).setOnClickListener(this);
        findViewById(R.id.btnExitRoom).setOnClickListener(this);
        findViewById(R.id.btnClear).setOnClickListener(this);
        findViewById(R.id.rbRoomType1).setOnClickListener(this);
        findViewById(R.id.rbRoomType2).setOnClickListener(this);
        findViewById(R.id.rbRoomType3).setOnClickListener(this);
        mEnableMicView = findViewById(R.id.checkEnableMic);
        mEnableSpeakerView = findViewById(R.id.checkEnableSpeaker);
        mEnableMicView.setOnCheckedChangeListener(this);
        mEnableSpeakerView.setOnCheckedChangeListener(this);
        mRoomIdView = findViewById(R.id.etRoomId);
        mRoomTypeView = findViewById(R.id.rgRoomType);
        mRoomTypeView.setOnCheckedChangeListener(this);
        mLogMonitorView = findViewById(R.id.tv_Monitor);
        mLogHostView = findViewById(R.id.sv_host);
    }

    @Override
    public void onClick(View v) {
        final int id = v.getId();
        if (id == R.id.btnEnterRoom)
        {
            onEnterRoomClick();
        }else if(id == R.id.btnExitRoom)
        {
            onExitRoomClick();
        }else if (id == R.id.btnClear)
        {
            mLogMonitorView.setText("");
        }else if (id == R.id.rbRoomType1)
        {
            ITMGContext.GetInstance(this).GetRoom().ChangeRoomType(1);
        }else if(id == R.id.rbRoomType2)
        {
            ITMGContext.GetInstance(this).GetRoom().ChangeRoomType(2);
        }else if (id == R.id.rbRoomType3)
        {
            ITMGContext.GetInstance(this).GetRoom().ChangeRoomType(3);
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {

    }

    private void onEnterRoomClick() {
        String roomId = mRoomIdView.getText().toString().trim();
        if (TextUtils.isEmpty(roomId))
        {
            showToast("please input roomId");
            return;
        }

        int roomTypeCheckId = mRoomTypeView.getCheckedRadioButtonId();
        int roomType = 1;
        if (roomTypeCheckId == R.id.rbRoomType1)
        {
            roomType = 1;
        }else if (roomTypeCheckId == R.id.rbRoomType2)
        {
            roomType = 2;
        }else if (roomTypeCheckId == R.id.rbRoomType3)
        {
            roomType = 3;
        }

        byte[] authBuffer =  GMEAuthBufferHelper.getInstance().createAuthBuffer(roomId);

        // Step 5/11 enter room, then you need handle ITMG_MAIN_EVENT_TYPE_ENTER_ROOM,ITMG_MAIN_EVNET_TYPE_USER_UPDATE
        // and ITMG_MAIN_EVENT_TYPE_ROOM_DISCONNECT event
        // https://cloud.tencent.com/document/product/607/15210#.3Ca-id.3D.22enterroom.22.3E.E5.8A.A0.E5.85.A5.E6.88.BF.E9.97.B4.3C.2Fa.3E
        ITMGContext.GetInstance(this).EnterRoom(roomId, roomType, authBuffer);
    }

    private void onExitRoomClick() {
        // Step 10/11 exit room
        // 这里需要处理 ITMG_MAIN_EVENT_TYPE_EXIT_ROOM 事件
        // https://cloud.tencent.com/document/product/607/15210#.3Ca-id.3D.22exitroom.22.3E.E9.80.80.E5.87.BA.E6.88.BF.E9.97.B4.3C.2Fa.3E
        ITMGContext.GetInstance(this).ExitRoom();
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        ITMGContext gmeContext = ITMGContext.GetInstance(this);
        final int id = buttonView.getId();
        if (id == R.id.checkEnableMic)
        {
            // Step 8/11 enable to capture audio and send to server
            // https://cloud.tencent.com/document/product/607/15210#.3Ca-id.3D.22enablemic.22.3E.E5.BC.80.E5.90.AF.E6.88.96.E5.85.B3.E9.97.AD.E9.BA.A6.E5.85.8B.E9.A3.8E.3C.2Fa.3E
            int ret = gmeContext.GetAudioCtrl().EnableMic(isChecked);
        } else if (id == R.id.checkEnableSpeaker) {
            // Step 9/11 enable to capture audio and send to server
            // https://cloud.tencent.com/document/product/607/15210#.3Ca-id.3D.22enablespeaker.22.3E.E5.BC.80.E5.90.AF.E6.88.96.E5.85.B3.E9.97.AD.E6.89.AC.E5.A3.B0.E5.99.A8.3C.2Fa.3E
            gmeContext.GetAudioCtrl().EnableSpeaker(isChecked);
        }
    }

    @Override
    public void OnEvent(ITMGContext.ITMG_MAIN_EVENT_TYPE type, Intent data) {

        if (type == ITMGContext.ITMG_MAIN_EVENT_TYPE.ITMG_MAIN_EVENT_TYPE_ENTER_ROOM)
        {
            // Step 6/11 : Perform the enter room event
            int nErrCode = TMGCallbackHelper.ParseIntentParams2(data).nErrCode;
            String strMsg = TMGCallbackHelper.ParseIntentParams2(data).strErrMsg;
            if (nErrCode == AVError.AV_OK)
            {
                appendLog2MonitorView("EnterRomm success");
            }else
            {
                appendLog2MonitorView(String.format(Locale.getDefault(), "EnterRoom errCode:%d errMsg:%s",
                        nErrCode, strMsg));
            }
        }else if (type == ITMGContext.ITMG_MAIN_EVENT_TYPE.ITMG_MAIN_EVNET_TYPE_USER_UPDATE)
        {
            // Step 7/11 : User in the room has new state, such as turn on/off microphone
            //			or new one enter/quit the room.
            //			more info please read the document.
            int nSubEvent= data.getIntExtra("event_id", 0);
            if (ITMGContext.ITMG_EVENT_ID_USER_ENTER == nSubEvent)
            {
                String[] strUsers = data.getStringArrayExtra("user_list");
                if (strUsers != null && strUsers.length > 0)
                {
                    for (int i = 0; i < strUsers.length; i++)
                    {
                        String userID = strUsers[i];
                        if (!mMapUserInfo.containsKey(userID))
                        {
                            //如果不在房间里
                            TagUserInfo userInfo = new TagUserInfo();
                            userInfo.listen = false;
                            userInfo.name = userID;
                            userInfo.volume = 0;
                            mMapUserInfo.put(userID, userInfo);
                        }
                    }
                    appendLog2MonitorView("UserUpdate complete:" + convertMapToString(mMapUserInfo));
                }
            }else if(ITMGContext.ITMG_EVENT_ID_USER_EXIT == nSubEvent)
            {
                String[] strUsers = data.getStringArrayExtra("user_list");
                if (strUsers != null && strUsers.length > 0)
                {
                    for (int i = 0; i < strUsers.length; i++)
                    {
                        String userID = strUsers[i];
                        if (mMapUserInfo.containsKey(userID))
                        {
                            //如果不在房间里
                            mMapUserInfo.remove(userID);
                        }
                    }
                }
                appendLog2MonitorView("UserUpdate complete:" + convertMapToString(mMapUserInfo));
            }
        }else if (type == ITMGContext.ITMG_MAIN_EVENT_TYPE.ITMG_MAIN_EVENT_TYPE_EXIT_ROOM)
        {
            // Step 11/11 : Perform the exit room event
            appendLog2MonitorView("ExitRomm success");
            mEnableMicView.setChecked(false);
            mEnableSpeakerView.setChecked(false);
            mRoomTypeView.check(R.id.rbRoomType1);
        }else if (type == ITMGContext.ITMG_MAIN_EVENT_TYPE.ITMG_MAIN_EVENT_TYPE_ROOM_DISCONNECT)
        {
            appendLog2MonitorView("Disconnect with server");
        }else if(type == ITMGContext.ITMG_MAIN_EVENT_TYPE.ITMG_MAIN_EVENT_TYPE_CHANGE_ROOM_TYPE)
        {
            //切换房间类型回调
            int code = data.getIntExtra("result", 0);
            String strErrInfo = data.getStringExtra("error_info");
            int nNewRoomType = data.getIntExtra("new_room_type", 0);
            int nSubEventType = data.getIntExtra("sub_event_type", 0);
            switch (nSubEventType)
            {
                case ITMGContext.ITMG_ROOM_CHANGE_EVENT_ENTERROOM:
                case ITMGContext.ITMG_ROOM_CHANGE_EVENT_COMPLETE:
                    switch (nNewRoomType){
                        case 1:
                            mRoomTypeView.check(R.id.rbRoomType1);
                            break;
                        case 2:
                            mRoomTypeView.check(R.id.rbRoomType2);
                            break;
                        case 3:
                            mRoomTypeView.check(R.id.rbRoomType3);
                            break;
                    }
                    showToast("Roomtype changed");
                    appendLog2MonitorView("ChangeRoomtype roomtype change to " + nNewRoomType);
                    break;
                default:
            }
        }
    }

    private void appendLog2MonitorView(String text)
    {
        String logText = mLogMonitorView.getText().toString();
        if (!logText.isEmpty())
        {
            logText = logText + "\n" + text;
        }else
        {
            logText = text;
        }
        mLogMonitorView.setText(logText);
        mLogHostView.fullScroll(View.FOCUS_DOWN);
    }

    public static String convertMapToString(Map<String, TagUserInfo> map) {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        Iterator<Map.Entry<String, TagUserInfo>> it = map.entrySet().iterator();
        String split = "";
        while (it.hasNext()) {
            sb.append(split);
            Map.Entry<String, TagUserInfo> entry = it.next();
            sb.append(entry.getKey());
            split = ",";
        }
        sb.append("}");
        return sb.toString();
    }
}