package com.navinfo.outdoor.activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.github.lazylibrary.util.DensityUtil;
import com.github.lazylibrary.util.FileUtils;
import com.navinfo.outdoor.R;
import com.navinfo.outdoor.api.Constant;
import com.navinfo.outdoor.base.BaseActivity;
import com.navinfo.outdoor.util.AWMp4ParserHelper;
import com.navinfo.outdoor.util.MyTecentLocationSource;
import com.otaliastudios.cameraview.CameraException;
import com.otaliastudios.cameraview.CameraListener;
import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.CameraView;
import com.otaliastudios.cameraview.FileCallback;
import com.otaliastudios.cameraview.PictureResult;
import com.otaliastudios.cameraview.VideoResult;
import com.otaliastudios.cameraview.controls.Engine;
import com.otaliastudios.cameraview.controls.Mode;
import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.SizeSelector;
import com.otaliastudios.cameraview.size.SizeSelectors;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
import com.tencent.tencentmap.mapsdk.maps.MapView;
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
import com.tencent.tencentmap.mapsdk.maps.UiSettings;
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
import com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static com.navinfo.outdoor.R.drawable.location;
import static com.tencent.tencentmap.mapsdk.maps.model.MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE;

public class PicturesActivity extends BaseActivity implements View.OnClickListener {
    private static final CameraLogger LOG = CameraLogger.create("Picture");
    private CameraView camera;
    private long captureTime = 0;
    private android.widget.Button btnSwitch;
    private TencentMap tencentMap;
    private MyLocationStyle locationStyle;
    private TextureMapView ivMap;
    private CheckBox captureVideo; // 拍摄视频
    private Button btnVideo, stopVideo;

    private String finalVideoPath; // 摄像后最终保存的文件名
    private File tmpFile; // 合并文件的临时文件路径
    private Timer timer;
    private CsvTimerTask timerTask; // 执行定时写入csv文件的task
    private DateFormat formatter;
    private final long period = 1; // 记录csv文件的间隔时间，单位为秒
    private ViewGroup layerChange; // 切换地图和相机的父控件
    private boolean isFinishActivity = false; // 是否需要关闭当前activity


    @Override
    protected int getLayout() {
        EventBus.getDefault().register(this);
        tmpFile = new File(Constant.PICTURE_FOLDER, "temp.mp4");
        formatter = new SimpleDateFormat("yyyyMMdd HHmmss");
        return R.layout.activity_pictures;
    }

    @Override
    protected void initView() {
        super.initView();

        if (getIntent()!=null) {
            finalVideoPath = getIntent().getStringExtra(Constant.INTENT_VIDEO_PATH);
        }
        if (finalVideoPath == null) {
            finalVideoPath = Constant.PICTURE_FOLDER+"/final.mp4";
        }

        layerChange = findViewById(R.id.layer_change);

        timer = new Timer();

       // this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        ivMap = (TextureMapView) findViewById(R.id.iv_map);
        btnSwitch = (Button) findViewById(R.id.btn_switch);
        btnSwitch.setOnClickListener(this::onClick);
//        capturePicture = (ImageButton) findViewById(R.id.capturePicture);
//        capturePicture.setOnClickListener(this::onClick);
        //相机记录器
        CameraLogger.setLogLevel(CameraLogger.LEVEL_VERBOSE);
        camera = findViewById(R.id.camera);
        camera.setOnClickListener(this::onClick);
        captureVideo = findViewById(R.id.capuretVideo);
        captureVideo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) { // 开始采集，设置按钮文字内容为“结束采集”
                    captureVideo.setText("暂停采集");
//                    stopVideo.setEnabled(false);// 开始采集视频后，禁用停止采集的按钮，必须暂停采集后才可点击停止采集
                    startTakenVideo(); // 开始采集视频
                } else {
                    stopTakenVideo();
                    captureVideo.setText("开始采集");
                }
            }
        });

        stopVideo = findViewById(R.id.btn_stop_video);
        stopVideo.setOnClickListener(this::onClick);
        //拍照权限
        camera.setLifecycleOwner(this);
        camera.setEngine(Engine.CAMERA1);
