package com.mogo.cloud.trafficlive.core;

import static com.mogo.cloud.live.constant.LiveConstant.LIVE_TYPE_CLOSE;
import static com.mogo.cloud.live.constant.LiveConstant.LIVE_TYPE_OPEN;
import static com.mogo.cloud.trafficlive.constant.TrafficLiveConstant.TAG;

import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import android.view.TextureView;

import com.mogo.cloud.live.listener.ILiveMultiRoomStatusListener;
import com.mogo.cloud.live.listener.ILiveProgressListener;
import com.mogo.cloud.live.listener.ILivePullStateListener;
import com.mogo.cloud.live.listener.IRequestLiveListener;
import com.mogo.cloud.live.manager.MoGoLiveManager;
import com.mogo.cloud.live.manager.MoGoLivePushConfig;
import com.mogo.cloud.live.manager.RequestLiveManager;
import com.mogo.cloud.passport.MoGoAiCloudClient;
import com.mogo.cloud.trafficlive.api.ITrafficCarLiveCallBack;
import com.mogo.cloud.trafficlive.api.ITrafficIntersectionLiveCallBack;

public class TrafficLiveCurrentManager
        implements ILiveProgressListener, ILiveMultiRoomStatusListener {

    private static volatile TrafficLiveCurrentManager mInstance;
    private final RequestLiveManager requestLiveManager;
    private ITrafficCarLiveCallBack trafficLiveCallBack;

    private TrafficLiveCurrentManager() {
        requestLiveManager = RequestLiveManager.getInstance();
    }

    public static TrafficLiveCurrentManager getInstance() {
        if (mInstance == null) {
            synchronized (TrafficLiveCurrentManager.class) {
                if (mInstance == null) {
                    mInstance = new TrafficLiveCurrentManager();
                    MoGoLiveManager.getInstance().addLiveProgressListener(mInstance);
                }
            }
        }
        return mInstance;
    }

    public boolean isCarOnLive() {
        return MoGoLiveManager.getInstance().getLiveStatusModel().isPlaying();
    }

    public void viewFrontVehicleLive(double lat, double lon, int bearing, SurfaceView surfaceView, ITrafficCarLiveCallBack callBack) throws Exception {
        if (callBack == null) {
            throw new Exception("ITrafficLiveCallBack can not be null");
        }
        if (surfaceView == null) {
            throw new Exception("SurfaceView can not be null");
        }
        if (lat == 0.0 || lon == 0.0) {
            throw new Exception("param lat and lon can not be 0.0f");
        }
        if (bearing < 0) {
            throw new Exception("param bearing can not less than 0");
        }

        this.trafficLiveCallBack = callBack;
        requestLiveManager.requestFrontVehicleLive(lat, lon, bearing, new IRequestLiveListener() {
            @Override
            public void onSuccess(String liveSn, double lat, double lon) {
                onVehicleLiveSuccess(liveSn, surfaceView);
            }

            @Override
            public void onError(Throwable e) {
                onVehicleLiveError(e.getMessage());
            }
        });
    }

    public void viewDesignativeVehicleLive(String liveSn, TextureView textureView, ITrafficCarLiveCallBack callBack) throws Exception {
        if (callBack == null) {
            throw new Exception("ITrafficLiveCallBack can not be null");
        }
        if (textureView == null) {
            throw new Exception("SurfaceView can not be null");
        }
        if (TextUtils.isEmpty(liveSn)) {
            throw new Exception("liveSn can not be null");
        }

        this.trafficLiveCallBack = callBack;
        requestLiveManager.requestDesignativeVehicleLive(LIVE_TYPE_OPEN, liveSn, new IRequestLiveListener() {
            @Override
            public void onSuccess() {
                onVehicleLiveSuccess(liveSn, textureView);
            }

            @Override
            public void onError(Throwable e) {
                onVehicleLiveError(e.getMessage());
            }
        });
    }

    public void viewDesignativeVehicleLive(String liveSn, SurfaceView surfaceView, ITrafficCarLiveCallBack callBack) throws Exception {
        if (callBack == null) {
            throw new Exception("ITrafficLiveCallBack can not be null");
        }
        if (surfaceView == null) {
            throw new Exception("SurfaceView can not be null");
        }
        if (TextUtils.isEmpty(liveSn)) {
            throw new Exception("liveSn can not be null");
        }

        this.trafficLiveCallBack = callBack;
        requestLiveManager.requestDesignativeVehicleLive(LIVE_TYPE_OPEN, liveSn, new IRequestLiveListener() {
            @Override
            public void onSuccess() {
                onVehicleLiveSuccess(liveSn, surfaceView);
            }

            @Override
            public void onError(Throwable e) {
                onVehicleLiveError(e.getMessage());
            }
        });
    }


    private void onVehicleLiveSuccess(String liveSn, SurfaceView surfaceView) {
        if (TextUtils.isEmpty(liveSn)) {
            if (TrafficLiveCurrentManager.this.trafficLiveCallBack != null) {
                TrafficLiveCurrentManager.this.trafficLiveCallBack.onError("There are no live vehicles ahead !");
            } else {
                Log.e(TAG, "onVehicleLiveSuccess , but result liveSn is null");
            }
            return;
        }
        String sn = MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn();
        // 初始化配置文件
        MoGoLivePushConfig mLivePushConfig = MoGoLivePushConfig.getInstance();
        // 自己对sn
        mLivePushConfig.setDevicesId(sn);
        // 登录要查看的SN房间
        MoGoLiveManager.getInstance().loginMultiRoom(liveSn);
        MoGoLiveManager.getInstance().addLivePullStateListener(mediaPlayerStateListener);
        // 直接 查看对应SN的直播
        MoGoLiveManager.getInstance().startLive(surfaceView);
        if (TrafficLiveCurrentManager.this.trafficLiveCallBack != null) {
            TrafficLiveCurrentManager.this.trafficLiveCallBack.onLive(liveSn);
        }
    }

    private void onVehicleLiveSuccess(String liveSn, TextureView textureView) {
        if (TextUtils.isEmpty(liveSn)) {
            if (TrafficLiveCurrentManager.this.trafficLiveCallBack != null) {
                TrafficLiveCurrentManager.this.trafficLiveCallBack.onError("There are no live vehicles ahead !");
            } else {
                Log.e(TAG, "onVehicleLiveSuccess , but result liveSn is null");
            }
            return;
        }
        String sn = MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn();
        // 初始化配置文件
        MoGoLivePushConfig mLivePushConfig = MoGoLivePushConfig.getInstance();
        mLivePushConfig.setDevicesId(sn);
        // 登录要查看的SN房间
        MoGoLiveManager.getInstance().loginMultiRoom(liveSn);
        MoGoLiveManager.getInstance().addLivePullStateListener(mediaPlayerStateListener);
        // 直接 查看对应SN的直播
        MoGoLiveManager.getInstance().startLive(textureView);
        if (TrafficLiveCurrentManager.this.trafficLiveCallBack != null) {
            TrafficLiveCurrentManager.this.trafficLiveCallBack.onLive(liveSn);
        }
    }

    private void onVehicleLiveError(String errorMsg) {
        if (TrafficLiveCurrentManager.this.trafficLiveCallBack != null) {
            TrafficLiveCurrentManager.this.trafficLiveCallBack.onError(errorMsg);
        }
    }

    public void stopCarLive(String liveSn) {
        requestLiveManager.requestDesignativeVehicleLive(LIVE_TYPE_CLOSE, liveSn, new IRequestLiveListener() {
            @Override
            public void onSuccess() {
            }

            @Override
            public void onError(Throwable e) {
                if (trafficLiveCallBack != null) {
                    trafficLiveCallBack.onError(e.getMessage());
                }
            }
        });
        MoGoLiveManager.getInstance().stopLive(liveSn);
        trafficLiveCallBack = null;
    }

    public void viewFrontIntersectionLive(double lat, double lon, int bearing, ITrafficIntersectionLiveCallBack callBack) throws Exception {
        if (lat == 0.0 || lon == 0.0) {
            throw new Exception("param lat and lon can not be 0.0f");
        }
        if (bearing < 0) {
            throw new Exception("param bearing can not less than 0");
        }
        requestLiveManager.requestFrontIntersectionLive(lat, lon, bearing, new IRequestLiveListener() {
            @Override
            public void onSuccess(String liveUrl) {
                callBack.liveUrlResult(liveUrl);
            }

            @Override
            public void onError(Throwable e) {
                callBack.onError(e.getMessage());
            }
        });
    }

    public void viewDesignativeIntersectionLive(String cameraId, ITrafficIntersectionLiveCallBack callBack) throws Exception {
        if (TextUtils.isEmpty(cameraId)) {
            throw new Exception("param cameraId can not be null");
        }
        requestLiveManager.requestDesignativeIntersectionLive(cameraId, new IRequestLiveListener() {
            @Override
            public void onSuccess(String liveUrl) {
                callBack.liveUrlResult(liveUrl);
            }

            @Override
            public void onError(Throwable e) {
                callBack.onError(e.getMessage());
            }
        });
    }

    @Override
    public void onEngineStart() {

    }

    @Override
    public void onEngineStop() {

    }

    @Override
    public void onDebugError(int errorCode, String funcName, String errorInfo) {
        Log.e(TAG, "onDebugError errorCode : " + errorCode + "  funcName : " + funcName + "  errorInfo : " + errorInfo);
        if (trafficLiveCallBack != null) {
            trafficLiveCallBack.onError(errorInfo);
        }
    }

    @Override
    public void onMultiRoomConnecting() {
        if (trafficLiveCallBack != null) {
            trafficLiveCallBack.onLiveConnecting();
        }
    }

    @Override
    public void onMultiRoomConnected() {
        if (trafficLiveCallBack != null) {
            trafficLiveCallBack.onLiveConnected();
        }
    }

    @Override
    public void onMultiRoomDisconnected() {
        if (trafficLiveCallBack != null) {
            trafficLiveCallBack.onDisConnect();
        }
    }

    private ILivePullStateListener mediaPlayerStateListener = new ILivePullStateListener() {
        @Override
        public void onVideoFirstFrame() {
            if (trafficLiveCallBack != null) {
                trafficLiveCallBack.onFirstFrame();
            }
        }

        @Override
        public void onPlayerStateUpdate(int statusCode) {
            if (trafficLiveCallBack != null) {
                switch (statusCode) {
                    case 0: {
                        trafficLiveCallBack.onError("onPullStreamError：");
                        break;
                    }
                    case 1: {
                        trafficLiveCallBack.onPlaRequesting();
                        break;
                    }
                    case 2: {
                        trafficLiveCallBack.onPlaying();
                        break;
                    }
                }
            }
        }


        @Override
        public void onDeviceError(int errorCode) {
            if (trafficLiveCallBack != null) {
                trafficLiveCallBack.onError("onDeviceError：" + errorCode);
            }
        }
    };
}
