package com.remax.visualnovel.widget.imagepicker.data;

import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.BUCKET_ORDER_BY;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.COLUMN_BUCKET_DISPLAY_NAME;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.COLUMN_BUCKET_ID;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.COLUMN_COUNT;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.COLUMN_URI;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.MEDIA_TYPE;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.MEDIA_TYPE_IMAGE;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.MEDIA_TYPE_VIDEO;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.MIME_TYPE;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.QUERY_URI;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants.SIZE;
import static com.remax.visualnovel.widget.imagepicker.data.MediaStoreConstants._ID;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.LongSparseArray;

import androidx.loader.content.CursorLoader;

import com.remax.visualnovel.R;
import com.remax.visualnovel.widget.imagepicker.bean.ImageSet;
import com.remax.visualnovel.widget.imagepicker.bean.MimeType;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

;


public class MediaSetsLoader extends CursorLoader {
    private boolean isLoadVideo;
    private boolean isLoadImage;
    private static final String[] COLUMNS = {
            _ID,
            COLUMN_BUCKET_ID,
            COLUMN_BUCKET_DISPLAY_NAME,
            COLUMN_URI,
            COLUMN_COUNT};
    private static final String[] PROJECTION = {
            _ID,
            COLUMN_BUCKET_ID,
            COLUMN_BUCKET_DISPLAY_NAME,
            MIME_TYPE};

    private MediaSetsLoader(Context context, String selection, String[] selectionArgs, boolean isLoadVideo, boolean isLoadImage) {
        super(context, QUERY_URI, PROJECTION, selection, selectionArgs, BUCKET_ORDER_BY);
        this.isLoadVideo = isLoadVideo;
        this.isLoadImage = isLoadImage;
    }

    public static CursorLoader create(Context context, Set<MimeType> mimeTypeSet, boolean isLoadVideo, boolean isLoadImage) {
        int index = 0;
        String mimeSelection = "";
        ArrayList<String> arrayList = MimeType.getMimeTypeList(mimeTypeSet);
        String[] selectionArgs = new String[arrayList.size()];
        for (String mimeType : arrayList) {
            selectionArgs[index] = mimeType;
            mimeSelection = String.format("%s =? OR %s", MIME_TYPE, mimeSelection);
            index++;
        }

        if (mimeSelection.endsWith(" OR ")) {
            mimeSelection = mimeSelection.substring(0, mimeSelection.length() - 4);
        }
        String selection = "(" + MEDIA_TYPE + "=" + MEDIA_TYPE_VIDEO + " OR " + MEDIA_TYPE + "=" + MEDIA_TYPE_IMAGE + ")" +
                " AND " +
                SIZE + ">0" +
                " AND (" +
                mimeSelection + ")";
        return new MediaSetsLoader(context, selection, selectionArgs, isLoadVideo, isLoadImage);
    }

    @Override
    public Cursor loadInBackground() {
        Cursor albums = super.loadInBackground();
        MatrixCursor allAlbum = new MatrixCursor(COLUMNS);
        int totalCount = 0;
        Uri allAlbumCoverUri = null;
        LongSparseArray<Long> countMap = new LongSparseArray<>();
        if (albums != null) {
            while (albums.moveToNext()) {
                int columnIndex = albums.getColumnIndex(COLUMN_BUCKET_ID);
                if (columnIndex >= 0) {
                    long bucketId = albums.getLong(columnIndex);
                    Long count = countMap.get(bucketId);
                    count = count == null ? 1L : (count + 1);
                    countMap.put(bucketId, count);
                }
            }
        }
        MatrixCursor newAlbums = new MatrixCursor(COLUMNS);
        if (albums != null) {
            if (albums.moveToFirst()) {
                allAlbumCoverUri = getUri(albums);
                Set<Long> done = new HashSet<>();
                do {
                    int columnIndex = albums.getColumnIndex(COLUMN_BUCKET_ID);
                    if (columnIndex < 0) {
                        continue;
                    }
                    long bucketId = albums.getLong(columnIndex);
                    if (done.contains(bucketId)) {
                        continue;
                    }
                    int columnIndexId = albums.getColumnIndex(_ID);
                    int columnIndexDisplayName = albums.getColumnIndex(COLUMN_BUCKET_DISPLAY_NAME);
                    if (columnIndexId < 0 || columnIndexDisplayName < 0) {
                        continue;
                    }
                    long fileId = albums.getLong(columnIndexId);
                    String bucketDisplayName = albums.getString(columnIndexDisplayName);
                    Uri uri = getUri(albums);
                    if (uri != null) {
                        long count = countMap.get(bucketId);
                        newAlbums.addRow(new String[]{
                                Long.toString(fileId),
                                Long.toString(bucketId),
                                bucketDisplayName,
                                uri.toString(),
                                String.valueOf(count)});
                        done.add(bucketId);
                        totalCount += (int) count;
                    }
                } while (albums.moveToNext());
            }
        }

        String name = "";
        if (isLoadImage && isLoadVideo) {
            name = getContext().getString(R.string.picker_str_folder_item_all);
        } else if (isLoadImage) {
            name = getContext().getString(R.string.picker_str_folder_item_image);
        } else if (isLoadVideo) {
            name = getContext().getString(R.string.picker_str_folder_item_video);
        }

        allAlbum.addRow(new String[]{ImageSet.ID_ALL_MEDIA, ImageSet.ID_ALL_MEDIA, name,
                allAlbumCoverUri == null ? null : allAlbumCoverUri.toString(),
                String.valueOf(totalCount)});

        return new MergeCursor(new Cursor[]{allAlbum, newAlbums});
    }

    private static Uri getUri(Cursor cursor) {
        int idColumnIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns._ID);
        int mimeTypeColumnIndex = cursor.getColumnIndex(MIME_TYPE);
        if (idColumnIndex < 0 || mimeTypeColumnIndex < 0) {
            return null;
        }
        long id = cursor.getLong(idColumnIndex);
        String mimeType = cursor.getString(mimeTypeColumnIndex);
        Uri contentUri;
        if (MimeType.isImage(mimeType)) {
            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        } else if (MimeType.isVideo(mimeType)) {
            contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        } else {
            contentUri = QUERY_URI;
        }
        return ContentUris.withAppendedId(contentUri, id);
    }

    @Override
    public void onContentChanged() {
    }
}