//        camera.setVideoBitRate(5);
        camera.setPreviewFrameRate(5); // 设置预览视频的帧率


        // 设置视频可用的宽高size
        SizeSelector width = SizeSelectors.maxWidth(1920);
        SizeSelector height = SizeSelectors.maxHeight(1440);
        SizeSelector dimensions = SizeSelectors.and(width, height); // Matches sizes bigger than 1000x2000.
        // 获取屏幕信息
        int[] density = DensityUtil.getDeviceInfo(this);
        int x=1920, y=1440;
        if (density!=null&&density.length>1) {
            x = (density[0]>=density[1]?density[0]:density[1]);
            y = (density[0]>=density[1]?density[1]:density[0]);
        }
        SizeSelector ratio = SizeSelectors.aspectRatio(AspectRatio.of(x, y), 0); // Matches 1:1 sizes.

        SizeSelector result = SizeSelectors.or(
                SizeSelectors.and(ratio, dimensions), // Try to match both constraints
                ratio, // If none is found, at least try to match the aspect ratio
                SizeSelectors.biggest() // If none is found, take the biggest
        );
        camera.setVideoSize(result);
        camera.setVideoBitRate(1920*1440);
//        camera.setAudioBitRate();

        //获取地图
        tencentMap = ivMap.getMap();
        //获取地图UI 设置对象
        UiSettings uiSettings = tencentMap.getUiSettings();
        //设置logo的大小
        uiSettings.setLogoScale(0.7f);
//        uiSettings.setAllGesturesEnabled(false);
        setLocMarkerStyle(); // 设置当前位置显示样式

