package de.beyondsoft.ownchat.filepicker.fragments;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
import de.beyondsoft.ownchat.filepicker.MediaDetailsActivity;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.adapters.FolderGridAdapter;
import de.beyondsoft.ownchat.filepicker.models.ImageDirectory;
import de.beyondsoft.ownchat.filepicker.utils.AndroidLifecycleUtils;
import de.beyondsoft.ownchat.filepicker.utils.GridSpacingItemDecoration;
import de.beyondsoft.ownchat.filepicker.utils.ImageCaptureManager;
import de.beyondsoft.ownchat.filepicker.utils.MediaStoreHelper;

public class MediaFolderPickerFragment extends BaseFragment implements FolderGridAdapter.FolderGridAdapterListener {
    private static final int SCROLL_THRESHOLD = 30;
    RecyclerView recyclerView;

    TextView emptyView;

    private ImagePickerFragmentListener mListener;
    private FolderGridAdapter photoGridAdapter;
    private ImageCaptureManager imageCaptureManager;
    private RequestManager mGlideRequestManager;
    private int fileType;

    public MediaFolderPickerFragment() {
    }


    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_media_folder_picker, container, false);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if(context instanceof ImagePickerFragmentListener) {
            mListener = (ImagePickerFragmentListener) context;
        } else {
            throw new RuntimeException(context.toString() + " must implement PhotoPickerFragmentListener");
        }
    }

    @Override
    public void onResume() {
        getDataFromMedia();

        super.onResume();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public static MediaFolderPickerFragment newInstance(int fileType) {
        MediaFolderPickerFragment photoPickerFragment = new MediaFolderPickerFragment();
        Bundle bun = new Bundle();
        bun.putInt(FILE_TYPE, fileType);
        photoPickerFragment.setArguments(bun);
        return photoPickerFragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGlideRequestManager = Glide.with(this);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(view);
    }

    private void initView(View view) {
        recyclerView = view.findViewById(R.id.recyclerview);
        emptyView = view.findViewById(R.id.empty_view);
        fileType = getArguments().getInt(FILE_TYPE);

        imageCaptureManager = new ImageCaptureManager(getActivity());
        GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);

        int spanCount = 2; // 2 columns
        int spacing = 5; // 5px

        recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, false));
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                if(Math.abs(dy) > SCROLL_THRESHOLD) {
                    mGlideRequestManager.pauseRequests();
                } else {
                    resumeRequestsIfNotDestroyed();
                }
            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if(newState == RecyclerView.SCROLL_STATE_IDLE) {
                    resumeRequestsIfNotDestroyed();
                }
            }
        });

        getDataFromMedia();
    }

    private void getDataFromMedia() {
        Bundle mediaStoreArgs = new Bundle();
        mediaStoreArgs.putBoolean(FilePickerConst.EXTRA_SHOW_GIF, PickerManager.getInstance().isShowGif());
        mediaStoreArgs.putInt(FilePickerConst.EXTRA_FILE_TYPE, fileType);

        if(fileType == FilePickerConst.MEDIA_TYPE_IMAGE) {
            MediaStoreHelper.getPhotoDirs(getActivity(), mediaStoreArgs, this::updateList);
        } else if(fileType == FilePickerConst.MEDIA_TYPE_VIDEO) {
            MediaStoreHelper.getVideoDirs(getActivity(), mediaStoreArgs, this::updateList);
        }
    }

    private void updateList(List<ImageDirectory> dirs) {
        Log.i("FILE_PICKER", "Number of directories: " + dirs.size());

        if(dirs.size() > 0) {
            emptyView.setVisibility(View.GONE);
            recyclerView.setVisibility(View.VISIBLE);
        } else {
            emptyView.setVisibility(View.VISIBLE);
            recyclerView.setVisibility(View.GONE);
            return;
        }

        ImageDirectory photoDirectory = new ImageDirectory();
        photoDirectory.setBucketId(FilePickerConst.ALL_PHOTOS_BUCKET_ID);

        if(fileType == FilePickerConst.MEDIA_TYPE_VIDEO) {
            photoDirectory.setName(getString(R.string.all_videos));
        } else if(fileType == FilePickerConst.MEDIA_TYPE_IMAGE) {
            photoDirectory.setName(getString(R.string.all_photos));
        } else {
            photoDirectory.setName(getString(R.string.all_files));
        }

        if(dirs.size() > 0 && dirs.get(0).getMedias().size() > 0) {
            photoDirectory.setDateAdded(dirs.get(0).getDateAdded());
            photoDirectory.setCoverPath(dirs.get(0).getMedias().get(0).getPath());
        }

        for(int i = 0; i < dirs.size(); i++) {
            photoDirectory.addPhotos(dirs.get(i).getMedias());
        }

        dirs.add(0, photoDirectory);

        if(photoGridAdapter != null) {
            photoGridAdapter.setData(dirs);
            photoGridAdapter.notifyDataSetChanged();
        } else {
            photoGridAdapter = new FolderGridAdapter(getActivity(), (ArrayList<ImageDirectory>) dirs, null, (fileType == FilePickerConst.MEDIA_TYPE_IMAGE) && PickerManager.getInstance().isEnableCamera());
            recyclerView.setAdapter(photoGridAdapter);

            photoGridAdapter.setFolderGridAdapterListener(this);
        }
    }

    @Override
    public void onCameraClicked() {
        try {
            Intent intent = imageCaptureManager.dispatchTakePictureIntent(getActivity());

            if(intent != null) {
                startActivityForResult(intent, ImageCaptureManager.REQUEST_TAKE_PHOTO);
            } else {
                Toast.makeText(getActivity(), R.string.no_camera_exists, Toast.LENGTH_SHORT).show();
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFolderClicked(ImageDirectory photoDirectory) {
        Intent intent = new Intent(getActivity(), MediaDetailsActivity.class);
        intent.putExtra(ImageDirectory.class.getSimpleName(), photoDirectory);
        intent.putExtra(FilePickerConst.EXTRA_FILE_TYPE, fileType);
        getActivity().startActivityForResult(intent, FilePickerConst.REQUEST_CODE_MEDIA_DETAIL);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch(requestCode) {
            case ImageCaptureManager.REQUEST_TAKE_PHOTO:
                if(resultCode == Activity.RESULT_OK) {
                    String imagePath = imageCaptureManager.galleryAddPic();

                    if(imagePath != null && PickerManager.getInstance().getMaxCount() == 1) {
                        PickerManager.getInstance().add(imagePath, FilePickerConst.FILE_TYPE_MEDIA);
                        mListener.onItemSelected();
                    } else {
                        new Handler().postDelayed(this::getDataFromMedia, 1000);
                    }
                }

                break;
        }
    }

    private void resumeRequestsIfNotDestroyed() {
        if(!AndroidLifecycleUtils.canLoadImage(this)) {
            return;
        }

        mGlideRequestManager.resumeRequests();
    }
}
