package com.lemenzo.gallery.albums;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.lemenzo.gallery.R;
import com.lemenzo.gallery.data.MediaRepository;
import com.lemenzo.gallery.gallery.GalleryAdapter;
import com.lemenzo.gallery.model.Album;
import com.lemenzo.gallery.model.MediaItem;
import com.lemenzo.gallery.util.BackgroundExecutors;
import com.lemenzo.gallery.ui.MediaGridDecoration;
import com.lemenzo.gallery.ui.RecyclerTuning;
import com.lemenzo.gallery.ui.SystemInsets;
import com.lemenzo.gallery.viewer.ViewerActivity;

import java.util.List;
import java.util.concurrent.ExecutorService;

public final class AlbumActivity extends Activity {
    private static final String EXTRA_ID = "id";
    private static final String EXTRA_NAME = "name";

    private final ExecutorService executor = BackgroundExecutors.single("LemenzoGalleryAlbum");
    private GalleryAdapter adapter;
    private static final int PAGE_SIZE = 180;
    private long albumId;
    private int loadedCount;
    private MediaItem pageAnchor;
    private boolean loadingPage;
    private boolean endReached;
    private java.util.concurrent.Future<?> pageTask;
    private int loadGeneration;
    private RecyclerView grid;

    public static Intent intent(Context context, Album album) {
        return new Intent(context, AlbumActivity.class)
                .putExtra(EXTRA_ID, album.bucketId)
                .putExtra(EXTRA_NAME, album.name);
    }

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setContentView(R.layout.activity_album);
        SystemInsets.apply(this);
        findViewById(R.id.back_button).setOnClickListener(v -> finish());
        ((TextView) findViewById(R.id.title)).setText(getIntent().getStringExtra(EXTRA_NAME));

        grid = findViewById(R.id.media_grid);
        int columns = 3;
        GridLayoutManager layoutManager = new GridLayoutManager(this, columns);
        adapter = new GalleryAdapter(this, new GalleryAdapter.Listener() {
            @Override public void onOpen(MediaItem item) {
                startActivity(ViewerActivity.intent(AlbumActivity.this, item));
            }
            @Override public void onSelectionChanged(int count) {}
        }, false);
        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override public int getSpanSize(int position) {
                return adapter.spanSize(position, columns);
            }
        });
        grid.setLayoutManager(layoutManager);
        grid.addItemDecoration(new MediaGridDecoration(2, columns));
        grid.setAdapter(adapter);
        RecyclerTuning.applyMediaGrid(grid);

        albumId = getIntent().getLongExtra(EXTRA_ID, -1);
        grid.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                if (dy <= 0 || loadingPage || endReached) return;
                int last = layoutManager.findLastVisibleItemPosition();
                if (last >= Math.max(0, adapter.getItemCount() - 36)) loadNextPage(false);
            }
        });
        reload();
    }

    private void reload() {
        if (pageTask != null) { pageTask.cancel(true); pageTask = null; }
        loadedCount = 0; pageAnchor = null; loadingPage = false; endReached = false; loadGeneration++;
        if (adapter != null) adapter.submit(java.util.Collections.emptyList(), false);
        loadNextPage(true);
    }

    private void loadNextPage(boolean firstPage) {
        if (loadingPage || endReached || albumId < 0) return;
        loadingPage = true; final MediaItem anchor = pageAnchor; final int generation = loadGeneration;
        pageTask = executor.submit(() -> {
            List<MediaItem> items = new MediaRepository(this).albumPageAfter(albumId, anchor, PAGE_SIZE);
            runOnUiThread(() -> {
                if (generation != loadGeneration || isFinishing() || adapter == null) return;
                loadingPage = false;
                if (firstPage) adapter.submit(items, false); else adapter.append(items, false);
                loadedCount += items.size();
                if (!items.isEmpty()) pageAnchor = items.get(items.size() - 1);
                endReached = items.size() < PAGE_SIZE;
            });
        });
    }

    @Override
    protected void onDestroy() {
        if (adapter != null) adapter.close();
        if (pageTask != null) pageTask.cancel(true);
        pageTask = null;
        executor.shutdownNow();
        super.onDestroy();
    }
}
