package com.lemenzo.gallery.search;

import android.content.Context;

import com.lemenzo.gallery.data.MediaRepository;
import com.lemenzo.gallery.model.MediaItem;
import com.lemenzo.gallery.smart.LocalVisualClassifier;
import com.lemenzo.gallery.viewer.MotionPhotoUtils;

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

/** Memory-bounded local search. Scans MediaStore pages without retaining the entire library. */
public final class SearchViewModel {
    private static final int PAGE_SIZE=400, MAX_RESULTS=2000;
    private final MediaRepository repository;
    private final SearchEngine engine=new SearchEngine();
    private final Context context;
    private final LocalVisualClassifier visualClassifier;

    public static final class Result { public final List<MediaItem> items; public final boolean truncated; Result(List<MediaItem> i,boolean t){items=i;truncated=t;} }
    public SearchViewModel(Context context){this.context=context.getApplicationContext();repository=new MediaRepository(context);visualClassifier=new LocalVisualClassifier(this.context);}
    public void load(){}

    public Result search(String query){
        ArrayList<MediaItem> results=new ArrayList<>();
        boolean blank=query==null||query.trim().isEmpty();
        if(blank)return new Result(results,false);
        MediaItem anchor=null; boolean truncated=false;
        while(!Thread.currentThread().isInterrupted()){
            List<MediaItem> page=repository.pageAfter(anchor,PAGE_SIZE); if(page.isEmpty())break;
            List<MediaItem> matches=engine.filter(page,query,
                    item -> MotionPhotoUtils.findVideoLength(context,item.uri)>0L,
                    new SearchEngine.VisualVerifier(){
                        @Override public boolean isVisualDocument(MediaItem item){return visualClassifier.isDocument(item);}
                        @Override public boolean isSelfie(MediaItem item){return visualClassifier.isSelfie(item);}
                    });
            for(MediaItem item:matches){if(results.size()<MAX_RESULTS)results.add(item);else{truncated=true;break;}}
            if(truncated||page.size()<PAGE_SIZE)break; anchor=page.get(page.size()-1);
        }
        return new Result(results,truncated);
    }
}