//        camera.addFrameProcessor(new FrameProcessor() {
//            @Override
//            public void process(@NonNull Frame frame) {
//                Log.e("PictureActivity", frame.getTime()+"");
//            }
//        });

        //相机预览监听
        camera.addCameraListener(new CameraListener() {
            @Override
            public void onPictureTaken(@NonNull @NotNull PictureResult result) {
                super.onPictureTaken(result);
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(System.currentTimeMillis());
                String format = formatter.format(calendar.getTime());
                //文件
                File file = new File(Constant.PICTURE_FOLDER, format + ".jpg");
                result.toFile(file, new FileCallback() {
                    @Override
                    public void onFileReady(@Nullable @org.jetbrains.annotations.Nullable File file) {
                        Toast.makeText(PicturesActivity.this, "保存成功:" + file.getPath(), Toast.LENGTH_SHORT).show();
                    }
                });
                if (camera.isTakingVideo()) {
                    message("Captured while taking video. Size=" + result.getSize(), false);
                }
                long callbackTime = System.currentTimeMillis();
                captureTime = callbackTime - 300;
                Log.d("captureTime", captureTime + "");
            }

            //录像监听
            @Override
            public void onVideoTaken(@NonNull @NotNull VideoResult result) {
                super.onVideoTaken(result);
                Toast.makeText(PicturesActivity.this, "暂停摄像", Toast.LENGTH_SHORT).show();
                showLoadingDialog();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if (result!=null) {
                            File currentFile = result.getFile();
                            if (finalVideoPath!=null) { // 有指定的视频文件名称，合并文件
                                if (new File(finalVideoPath).exists()) {
                                    List<String> spliteFileList = new ArrayList<>();
                                    spliteFileList.add(finalVideoPath);
                                    spliteFileList.add(currentFile.getAbsolutePath());
                                    try {
                                        AWMp4ParserHelper.getInstance().mergeVideos(spliteFileList, tmpFile.getAbsolutePath());
                                        if (tmpFile.exists()) {
                                            File finalVideoFile = new File(finalVideoPath);
                                            finalVideoFile.delete();
                                            currentFile.delete();
                                            tmpFile.renameTo(finalVideoFile);
                                        } else {
                                            Toast.makeText(PicturesActivity.this, "视频合并失败！", Toast.LENGTH_SHORT).show();
                                        }
                                    } catch (Exception e) {
                                        Log.e("PictureActivity", e.getMessage());
                                    }
                                } else {
                                    currentFile.renameTo(new File(finalVideoPath));
                                }
                            }
                        }
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                dismissLoadingDialog();
                                if (isFinishActivity) {
                                    PicturesActivity.this.finish();
                                }
                            }
                        });
                    }
                }).start();
            }

            @Override
            public void onCameraError(@NonNull @NotNull CameraException exception) {
                super.onCameraError(exception);
                Toast.makeText(PicturesActivity.this, exception.toString(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onVideoRecordingStart() {
                super.onVideoRecordingStart();
                /**
                 * 获取当前视频的时间，记录csv文件时使用
                 * */
                long currentTime = AWMp4ParserHelper.getInstance().getVedioTotalTime(new File(finalVideoPath));
                timerTask = new CsvTimerTask(new File(finalVideoPath+".txt"));

                // 开始采集，每隔2秒实时记录位置信息、视频时间以及设备时间
                if (currentTime == 0) {
                    timer.schedule(timerTask, 0, period*1000);
                } else {
                    timerTask.setCurrentVideoTime(currentTime/1000+1);
                    timer.schedule(timerTask, 1, period*1000);
                }

            }

            @Override
            public void onVideoRecordingEnd() {
                super.onVideoRecordingEnd();
                if (timerTask!=null){
                    timerTask.cancel();
                }else {
                    // Toast.makeText(PictureActivity.this, "请先拍照", Toast.LENGTH_SHORT).show();
                }
            }
        });

        // 修改相机的宽高为屏幕宽高的1/3
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        FrameLayout.LayoutParams layoutParamsMap = (FrameLayout.LayoutParams) ivMap.getLayoutParams();//相机的宽高
        layoutParamsMap.height = dm.heightPixels/3;
        layoutParamsMap.width = dm.widthPixels/3;
        ivMap.setLayoutParams(layoutParamsMap);

    }

    private void message(String content, Boolean important) {
        if (important) {
            LOG.w(content);
            Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
        } else {
            LOG.i(content);
            Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void initData() {
        super.initData();
        camera.setMode(Mode.VIDEO);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
//            case R.id.capuretVideo:
//                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                Calendar calendar = Calendar.getInstance();
//                calendar.setTimeInMillis(System.currentTimeMillis());
//                String format = formatter.format(calendar.getTime());
//                //文件
//                File file = new File(Constant.PICTURE_FOLDER, format + ".mp4");
//                cameraView.takeVideo(file, 15000);
//                break;
            case R.id.btn_stop_video:
                if (timerTask!=null){
                    timerTask.cancel();
                    Intent intent = new Intent();
                    intent.putExtra(Constant.INTENT_VIDEO_PATH, finalVideoPath);
                    setResult(0x101, intent);
                }else {
                    Toast.makeText(this, "本段视频没有计时！", Toast.LENGTH_SHORT).show();
                }
                if (camera.isTakingVideo()) {
                    isFinishActivity = true;
                    camera.stopVideo();
                } else {
                    finish();
                }

                break;

            case R.id.btn_switch:
                btnSwich();
                break;
        }
    }
    /**
     * 开始采集
     */
    private void startTakenVideo() {
        if (camera.isTakingVideo()) {
            Toast.makeText(this, "已经在拍摄中...", Toast.LENGTH_SHORT).show();
            return;
        }
        DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        String formatVideoName = formatter.format(calendar.getTime());
        //文件
        File file = new File(Constant.PICTURE_FOLDER, formatVideoName + ".mp4");
        if (file.exists()) {
            try {
                FileOutputStream fo = new FileOutputStream(file);
                FileDescriptor fileDescriptor = fo.getFD();
                camera.takeVideo(fileDescriptor);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            camera.takeVideo(file);
        }

    }

    private void stopTakenVideo() {
        if (camera.isTakingVideo()) {
            camera.stopVideo();
        }
    }
    private Bitmap getBitMap(int resourceId) {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int newWidth = 55;
        int newHeight = 55;
        float widthScale = ((float) newWidth) / width;
        float heightScale = ((float) newHeight) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(widthScale, heightScale);
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        return bitmap;
    }

    /**
     * 设置定位图标样式
     */
    private void setLocMarkerStyle() {
        tencentMap.setLocationSource(new MyTecentLocationSource(this));
        tencentMap.setMyLocationEnabled(true);

        locationStyle = new MyLocationStyle();
        locationStyle = locationStyle.myLocationType(LOCATION_TYPE_LOCATION_ROTATE);
        //创建图标
        BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getBitMap(location));
        locationStyle.icon(bitmapDescriptor);
        //设置定位圆形区域的边框宽度;
        locationStyle.fillColor(getResources().getColor(android.R.color.transparent));
        locationStyle.strokeWidth(1);
        tencentMap.setMyLocationStyle(locationStyle);
    }


    public void btnSwich() {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        System.out.println("width-display :" + dm.widthPixels);
        System.out.println("heigth-display :" + dm.heightPixels);
        FrameLayout.LayoutParams layoutParamsMap = (FrameLayout.LayoutParams) ivMap.getLayoutParams();//地图的宽高
        int heightMap = ivMap.getMeasuredHeight();
        int widthMap = ivMap.getMeasuredWidth();
        FrameLayout.LayoutParams layoutParamsCamera = (FrameLayout.LayoutParams) camera.getLayoutParams();//相机的宽高
        int heightCamera = camera.getMeasuredHeight();
        int widthCamera = camera.getMeasuredWidth();

        layerChange.removeAllViews();
        if (widthMap > widthCamera) {

            layoutParamsCamera.width = dm.widthPixels;
            layoutParamsCamera.height = dm.heightPixels;
            layoutParamsMap.height = heightCamera;
            layoutParamsMap.width = widthCamera;
            camera.setLayoutParams(layoutParamsCamera);
            ivMap.setLayoutParams(layoutParamsMap);
            layerChange.addView(camera);
            layerChange.addView(ivMap);
        } else {

            layoutParamsMap.height = dm.heightPixels;
            layoutParamsMap.width = dm.widthPixels;
            layoutParamsCamera.height = heightMap;
            layoutParamsCamera.width = widthMap;
            camera.setLayoutParams(layoutParamsCamera);
            ivMap.setLayoutParams(layoutParamsMap);
            layerChange.addView(ivMap);
            layerChange.addView(camera);
        }
    }



    @Override
    protected void onResume() {
        super.onResume();
        camera.open();


    }

    @Override
    protected void onPause() {
        super.onPause();
        camera.close();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopTakenVideo();
        camera.destroy();
        timer.cancel();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMessageMainThread(Message msg) {
        switch (msg.what) {
            case Constant.EVENT_WHAT_LOCATION_CHANGE: // 用户位置更新
                if (tencentMap!=null) {
                    CameraUpdate cameraSigma =
                            CameraUpdateFactory.newCameraPosition(new CameraPosition(
                                    new LatLng(Constant.currentLocation.getLatitude(),Constant.currentLocation.getLongitude()), //中心点坐标，地图目标经纬度
                                    16,  //目标缩放级别
                                    0, //目标倾斜角
                                    0)); //目标旋转角 0~360° (正北方为0)
                    tencentMap.animateCamera(cameraSigma);
                }
                break;
        }
    }

    /**
     * 记录视频拍摄的时间及经纬度
     */
    private class CsvTimerTask extends TimerTask {
        private File csvFile;
        private long currentVideoTime; // 记录当前的视频时间

        public CsvTimerTask(File csvFile) {
            this.csvFile = csvFile;
            if (!csvFile.exists()) {
                csvFile.getParentFile().mkdirs();
            }
        }

        public void setCurrentVideoTime(long currentVideoTime) {
            this.currentVideoTime = currentVideoTime;
        }

        @Override
        public void run() {
            // 记录当前时间、视频时间、以及当前经纬度信息
            StringBuffer sb = new StringBuffer();
            sb.append(formatter.format(new Date())); // 记录当前时间
            sb.append(",");
            sb.append(currentVideoTime) ;// 记录视频时间
            sb.append(",");
            sb.append(Constant.currentLocation.getLatitude());
            sb.append(",");
            sb.append(Constant.currentLocation.getLongitude());
            sb.append("\r\n");
            FileUtils.writeFile(csvFile.getAbsolutePath(), sb.toString(), true);
            currentVideoTime = currentVideoTime+period; //
        }
    }
}