package info.puzz.a10000sentences.logic;

import android.content.Context;
import android.os.AsyncTask;

import com.activeandroid.query.Select;

import java.security.SecureRandom;
import java.util.List;
import java.util.Random;

import javax.inject.Inject;

import info.puzz.a10000sentences.Preferences;
import info.puzz.a10000sentences.dao.Dao;
import info.puzz.a10000sentences.models.Sentence;
import info.puzz.a10000sentences.models.SentenceCollection;
import info.puzz.a10000sentences.models.SentenceHistory;
import info.puzz.a10000sentences.models.SentenceStatus;

public final class SentenceCollectionsService {

    private static final Random RANDOM = new SecureRandom(String.valueOf(System.currentTimeMillis()).getBytes());

    private final Dao dao;

    public SentenceCollectionsService(Dao dao) {
        this.dao = dao;
    }

    public Sentence nextSentence(Context context, SentenceCollection collection, String exceptSentenceId) {
        int maxRepeat = Preferences.getMaxRepeat(context);
        int status = SentenceStatus.TODO.getStatus();
        if (RANDOM.nextInt(maxRepeat) < collection.repeatCount) {
            // New sentence:
            status = SentenceStatus.REPEAT.getStatus();
        }

        return getRandomSentenceByStatus(collection, status, exceptSentenceId);
    }

    public Sentence getRandomKnownSentence(Context context, SentenceCollection collection, String exceptSentenceId) {
        return new Select()
                .from(Sentence.class)
                .where("collection_id=? and status=? and sentence_id<>?", collection.collectionID, SentenceStatus.DONE.getStatus(), String.valueOf(exceptSentenceId))
                .orderBy("random()")
                .executeSingle();
    }

    private Sentence getRandomSentenceByStatus(SentenceCollection collection, int status, String exceptSentenceId) {
        List<Sentence> sentences = new Select()
                .from(Sentence.class)
                .where("collection_id=? and status=? and sentence_id!=?", collection.getCollectionID(), status, String.valueOf(exceptSentenceId))
                .orderBy("complexity")
                .limit(20)
                .execute();
        if (sentences.size() == 0) {
            return null;
        }
        return sentences.get(RANDOM.nextInt(sentences.size()));
    }

    public void updateStatus(final Sentence sentence, final SentenceStatus status, final long started) {
        sentence.status = status.getStatus();
        sentence.save();

        new AsyncTask<String, Void, Void>() {
            @Override
            protected Void doInBackground(String... strings) {
                SentenceCollection collection = dao.reloadCollectionCounter(dao.getCollection(sentence.collectionId));

                SentenceHistory h = new SentenceHistory();
                h.sentenceId = sentence.getSentenceId();
                h.collectionId = sentence.collectionId;
                h.status = status.getStatus();
                h.created = System.currentTimeMillis();
                h.time = (int) (System.currentTimeMillis() - started);
                h.doneCount = collection.doneCount;
                h.todoCount = collection.todoCount;
                h.repeatCount = collection.repeatCount;
                h.ignoreCount = collection.ignoreCount;
                h.save();

                return null;
            }
        }.execute();
    }
}

@@ -95,16 +95,41 @@
 yncTask;
+%0Aimport android.util.Log;
 %0A%0Aimport
@@ -197,16 +197,42 @@
 Random;%0A
+import java.util.HashMap;%0A
 import j
@@ -246,16 +246,38 @@
 l.List;%0A
+import java.util.Map;%0A
 import j
@@ -293,17 +293,16 @@
 Random;%0A
-%0A
 import j
@@ -308,22 +308,32 @@
 java
-x.inject.Injec
+.util.concurrent.TimeUni
 t;%0A%0A
@@ -693,16 +693,105 @@
 vice %7B%0A%0A
+    private static final String TAG = SentenceCollectionsService.class.getSimpleName();%0A%0A
     priv
@@ -1400,78 +1400,277 @@
     
-return getRandomSentenceByStatus(collection, status, exceptSentenceId)
+Sentence result = getRandomSentenceByStatus(collection, SentenceStatus.fromStatus(status), exceptSentenceId);%0A        if (result == null) %7B%0A            return getRandomSentenceByStatus(collection, SentenceStatus.TODO, exceptSentenceId);%0A        %7D%0A%0A        return result
 ;%0A  
@@ -1807,16 +1807,17 @@
  return 
+ 
 new Sele
@@ -2181,19 +2181,30 @@
 ection, 
-int
+SentenceStatus
  status,
@@ -2423,24 +2423,36 @@
 ID(), status
+.getStatus()
 , String.val
@@ -2565,24 +2565,1115 @@
 .execute();%0A
+%0A        if (status == SentenceStatus.REPEAT) %7B%0A            // REPEAT sentences are special because we don't want them to be repeated immediately after%0A            // the user failed to guess them. So, find the oldest one:%0A            Map%3CString, Long%3E sentenceTakenTime = new HashMap%3C%3E();%0A            List%3CSentenceHistory%3E senHist = new Select()%0A                    .from(SentenceHistory.class)%0A                    .orderBy(%22created%22)%0A                    .limit(200)%0A                    .execute();%0A            for (SentenceHistory sh : senHist) %7B%0A                sentenceTakenTime.put(sh.sentenceId, sh.created);%0A            %7D%0A%0A            for (Sentence sentence : sentences) %7B%0A                Long timeTaken = sentenceTakenTime.get(sentence.sentenceId);%0A                if (timeTaken == null) %7B // Longer than the sample of history we took =%3E OK:%0A                    return sentence;%0A                %7D%0A%0A                if (System.currentTimeMillis() - timeTaken.longValue() %3E TimeUnit.MINUTES.toMillis(3)) %7B%0A                    return sentence;%0A                %7D%0A            %7D%0A        %7D%0A%0A
         if (
@@ -4892,8 +4892,9 @@
     %7D%0A%7D%0A
+%0A

Better calculation for which REPEAT sentence to choose