package ai.guiji.duix.sample.ui.activity.base;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.annotation.Nullable;

import org.webrtc.EglBase;
import org.webrtc.MediaStream;
import org.webrtc.MediaStreamTrack;
import org.webrtc.PeerConnection;
import org.webrtc.RendererCommon;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoTrack;

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

import ai.guiji.duix.sample.pojo.DUIXConfig;
import ai.guiji.duix.sample.util.DeviceUtils;
import ai.guiji.duix.sample.util.DisplayUtils;
import ai.guiji.duix.sdk.DUIXCore;
import ai.guiji.duix.sdk.DUIXFactory;
import ai.guiji.duix.sdk.Logger;
import ai.guiji.duix.sdk.callback.IDUIXListener;
import ai.guiji.duix.sdk.callback.RendererTouchListener;

public abstract class DUIXActivity extends BaseActivity {

    private boolean backPressed;
    protected String UUID;
    protected DUIXCore mDUIXCore;
    protected EglBase.Context eglBaseContext;
    protected SurfaceViewRenderer fullscreen_renderer;
    protected SurfaceViewRenderer small_renderer;
    List<VideoTrack> mVideoTracks = new ArrayList<>();  // 这里
    SurfaceViewRenderer[] sinks = new SurfaceViewRenderer[2];

    protected DUIXConfig mConfig;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestFullScreen();
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        AudioManager mAudioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
        mAudioManager.setSpeakerphoneOn(true);
        mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);

        mConfig = (DUIXConfig) getIntent().getSerializableExtra("config");
        Log.e(TAG, "read config: " + mConfig);
    }


    @SuppressLint("ClickableViewAccessibility")
    protected void initDUIX() {
        eglBaseContext = EglBase.create().getEglBaseContext();

        fullscreen_renderer.init(eglBaseContext, null);
        fullscreen_renderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
        fullscreen_renderer.setMirror(false);
        fullscreen_renderer.setEnableHardwareScaler(false);

        small_renderer.init(eglBaseContext, null);
        small_renderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
        small_renderer.setMirror(true);
        small_renderer.setEnableHardwareScaler(false);
        small_renderer.setZOrderOnTop(true);
        small_renderer.setZOrderMediaOverlay(true);

        small_renderer.setOnTouchListener(
                new RendererTouchListener(
                        new Rect(0, 0, DisplayUtils.getScreenWidth(mContext), DisplayUtils.getScreenHeight(mContext))));
        small_renderer.setOnClickListener(v -> {
            if (sinks[0] != null && sinks[1] != null && mVideoTracks.size() == 2) {
                mVideoTracks.get(0).removeSink(sinks[0]);
                mVideoTracks.get(0).removeSink(sinks[1]);
                mVideoTracks.get(1).removeSink(sinks[0]);
                mVideoTracks.get(1).removeSink(sinks[1]);
                // 交换输出
                SurfaceViewRenderer tmp = sinks[0];
                sinks[0] = sinks[1];
                sinks[1] = tmp;

                sinks[0].setMirror(true);
                sinks[1].setMirror(false);
                mVideoTracks.get(0).addSink(sinks[0]);
                mVideoTracks.get(1).addSink(sinks[1]);
            }
        });

        sinks[0] = small_renderer;
        sinks[1] = fullscreen_renderer;
        sinks[0].setMirror(true);
        sinks[1].setMirror(false);

        mDUIXCore = DUIXFactory.getDUIX();
        mDUIXCore.addDUIXListener(mDUIXCallback);
        String deviceId = "endpoint_android_" + DeviceUtils.getUUID(mContext);
        DUIXFactory.IMOptions imOptions = new DUIXFactory.IMOptions(deviceId)
                .setImHost(mConfig.getHost())
                .setImPort(mConfig.getPort())
                .setDebugger(false)
                .setImUserJID(mConfig.getJID());
        mDUIXCore.connect(mContext, imOptions);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        for (VideoTrack track : mVideoTracks) {
            track.removeSink(sinks[0]);
            track.removeSink(sinks[1]);
        }
        if (fullscreen_renderer != null) {
            fullscreen_renderer.release();
        }
        if (small_renderer != null) {
            small_renderer.release();
        }
        if (mDUIXCore != null) {
            if (UUID != null) {
                mDUIXCore.closeSession(UUID);
            }
            mDUIXCore.removeDUIXListener(mDUIXCallback);
            mDUIXCore.release();
        }
    }

    protected abstract void connected();

    protected abstract void busy();

    protected abstract void renderState(String state, String dataJson);

    protected abstract void connectError(String msg);

    protected abstract void detectedSpeech(String asrText);

    protected abstract void iceConnectionChange(PeerConnection.IceConnectionState iceConnectionState);

    protected abstract void command(String type, String flowId, String nodeId);


    IDUIXListener mDUIXCallback = new IDUIXListener() {
        @Override
        public void onIMConnected() {
            connected();
        }

        @Override
        public void onIMConnectFail(String msg) {
            connectError(msg);
        }

        @Override
        public void onBusy() {
            // 显示Busy窗口
            busy();
        }

        @Override
        public void onRender(String id, String name) {
            Logger.e("onRender id: " + id + "  name: " + name);
        }

        @Override
        public void onRenderState(String state, String dataJson) {
            Logger.e("onRenderState: " + dataJson);
            renderState(state, dataJson);
        }

        @Override
        public void onCommand(String type, String flowId, String nodeId, String json) {
//            Logger.e("onCommand: " + type);
            command(type, flowId, nodeId);
        }

        @Override
        public void available() {
            if (mDUIXCore != null) {
                mDUIXCore.pingSession();
            }
        }

        @Override
        public void onByeBye(String uuid, int code, String reason) {
            Logger.e("ByeBye!");
            closeSession(reason);
        }

        @Override
        public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
            iceConnectionChange(iceConnectionState);
        }

        @Override
        public void onDetectedSpeech(String asrText) {
            detectedSpeech(asrText);
        }

        @Override
        public void onAddTrack(MediaStreamTrack track, MediaStream[] mediaStreams) {
            if (track instanceof VideoTrack) {
                // show local renderer
                VideoTrack localVideo = mDUIXCore.getLocalVideoTrack();
                if (localVideo != null) {
                    localVideo.addSink(small_renderer);
                    mVideoTracks.add(localVideo);
                }
                VideoTrack remoteVideoTrack = (VideoTrack) track;
                remoteVideoTrack.addSink(fullscreen_renderer);
                mVideoTracks.add(remoteVideoTrack);
            }
        }
    };


    protected void closeSession(String msg) {
        runOnUiThread(() -> {
            if (!isFinishing() && !backPressed) {
                backPressed = true;
                if (msg != null && !"".equals(msg)) {
                    Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
                }
                if (UUID != null && mDUIXCore != null) {
                    mDUIXCore.closeSession(UUID);
                }
                mHandler.postDelayed(() -> {
                    if (!isFinishing()) {
                        finish();
                    }
                }, 1000);
            }
        });
    }
}
