package com.datarecovery.master.module.preview;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.SurfaceHolder;
import android.widget.SeekBar;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager2.widget.ViewPager2;

import com.atmob.app.lib.base.BaseActivity;
import com.atmob.common.ui.SizeUtil;
import com.datarecovery.master.R;
import com.datarecovery.master.data.consts.EventId;
import com.datarecovery.master.databinding.ActivityPreviewBinding;
import com.datarecovery.master.dialog.CommonSureDialog;
import com.datarecovery.master.handler.EventHelper;
import com.datarecovery.master.module.member.MemberType;
import com.datarecovery.master.utils.BoxingUtil;
import com.datarecovery.master.utils.FilesSearch;
import com.datarecovery.master.utils.ImageDeepDetector;
import com.datarecovery.master.utils.Maps;
import com.datarecovery.master.utils.ReportUtil;
import com.datarecovery.master.utils.SafeMediaPlayer;
import com.datarecovery.master.utils.ToastUtil;
import com.gyf.immersionbar.ImmersionBar;

import java.lang.ref.WeakReference;
import java.util.List;

import dagger.hilt.android.AndroidEntryPoint;

@AndroidEntryPoint
public class PreviewActivity extends BaseActivity<ActivityPreviewBinding> {

    public static final int TYPE_IMG = 1;
    public static final int TYPE_VIDEO = 2;
    public static final int TYPE_AUDIO = 3;
    private PreviewViewModel previewViewModel;
    private MediaPlayer mediaPlayer;


    private CommonSureDialog showTrialExportFailDialog;

    private ViewPager2.OnPageChangeCallback onPageChangeCallback;
    private CommonSureDialog showFreeStopDialog;

    @IntDef({TYPE_IMG, TYPE_VIDEO, TYPE_AUDIO})
    @interface Type {
    }

    public static void startImagePreView(Context context, List<ImageDeepDetector.ImageFile> imageFileList, int position, boolean isTrial) {
        Intent intent = new Intent(context, PreviewActivity.class);
        intent.putExtra("type", TYPE_IMG);
        intent.putExtra("position", position);
        intent.putExtra("isTrial", isTrial);
        PreviewViewModel.weakReference = new WeakReference<>(imageFileList);
        if (!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }

    public static void startDocumentPreView(Context context, @Type int type, FilesSearch.DocumentFile documentFile, boolean isTrial) {
        Intent intent = new Intent(context, PreviewActivity.class);
        intent.putExtra("type", type);
        intent.putExtra("isTrial", isTrial);
        PreviewViewModel.weakReference = new WeakReference<>(documentFile);
        if (!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }

    @Override
    protected boolean shouldImmersion() {
        return true;
    }

    @Override
    protected void configImmersion(@NonNull ImmersionBar immersionBar) {
        immersionBar.statusBarDarkFont(true);
    }

    @Override
    protected void initViewModel() {
        previewViewModel = getViewModelProvider().get(PreviewViewModel.class);
        binding.setPreviewViewModel(previewViewModel);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initView();
        initIntentData();
        initObserver();
    }

    private void initObserver() {
        previewViewModel.getClickMediaPlayerEvent().observe(this, o -> {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
            } else {
                mediaPlayer.start();
            }
            previewViewModel.setIsPlaying(mediaPlayer.isPlaying());
        });
        previewViewModel.getSeekBarProgress().observe(this, process -> mediaPlayer.seekTo(BoxingUtil.boxing(process)));
        previewViewModel.getShowFreeStopDialog().observe(this, o -> {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
            }
            previewViewModel.setIsPlaying(false);
            showFreeStopDialog();
        });
        previewViewModel.getHandlePlayProgress().observe(this, o -> previewViewModel.handleMediaPlayerProgress(mediaPlayer.getCurrentPosition()));
        previewViewModel.getRefreshAudioCurrentProgress().observe(this, o -> binding.previewAudioSeekbar.setProgress(mediaPlayer.getCurrentPosition()));
        previewViewModel.getShowTrialExportFailDialog().observe(this, o -> showTrialExportFailDialog());
    }

    private void showFreeStopDialog() {
        if (showFreeStopDialog == null) {
            showFreeStopDialog = new CommonSureDialog(this);
            if (previewViewModel.getType() == TYPE_VIDEO) {
                showFreeStopDialog.setDialogTitle(R.string.trial_export_video_fail_title)
                        .setDialogContent(R.string.trial_export_video_fail_content);
            } else if (previewViewModel.getType() == TYPE_AUDIO) {
                showFreeStopDialog.setDialogTitle(R.string.trial_export_audio_fail_title)
                        .setDialogContent(R.string.trial_export_audio_fail_content);
            }
            showFreeStopDialog.setSureText(R.string.dialog_trial_recover);
            showFreeStopDialog.setOnDialogClickListener(() -> {
                if (previewViewModel.getType() == TYPE_VIDEO) {
                    EventHelper.report(EventId.hf1001125);
                } else if (previewViewModel.getType() == TYPE_AUDIO) {
                    EventHelper.report(EventId.hf1001127);
                }
                previewViewModel.onTrialRecoverClick();
            });
            showFreeStopDialog.setOnDismissListener(dialog -> {
                if (previewViewModel.getType() == TYPE_VIDEO) {
                    EventHelper.report(EventId.hf1001126);
                } else if (previewViewModel.getType() == TYPE_AUDIO) {
                    EventHelper.report(EventId.hf1001128);
                }
            });
        }
        showFreeStopDialog.show();
    }

