package org.stepic.droid.receivers;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.widget.Toast;

import org.stepic.droid.R;
import org.stepic.droid.analytic.Analytic;
import org.stepic.droid.base.App;
import org.stepic.droid.concurrency.SingleThreadExecutor;
import org.stepic.droid.core.downloads.contract.DownloadsPoster;
import org.stepic.droid.model.CachedVideo;
import org.stepic.droid.model.DownloadEntity;
import org.stepic.droid.model.Lesson;
import org.stepic.droid.model.Step;
import org.stepic.droid.preferences.UserPreferences;
import org.stepic.droid.storage.CancelSniffer;
import org.stepic.droid.storage.StoreStateManager;
import org.stepic.droid.storage.operations.DatabaseFacade;
import org.stepic.droid.util.AppConstants;
import org.stepic.droid.util.RWLocks;
import org.stepic.droid.util.StorageUtil;

import java.io.File;

import javax.inject.Inject;

import timber.log.Timber;

import static org.stepic.droid.storage.DownloadManagerExtensionKt.getDownloadStatus;

public class DownloadCompleteReceiver extends BroadcastReceiver {
    @Inject
    DownloadManager systemDownloadManager;

    @Inject
    UserPreferences userPreferences;

    @Inject
    DatabaseFacade databaseFacade;

    @Inject
    StoreStateManager storeStateManager;

    @Inject
    CancelSniffer cancelSniffer;

    @Inject
    SingleThreadExecutor threadSingleThreadExecutor;

    @Inject
    DownloadManager downloadManager;

    @Inject
    Analytic analytic;

    @Inject
    DownloadsPoster downloadsPoster;

    public DownloadCompleteReceiver() {
        Timber.d("create DownloadCompleteReceiver");
        App.Companion
                .componentManager()
                .downloadsComponent()
                .inject(this);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        final long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        final PendingResult result = goAsync();
        if (referenceId >= 0) {
            threadSingleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        blockForInBackground(referenceId);
                    } finally {
                        result.finish();
                    }

                }
            });
        }
    }

    private void blockForInBackground(final long referenceId) {
        try {
            RWLocks.DownloadLock.writeLock().lock();

            final DownloadEntity downloadEntity = databaseFacade.getDownloadEntityIfExist(referenceId);
            if (downloadEntity != null) {
                final long step_id = downloadEntity.getStepId();
                databaseFacade.deleteDownloadEntityByDownloadId(referenceId);


                if (cancelSniffer.isStepIdCanceled(step_id)) {
                    downloadManager.remove(referenceId);//remove notification (is it really work and need?)
                    cancelSniffer.removeStepIdCancel(step_id);
                } else {
                    //is not canceled
                    final Step step = databaseFacade.getStepById(step_id);
                    if (step == null) return;
                    final long status = getDownloadStatus(systemDownloadManager, referenceId);

                    final CachedVideo cachedVideo;
                    if (status == DownloadManager.STATUS_SUCCESSFUL) {
                        cachedVideo = prepareCachedVideo(downloadEntity);
                        databaseFacade.addVideo(cachedVideo);
                        step.set_cached(true);
                    } else {
                        cachedVideo = null;
                        step.set_cached(false);
                    }

                    step.set_loading(false);
                    databaseFacade.updateOnlyCachedLoadingStep(step);
                    storeStateManager.updateUnitLessonState(step.getLesson());

                    final Lesson lesson = databaseFacade.getLessonById(step.getLesson());
                    Handler mainHandler = new Handler(App.Companion.getAppContext().getMainLooper());
                    //Say to ui that ui is cached now
                    Runnable myRunnable = new Runnable() {
                        @Override
                        public void run() {
                            if (lesson != null) {
                                if (cachedVideo != null) {
                                    downloadsPoster.downloadComplete(step_id, lesson, cachedVideo);
                                } else {
                                    final Context context = App.Companion.getAppContext();
                                    Toast.makeText(context, context.getString(R.string.video_download_fail, lesson.getTitle()), Toast.LENGTH_SHORT).show();
                                    analytic.reportEvent(Analytic.Error.DOWNLOAD_FAILED);
                                    downloadsPoster.downloadFailed(referenceId);
                                }
                            }
                        }
                    };
                    mainHandler.post(myRunnable);
                }
            } else {
                if (referenceId < 0) {
                    analytic.reportError(Analytic.Error.DOWNLOAD_ID_NEGATIVE, new IllegalArgumentException("ReferenceId was " + referenceId));
                } else {
                    downloadManager.remove(referenceId);//remove notification (is it really work and need?)
                }
            }
        } finally {
            RWLocks.DownloadLock.writeLock().unlock();
        }
    }

    private CachedVideo prepareCachedVideo(DownloadEntity downloadEntity) {
        final long video_id = downloadEntity.getVideoId();
        final long step_id = downloadEntity.getStepId();

        File userDownloadFolder = userPreferences.getUserDownloadFolder();
        File downloadFolderAndFile = new File(userDownloadFolder, video_id + "");
        String path = Uri.fromFile(downloadFolderAndFile).getPath();
        String thumbnail = downloadEntity.getThumbnail();
        if (userPreferences.isSdChosen()) {
            File sdFile = userPreferences.getSdCardDownloadFolder();
            if (sdFile != null) {
                try {
                    StorageUtil.moveFile(userDownloadFolder.getPath(), video_id + "", sdFile.getPath());
                    StorageUtil.moveFile(userDownloadFolder.getPath(), video_id + AppConstants.THUMBNAIL_POSTFIX_EXTENSION, sdFile.getPath());
                    downloadFolderAndFile = new File(sdFile, video_id + "");
                    final File thumbnailFile = new File(sdFile, video_id + AppConstants.THUMBNAIL_POSTFIX_EXTENSION);
                    path = Uri.fromFile(downloadFolderAndFile).getPath();
                    thumbnail = Uri.fromFile(thumbnailFile).getPath();
                } catch (Exception er) {
                    analytic.reportError(Analytic.Error.FAIL_TO_MOVE, er);
                }
            }

        }

        final CachedVideo cachedVideo = new CachedVideo(step_id, video_id, path, thumbnail);
        cachedVideo.setQuality(downloadEntity.getQuality());
        return cachedVideo;
    }

}
@@ -1497,23 +1497,17 @@
 xecutor 
-threadS
+s
 ingleThr
@@ -2050,16 +2050,78 @@
 D, -1);%0A
+        if (referenceId %3C 0) %7B%0A            return;%0A        %7D%0A%0A
         
@@ -2172,51 +2172,9 @@
     
-if (referenceId %3E= 0) %7B%0A            threadS
+s
 ingl
@@ -2218,36 +2218,32 @@
 ) %7B%0A            
-    
 @Override%0A      
@@ -2228,36 +2228,32 @@
       @Override%0A
-    
             publ
@@ -2280,38 +2280,30 @@
             
- 
-   
 try %7B%0A
-    
             
@@ -2357,28 +2357,24 @@
             
-   
- 
 %7D finally %7B%0A
@@ -2365,36 +2365,32 @@
     %7D finally %7B%0A
-    
                 
@@ -2406,28 +2406,24 @@
 t.finish();%0A
-    
             
@@ -2420,37 +2420,32 @@
               %7D%0A
-%0A    
             %7D%0A  
@@ -2454,25 +2454,11 @@
     
-    %7D);%0A        %7D
+%7D);
 %0A   

fix bug with goAsync in DownloadCompleteReceiver