package com.lemenzo.gallery.viewer;

import android.content.Context;
import com.lemenzo.gallery.data.MediaRepository;
import com.lemenzo.gallery.model.MediaItem;
import java.util.ArrayList;
import java.util.List;

/** Incremental viewer navigation over very large libraries. */
public final class ViewerViewModel {
    public static final int PAGE_SIZE = 240;
    private final MediaRepository repository;

    public static final class Window {
        public final List<MediaItem> items;
        public final int startOffset;
        public final boolean endReached;
        Window(List<MediaItem> items, int startOffset, boolean endReached) {
            this.items = items; this.startOffset = startOffset; this.endReached = endReached;
        }
    }

    public ViewerViewModel(Context context) { repository = new MediaRepository(context); }

    public Window loadWindow(String targetUri) {
        int anchorOffset = repository.findOffsetForUri(targetUri);
        if (anchorOffset >= 0) {
            int start = Math.max(0, anchorOffset - PAGE_SIZE);
            List<MediaItem> window = repository.page(start, PAGE_SIZE * 3);
            if (find(window, targetUri) >= 0) {
                return new Window(window, start, window.size() < PAGE_SIZE * 3);
            }
        }
        // Rare compatibility fallback for providers unable to expose an anchor offset.
        int pageOffset = 0;
        while (!Thread.currentThread().isInterrupted()) {
            List<MediaItem> page = repository.page(pageOffset, PAGE_SIZE);
            if (page.isEmpty()) return new Window(new ArrayList<>(), 0, true);
            if (find(page, targetUri) >= 0) {
                int start = Math.max(0, pageOffset - PAGE_SIZE);
                List<MediaItem> window = repository.page(start, PAGE_SIZE * 3);
                return new Window(window, start, window.size() < PAGE_SIZE * 3);
            }
            if (page.size() < PAGE_SIZE) return new Window(page, pageOffset, true);
            pageOffset += page.size();
        }
        return new Window(new ArrayList<>(), 0, true);
    }

    public List<MediaItem> nextPage(int startOffset, int currentSize) {
        return repository.page(startOffset + currentSize, PAGE_SIZE);
    }

    public List<MediaItem> previousPage(int startOffset) {
        if (startOffset <= 0) return new ArrayList<>();
        int from = Math.max(0, startOffset - PAGE_SIZE);
        return repository.page(from, startOffset - from);
    }

    public int find(List<MediaItem> items, String uri) {
        if (uri == null) return -1;
        for (int i = 0; i < items.size(); i++) if (items.get(i).uri.toString().equals(uri)) return i;
        return -1;
    }
}