    private void showTrialExportFailDialog() {
        if (showTrialExportFailDialog == null) {
            showTrialExportFailDialog = new CommonSureDialog(this);
            showTrialExportFailDialog.setDialogTitle(R.string.trial_export_fail_title)
                    .setDialogContent(R.string.trial_export_fail_content).setSureText(R.string.dialog_trial_recover);
            String evenType;
            if (previewViewModel.getType() == TYPE_IMG) {
                evenType = MemberType.APP_IMAGE_RECOVER;
            } else if (previewViewModel.getType() == TYPE_VIDEO) {
                evenType = MemberType.APP_VIDEO_RECOVER;
            } else if (previewViewModel.getType() == TYPE_AUDIO) {
                evenType = MemberType.APP_AUDIO_RECOVER;
            } else {
                evenType = null;
            }
            showTrialExportFailDialog.setOnDialogClickListener(() -> {
                EventHelper.report(EventId.hf1001123, Maps.asMap(EventId.EVENT_ID, ReportUtil.getReportId(evenType)));
                previewViewModel.onTrialRecoverClick();
            });
            showTrialExportFailDialog.setOnDismissListener(dialog -> {
                if (!TextUtils.isEmpty(evenType)) {
                    EventHelper.report(EventId.hf1001124, Maps.asMap(EventId.EVENT_ID, ReportUtil.getReportId(evenType)));
                }
            });
        }
        showTrialExportFailDialog.show();
    }


    private void initIntentData() {
        int type = getIntent().getIntExtra("type", 0);
        int position = getIntent().getIntExtra("position", 0);
        boolean isTrial = getIntent().getBooleanExtra("isTrial", false);
        previewViewModel.setPreviewData(type, position, isTrial);
        if (type == TYPE_IMG) {
            initImagePreviewPager();
        } else {
            if (type == TYPE_VIDEO || type == TYPE_AUDIO) {
                initMediaPlayer(previewViewModel.getUri());
            }
            if (type == TYPE_VIDEO) {
                initSurfaceView();
            }
        }
    }

    private void initSeekBar() {
        binding.previewAudioSeekbar.setProgress(0);
        binding.previewAudioSeekbar.setMax(mediaPlayer.getDuration());
        binding.previewAudioSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    mediaPlayer.seekTo(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                previewViewModel.setSeekbarChanging(true);
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                previewViewModel.setSeekbarChanging(false);
                previewViewModel.setSeekbarTo(seekBar.getProgress());
            }
        });
        previewViewModel.startMediaTimer();
    }

    private void initView() {
        binding.previewHeader.setNavigationOnClickListener(v -> finish());
        addTopStatusBarHeight(binding.previewHeader);
    }

    private void initImagePreviewPager() {
        PreviewImagePagerAdapter imagePagerAdapter = new PreviewImagePagerAdapter(previewViewModel.getImagePreviewList(), previewViewModel.isTrial());
        binding.previewViewPager.setAdapter(imagePagerAdapter);
        onPageChangeCallback = new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                previewViewModel.setPosition(position);
            }
        };
        binding.previewViewPager.registerOnPageChangeCallback(onPageChangeCallback);
        binding.previewViewPager.setCurrentItem(previewViewModel.getPosition(), false);
    }

    private void initSurfaceView() {
        SurfaceHolder holder = binding.previewVideo.getHolder();
        previewViewModel.setSurfaceCreated(false);
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                mediaPlayer.setDisplay(holder);
                previewViewModel.setSurfaceCreated(true);
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                mediaPlayer.stop();
                mediaPlayer.setDisplay(null);
            }
        });
    }

    private void initMediaPlayer(Uri uri) {
        mediaPlayer = new SafeMediaPlayer();
        try {
            mediaPlayer.setDataSource(this, uri);
            mediaPlayer.setOnPreparedListener(mp -> {
                previewViewModel.setTotalDuration(mediaPlayer.getDuration());
                if (previewViewModel.getType() == TYPE_VIDEO) {
                    initVideo();
                } else if (previewViewModel.getType() == TYPE_AUDIO) {
                    initSeekBar();
                }
            });
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnErrorListener((mp, what, extra) -> {
                ToastUtil.show(R.string.preview_source_error, ToastUtil.LENGTH_SHORT);
                return false;
            });
            mediaPlayer.setOnCompletionListener(mp -> {
                if (previewViewModel.getType() == TYPE_VIDEO) {
                    previewViewModel.setIsPlaying(false);
                    previewViewModel.setIsPlayStart(false);
                } else if (previewViewModel.getType() == TYPE_AUDIO) {
                    mediaPlayer.seekTo(0);
                    previewViewModel.setIsPlaying(false);
                }
            });
        } catch (Exception ignored) {
        }
    }

    private void initVideo() {
        int videoWidth = mediaPlayer.getVideoWidth();
        int screenWidth = SizeUtil.getScreenWidth();
        float scaleX = screenWidth / (videoWidth * 1f);
        int width = (int) (videoWidth * scaleX);
        int height = (int) (mediaPlayer.getVideoHeight() * scaleX);
        binding.previewVideo.resize(width, height);
        previewViewModel.startMediaTimer();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) mediaPlayer.release();
        binding.previewViewPager.unregisterOnPageChangeCallback(onPageChangeCallback);
    }
}