package com.remax.visualnovel.widget.imagepicker.activity.multi;

import static com.remax.visualnovel.widget.imagepicker.activity.multi.MultiImagePickerActivity.INTENT_KEY_PRESENTER;
import static com.remax.visualnovel.widget.imagepicker.activity.multi.MultiImagePickerActivity.INTENT_KEY_SELECT_CONFIG;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;

import com.remax.visualnovel.R;
import com.remax.visualnovel.app.widget.LoadingDialog;
import com.remax.visualnovel.widget.imagepicker.ImagePicker;
import com.remax.visualnovel.widget.imagepicker.activity.PBaseLoaderFragment;
import com.remax.visualnovel.widget.imagepicker.activity.preview.MultiImagePreviewActivity;
import com.remax.visualnovel.widget.imagepicker.adapter.PickerFolderAdapter;
import com.remax.visualnovel.widget.imagepicker.adapter.PickerItemAdapter;
import com.remax.visualnovel.widget.imagepicker.bean.ImageItem;
import com.remax.visualnovel.widget.imagepicker.bean.ImageSet;
import com.remax.visualnovel.widget.imagepicker.bean.PickerError;
import com.remax.visualnovel.widget.imagepicker.bean.PickerItemDisableCode;
import com.remax.visualnovel.widget.imagepicker.bean.SelectMode;
import com.remax.visualnovel.widget.imagepicker.bean.selectconfig.BaseSelectConfig;
import com.remax.visualnovel.widget.imagepicker.bean.selectconfig.MultiSelectConfig;
import com.remax.visualnovel.widget.imagepicker.data.IReloadExecutor;
import com.remax.visualnovel.widget.imagepicker.data.OnImagePickCompleteListener;
import com.remax.visualnovel.widget.imagepicker.helper.PickerErrorExecutor;
import com.remax.visualnovel.widget.imagepicker.presenter.IPickerPresenter;
import com.remax.visualnovel.widget.imagepicker.utils.MediaUtils;
import com.remax.visualnovel.widget.imagepicker.utils.PBitmapUtils;
import com.remax.visualnovel.widget.imagepicker.views.PickerUiConfig;
import com.remax.visualnovel.widget.itemdecoration.GridSpaceItemDecoration;

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

import timber.log.Timber;


/**
 * Description: 多选页
 * <p>
 * Author: peixing.yang
 * Date: 2019/2/21
 * 使用文档 ：https://github.com/yangpeixing/YImagePicker/wiki/Documentation_3.x
 */
