package com.lemenzo.gallery.data;

import android.content.Context;

import com.lemenzo.gallery.model.Album;
import com.lemenzo.gallery.model.MediaItem;
import com.lemenzo.gallery.model.MediaType;

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

/** Builds album summaries with seek paging so very large libraries do not pay growing OFFSET cost. */
public final class AlbumRepository {
    private static final int PAGE_SIZE = 400;
    private final MediaRepository media;

    public AlbumRepository(Context context) {
        media = new MediaRepository(context);
    }

    public List<Album> load() {
        LinkedHashMap<Long, Mutable> albums = new LinkedHashMap<>();
        MediaItem anchor = null;

        while (!Thread.currentThread().isInterrupted()) {
            List<MediaItem> page = media.pageAfter(anchor, PAGE_SIZE);
            if (page.isEmpty()) break;

            for (MediaItem item : page) {
                Mutable album = albums.get(item.bucketId);
                if (album == null) {
                    album = new Mutable(item.bucketId, item.bucketName, item.uri, item.sortDate());
                    albums.put(item.bucketId, album);
                }
                album.count++;
                if (item.type == MediaType.IMAGE) album.photos++;
                else album.videos++;

                if (item.sortDate() > album.date) {
                    album.date = item.sortDate();
                    album.cover = item.uri;
                }
            }

            anchor = page.get(page.size() - 1);
            if (page.size() < PAGE_SIZE) break;
        }

        ArrayList<Album> out = new ArrayList<>(albums.size());
        for (Mutable album : albums.values()) {
            out.add(new Album(
                    album.id,
                    album.name,
                    album.cover,
                    album.count,
                    album.photos,
                    album.videos,
                    album.date));
        }
        out.sort((a, b) -> Long.compare(b.latestDate, a.latestDate));
        return out;
    }

    private static final class Mutable {
        long id;
        long date;
        String name;
        android.net.Uri cover;
        int count;
        int photos;
        int videos;

        Mutable(long id, String name, android.net.Uri cover, long date) {
            this.id = id;
            this.name = name;
            this.cover = cover;
            this.date = date;
        }
    }
}