public class MultiImagePickerFragment extends PBaseLoaderFragment implements View.OnClickListener,
        PickerItemAdapter.OnActionResult, IReloadExecutor {
    private List<ImageSet> imageSets = new ArrayList<>();
    private ArrayList<ImageItem> imageItems = new ArrayList<>();
    private RecyclerView mRecyclerView;
    private View v_masker;
    private TextView mTvTime;
    private PickerFolderAdapter mImageSetAdapter;
    private RecyclerView mFolderListRecyclerView;
    private PickerItemAdapter mAdapter;
    private ImageSet currentImageSet;
    private FrameLayout titleBarContainer;
    private FrameLayout bottomBarContainer;
    private MultiSelectConfig selectConfig;
    private IPickerPresenter presenter;
    private PickerUiConfig uiConfig;
    private FragmentActivity mContext;
    private GridLayoutManager layoutManager;
    private View view;

    private LoadingDialog loadingDialog;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.picker_activity_multipick, container, false);
        return view;
    }

    /**
     * 校验传递数据是否合法
     */
    private boolean isIntentDataValid() {
        Bundle bundle = getArguments();
        if (bundle != null) {
            selectConfig = (MultiSelectConfig) bundle.getSerializable(INTENT_KEY_SELECT_CONFIG);
            presenter = (IPickerPresenter) bundle.getSerializable(INTENT_KEY_PRESENTER);
            if (presenter == null) {
                PickerErrorExecutor.executeError(onImagePickCompleteListener,
                        PickerError.PRESENTER_NOT_FOUND.getCode());
                return false;
            }
            if (selectConfig == null) {
                PickerErrorExecutor.executeError(onImagePickCompleteListener,
                        PickerError.SELECT_CONFIG_NOT_FOUND.getCode());
                return false;
            }
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mContext = getActivity();
        if (isIntentDataValid()) {
            ImagePicker.isOriginalImage = selectConfig.isDefaultOriginal();
            uiConfig = presenter.getUiConfig(getWeakActivity());
            setStatusBar();
            findView();
            if (selectConfig.getLastImageList() != null) {
                selectList.addAll(selectConfig.getLastImageList());
            }
            loadMediaSets();
            refreshCompleteState();
        }
    }

    private OnImagePickCompleteListener onImagePickCompleteListener;

    /**
     * 设置图片选择器完成回调
     *
     * @param onImagePickCompleteListener 完成回调
     */
    public void setOnImagePickCompleteListener(@NonNull OnImagePickCompleteListener onImagePickCompleteListener) {
        this.onImagePickCompleteListener = onImagePickCompleteListener;
    }

    /**
     * 初始化控件
     */
    private void findView() {
        v_masker = view.findViewById(R.id.v_masker);
        mRecyclerView = view.findViewById(R.id.mRecyclerView);
        mFolderListRecyclerView = view.findViewById(R.id.mSetRecyclerView);
        mTvTime = view.findViewById(R.id.tv_time);
        mTvTime.setVisibility(View.GONE);
        titleBarContainer = view.findViewById(R.id.titleBarContainer);
        bottomBarContainer = view.findViewById(R.id.bottomBarContainer);
        initAdapters();
        initUI();
        setListener();
        refreshCompleteState();
    }

    private RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                if (mTvTime.getVisibility() == View.VISIBLE) {
                    mTvTime.setVisibility(View.GONE);
                    mTvTime.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.picker_fade_out));
                }
            } else {
                if (mTvTime.getVisibility() == View.GONE) {
                    mTvTime.setVisibility(View.VISIBLE);
                    mTvTime.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.picker_fade_in));
                }
            }
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (imageItems != null)
                try {
                    mTvTime.setText(imageItems.get(layoutManager.findFirstVisibleItemPosition()).getTimeFormat());
                } catch (Exception ignored) {

                }
        }
    };

    /**
     * 初始化UI界面
     */
    private void initUI() {
        mRecyclerView.setBackgroundColor(uiConfig.getPickerBackgroundColor());
        titleBar = inflateControllerView(titleBarContainer, true, uiConfig);
        bottomBar = inflateControllerView(bottomBarContainer, false, uiConfig);
        setFolderListHeight(mFolderListRecyclerView, v_masker, false);
    }

    /**
     * 初始化监听
     */
    private void setListener() {
        v_masker.setOnClickListener(this);
//        mRecyclerView.addOnScrollListener(onScrollListener);
        mImageSetAdapter.setFolderSelectResult((set, pos) -> selectImageFromSet(pos, true));
    }

    /**
     * 初始化相关adapter
     */
    private void initAdapters() {
        mFolderListRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mImageSetAdapter = new PickerFolderAdapter(presenter, uiConfig);
        mFolderListRecyclerView.setAdapter(mImageSetAdapter);
        mImageSetAdapter.refreshData(imageSets);

        mAdapter = new PickerItemAdapter(selectList, new ArrayList<ImageItem>(), selectConfig, presenter, uiConfig);
        mAdapter.setHasStableIds(true);
        mAdapter.setOnActionResult(this);
        layoutManager = new GridLayoutManager(mContext, selectConfig.getColumnCount());
        mRecyclerView.addItemDecoration(new GridSpaceItemDecoration(selectConfig.getColumnCount(), dp(5), dp(5), false));
        if (mRecyclerView.getItemAnimator() instanceof SimpleItemAnimator) {
            ((SimpleItemAnimator) mRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
            mRecyclerView.getItemAnimator().setChangeDuration(0);// 通过设置动画执行时间为0来解决闪烁问题
        }
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setAdapter(mAdapter);
    }

    /**
     * 选择图片文件夹
     *
     * @param position 位置
     */
    private void selectImageFromSet(final int position, boolean isTransit) {
        currentImageSet = imageSets.get(position);
        if (isTransit) {
            toggleFolderList();
        }
        for (ImageSet set1 : imageSets) {
            set1.isSelected = false;
        }
        currentImageSet.isSelected = true;
        mImageSetAdapter.notifyDataSetChanged();
        if (currentImageSet.isAllMedia()) {
            if (selectConfig.isShowCameraInAllMedia()) {
                selectConfig.setShowCamera(true);
            }
        } else {
            if (selectConfig.isShowCameraInAllMedia()) {
                selectConfig.setShowCamera(false);
            }
        }
        loadMediaItemsFromSet(currentImageSet);
    }


    /**
     * 显示或隐藏图片文件夹选项列表
     */
    @Override
    protected void toggleFolderList() {
        if (mFolderListRecyclerView.getVisibility() == View.GONE) {
            controllerViewOnTransitImageSet(true);
            v_masker.setVisibility(View.VISIBLE);
            mFolderListRecyclerView.setVisibility(View.VISIBLE);
            mFolderListRecyclerView.setAnimation(AnimationUtils.loadAnimation(mContext,
                    uiConfig.isShowFromBottom() ? R.anim.picker_show2bottom : R.anim.picker_anim_in));
        } else {
            controllerViewOnTransitImageSet(false);
            v_masker.setVisibility(View.GONE);
            mFolderListRecyclerView.setVisibility(View.GONE);
            mFolderListRecyclerView.setAnimation(AnimationUtils.loadAnimation(mContext,
                    uiConfig.isShowFromBottom() ? R.anim.picker_hide2bottom : R.anim.picker_anim_up));
        }
    }

    @Override
    public void onClick(@NonNull View v) {
        if (onDoubleClick()) {
            return;
        }
        if (v == v_masker) {
            toggleFolderList();
        }
    }

    @Override
    protected void loadMediaSetsComplete(@Nullable List<ImageSet> imageSetList) {
        if (imageSetList == null || imageSetList.size() == 0 ||
                (imageSetList.size() == 1 && imageSetList.get(0).count == 0)) {
            tip(getString(R.string.picker_str_tip_media_empty));
            return;
        }
        this.imageSets = imageSetList;
        mImageSetAdapter.refreshData(imageSets);
        selectImageFromSet(0, false);
    }

    @Override
    protected void loadMediaItemsComplete(ImageSet set) {
        this.imageItems = set.imageItems;
        controllerViewOnImageSetSelected(set);
        mAdapter.refreshData(imageItems);
    }

    @Override
    protected void refreshAllVideoSet(ImageSet allVideoSet) {
        if (allVideoSet != null && allVideoSet.imageItems != null
                && allVideoSet.imageItems.size() > 0
                && !imageSets.contains(allVideoSet)) {
            imageSets.add(1, allVideoSet);
            mImageSetAdapter.refreshData(imageSets);
        }
    }

    @Override
    public void onTakePhotoResult(@NonNull ImageItem imageItem) {
        //剪裁模式下，直接跳转剪裁页面
        if (selectConfig.getSelectMode() == SelectMode.MODE_CROP) {
            intentCrop(imageItem);
            return;
        }
        //单选模式下，直接回调出去
        if (selectConfig.getSelectMode() == SelectMode.MODE_SINGLE) {
            notifyOnSingleImagePickComplete(imageItem);
            return;
        }
        //将拍照返回的imageItem手动添加到第一个item上并选中
        addItemInImageSets(imageSets, imageItems, imageItem);
        mAdapter.refreshData(imageItems);
        mImageSetAdapter.refreshData(imageSets);
        onCheckItem(imageItem, PickerItemDisableCode.NORMAL);
    }

    @Override
    public boolean onBackPressed() {
        if (mFolderListRecyclerView != null && mFolderListRecyclerView.getVisibility() == View.VISIBLE) {
            toggleFolderList();
            return true;
        }
        if (presenter != null && presenter.interceptPickerCancel(getWeakActivity(), selectList)) {
            return true;
        }
        PickerErrorExecutor.executeError(onImagePickCompleteListener, PickerError.CANCEL.getCode());
        return false;
    }


    @Override
    public void onClickItem(@NonNull ImageItem item, int position, int disableItemCode) {
        position = selectConfig.isShowCamera() ? position - 1 : position;
        //拍照
        if (position < 0 && selectConfig.isShowCamera()) {
            if (!presenter.interceptCameraClick(getWeakActivity(), this)) {
                checkTakePhotoOrVideo();
            }
            return;
        }

        //当前选中item是否不可以点击
        if (interceptClickDisableItem(disableItemCode, false)) {
            return;
        }

        mRecyclerView.setTag(item);

        //剪裁模式下，直接跳转剪裁
        if (selectConfig.getSelectMode() == SelectMode.MODE_CROP) {
            if (item.isGif() || item.isVideo()) {
                notifyOnSingleImagePickComplete(item);
            } else {
                intentCrop(item);
            }
            return;
        }

        //检测是否拦截了item点击
        if (!mAdapter.isPreformClick() && presenter.interceptItemClick(getWeakActivity(), item, selectList, imageItems,
                selectConfig, mAdapter, false, this)) {
            return;
        }

        //如果当前是视频，且视频只能单选，且单选情况下自动回调，则执行回调
        if (item.isVideo() && selectConfig.isVideoSinglePickAndAutoComplete()) {
            notifyOnSingleImagePickComplete(item);
            return;
        }

        //如果当前是单选模式，且单选模式下点击item直接回调，则直接回调
        if (selectConfig.getMaxCount() <= 1 && selectConfig.isSinglePickAutoComplete()) {
            notifyOnSingleImagePickComplete(item);
            return;
        }

        //如果当前是视频，且不支持视频预览，则拦截掉点击
        if (item.isVideo() && !selectConfig.isCanPreviewVideo()) {
            tip(getActivity().getString(R.string.picker_str_tip_cant_preview_video));
            return;
        }

        //如果开启了预览，则直接跳转预览
        if (selectConfig.isPreview()) {
            intentPreview(true, position);
        }
    }

    @Override
    public void onCheckItem(ImageItem imageItem, int disableItemCode) {
        if (selectConfig.getSelectMode() == SelectMode.MODE_SINGLE
                && selectConfig.getMaxCount() == 1
                && selectList != null && selectList.size() > 0) {
            if (selectList.contains(imageItem)) {
                selectList.clear();
            } else {
                selectList.clear();
                selectList.add(imageItem);
            }
        } else {
            //当前选中item是否不可以点击
            if (interceptClickDisableItem(disableItemCode, true)) {
                return;
            }

            //检测是否拦截了item点击
            if (!mAdapter.isPreformClick() && presenter.interceptItemClick(getWeakActivity(), imageItem, selectList, imageItems,
                    selectConfig, mAdapter, true, this)) {
                return;
            }

            //如果当前选中列表包含此item,则移除，否则添加
            if (selectList.contains(imageItem)) {
                selectList.remove(imageItem);
            } else {
                selectList.add(imageItem);
            }
        }
        mAdapter.notifyDataSetChanged();
        refreshCompleteState();
    }

    /**
     * 跳转剪裁页面
     *
     * @param imageItem 图片信息
     */
    private void intentCrop(ImageItem imageItem) {
        ImagePicker.crop(getActivity(), presenter, selectConfig, imageItem, new OnImagePickCompleteListener() {
            @Override
            public void onImagePickComplete(ArrayList<ImageItem> items) {
                selectList.clear();
                selectList.addAll(items);
                mAdapter.notifyDataSetChanged();
                notifyPickerComplete();
            }
        });
    }

    /**
     * 跳转预览
     *
     * @param position 默认选中的index
     */
    @Override
    protected void intentPreview(boolean isClickItem, int position) {
        if (!isClickItem && (selectList == null || selectList.size() == 0)) {
            return;
        }
        MultiImagePreviewActivity.intent(getActivity(), isClickItem ? currentImageSet : null,
                selectList, selectConfig, presenter, position, new MultiImagePreviewActivity.PreviewResult() {
                    @Override
                    public void onResult(ArrayList<ImageItem> mImageItems, boolean isCancel) {
                        if (isCancel) {
                            reloadPickerWithList(mImageItems);
                        } else {
                            selectList.clear();
                            selectList.addAll(mImageItems);
                            mAdapter.notifyDataSetChanged();
                            notifyPickerComplete();
                        }
                    }
                });
    }

    /**
     * 刷新选中图片列表，执行回调，退出页面
     */
    @Override
    protected void notifyPickerComplete() {
        if (presenter == null || presenter.interceptPickerCompleteClick(getWeakActivity(), selectList, selectConfig)) {
            return;
        }
        if (onImagePickCompleteListener != null) {
            if (getActivity() != null) {
                loadingDialog = new LoadingDialog();
                loadingDialog.build(getActivity());
                loadingDialog.show();
            }
            String temp = MediaUtils.getTempFilePath();
            new Thread(() -> {
                for (int i = 0; i < selectList.size(); i++) {
                    ImageItem imageItem = selectList.get(i);
                    imageItem.isOriginalImage = ImagePicker.isOriginalImage;
                    imageItem.path = MediaUtils.copyUriToLocalMedia(getActivity(), imageItem, temp);
                    //重新获取图片宽高（从图库获取的宽高有错误情况）
                    if (imageItem.isImage() || imageItem.isGif()) {
                        int[] imageWidthHeight = PBitmapUtils.getImageWidthHeight(imageItem.path);
                        Timber.d("MultiImagePickerFragment width:" + imageWidthHeight[0] + "   height:" + imageWidthHeight[1]);
                        imageItem.width = imageWidthHeight[0];
                        imageItem.height = imageWidthHeight[1];
                    }
                }
                if (getActivity() != null) {
                    getActivity().runOnUiThread(() -> {
                        if (loadingDialog != null) {
                            loadingDialog.dismiss();
                            loadingDialog = null;
                        }
                        onImagePickCompleteListener.onImagePickComplete(selectList);
                    });
                }
            }).start();
        }
    }

    @Override
    protected BaseSelectConfig getSelectConfig() {
        return selectConfig;
    }

    @Override
    protected IPickerPresenter getPresenter() {
        return presenter;
    }

    @Override
    protected PickerUiConfig getUiConfig() {
        return uiConfig;
    }

    @Override
    public void onDestroy() {
        uiConfig.setPickerUiProvider(null);
        uiConfig = null;
        presenter = null;
        super.onDestroy();
    }

    @Override
    public void reloadPickerWithList(List<ImageItem> selectedList) {
        selectList.clear();
        selectList.addAll(selectedList);
        mAdapter.refreshData(imageItems);
        refreshCompleteState();
    }
}
