package com.sheep.jiuyan.samllsheep.service;

import android.app.Activity;
import android.app.DownloadManager;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.view.View;

import com.kfzs.duanduan.utils.ApkUtils;
import com.kfzs.duanduan.view.DialogStorageLow;
import com.liulishuo.okdownload.DownloadListener;
import com.liulishuo.okdownload.DownloadTask;
import com.liulishuo.okdownload.SpeedCalculator;
import com.liulishuo.okdownload.core.breakpoint.BlockInfo;
import com.liulishuo.okdownload.core.breakpoint.BreakpointInfo;
import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.listener.DownloadListener4WithSpeed;
import com.liulishuo.okdownload.core.listener.assist.Listener4SpeedAssistExtend;
import com.sheep.gamegroup.event.BigEvent;
import com.sheep.gamegroup.event.EventTypes;
import com.sheep.gamegroup.greendao.DDProviderHelper;
import com.sheep.gamegroup.greendao.download.DownLoadInfo;
import com.sheep.gamegroup.model.entity.Applications;
import com.sheep.gamegroup.model.entity.TaskEty;
import com.sheep.gamegroup.util.ActivityManager;
import com.sheep.gamegroup.util.DownloadUtil;
import com.sheep.gamegroup.util.LogUtil;
import com.sheep.gamegroup.util.StringUtils;
import com.sheep.jiuyan.samllsheep.utils.G;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static com.sheep.jiuyan.samllsheep.utils.ClassFileHelper.DIR;

/**
 * @auther realicing
 * 自动更新的Service
 */

public class DownloadService extends Service {

    private DownloadUtil downloadUtil;

    @Override
    public void onCreate() {
        super.onCreate();
        downloadUtil = new DownloadUtil();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String download_url = intent.getStringExtra("download_url");
            String file_path = intent.getStringExtra("file_path");
            if (download_url != null && file_path != null) {
                DownloadTask task = DownloadUtil.getTask(download_url, file_path);
                task.enqueue(downloadListener);
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private DownloadListener downloadListener = new DownloadListener4WithSpeed() {
        @Override
        public void taskStart(@NonNull DownloadTask task) {
            LogUtil.println("DownloadListener", "taskStart");
            DDProviderHelper.getInstance().updateDownload(task.getId(), task.getUrl(), DownloadUtil.STATUS_INIT);
        }

        @Override
        public void connectStart(@NonNull DownloadTask task, int blockIndex, @NonNull Map<String, List<String>> requestHeaderFields) {
            LogUtil.println("DownloadListener", "connectStart", "blockIndex", blockIndex);
        }

        @Override
        public void connectEnd(@NonNull DownloadTask task, int blockIndex, int responseCode, @NonNull Map<String, List<String>> responseHeaderFields) {
            LogUtil.println("DownloadListener", "connectEnd", "blockIndex", blockIndex, "responseCode", responseCode);
        }

        @Override
        public void infoReady(@NonNull DownloadTask task, @NonNull BreakpointInfo info, boolean fromBreakpoint, @NonNull Listener4SpeedAssistExtend.Listener4SpeedModel model) {
            long totalLength = info.getTotalLength();
            LogUtil.println("DownloadListener", "infoReady", "fromBreakpoint", fromBreakpoint, "totalLength", totalLength);
            DownLoadInfo downloadInfo = downloadUtil.setDownloadTaskTotal(task.getUrl(), totalLength);
            EventBus.getDefault().post(new BigEvent().setEventTypes(EventTypes.DOWNLOAD_START).setData(downloadInfo));
        }

        @Override
        public void progressBlock(@NonNull DownloadTask task, int blockIndex, long currentBlockOffset, @NonNull SpeedCalculator blockSpeed) {
            LogUtil.println("DownloadListener", "progressBlock", "blockIndex", blockIndex, "currentBlockOffset", currentBlockOffset, "blockSpeed", blockSpeed.averageSpeed());
        }

        @Override
        public void progress(@NonNull DownloadTask task, long currentOffset, @NonNull SpeedCalculator taskSpeed) {
            LogUtil.println("DownloadListener", "progress", "currentOffset", currentOffset, "taskSpeed", taskSpeed.averageSpeed());
            DownLoadInfo downloadInfo = downloadUtil.setDownloadTaskPercent(currentOffset, taskSpeed.averageSpeed(), task.getId(), task.getUrl());
            EventBus.getDefault().post(new BigEvent().setEventTypes(EventTypes.DOWNLOAD_RUNNING).setData(downloadInfo));
        }

        @Override
        public void blockEnd(@NonNull DownloadTask task, int blockIndex, BlockInfo info, @NonNull SpeedCalculator blockSpeed) {
            LogUtil.println("DownloadListener", "blockEnd", "blockIndex", blockIndex, "blockSpeed", blockSpeed.averageSpeed());
        }

        @Override
        public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull SpeedCalculator taskSpeed) {
            LogUtil.println("DownloadListener", "taskEnd", "cause", cause.name(), "realCause", realCause != null ? realCause.getMessage() : "null", "taskSpeed", taskSpeed.averageSpeed());
            DownLoadInfo downLoadInfo;
            switch (cause) {
                case COMPLETED://下载完成
                    if (task.getFile() != null) {
                        downLoadInfo = downloadUtil.setDownloadTaskFinish(task.getUrl(), task.getFile().getAbsolutePath());
                        ApkUtils.installApk(getApplicationContext(), task.getFile().getAbsolutePath());
                        EventBus.getDefault().post(new BigEvent().setEventTypes(EventTypes.DOWNLOAD_COMPLETE).setData(downLoadInfo));
                    }
                    break;
                case PRE_ALLOCATE_FAILED://预先分配失败
                    //空间不足，弹框提示
                    try {
                        DialogStorageLow.showDialog(realCause != null ? realCause.getMessage() : null);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    downLoadInfo = downloadUtil.getDownloadTaskByUrl(task.getUrl());
                    downLoadInfo.setMStatus(DownloadUtil.STATUS_FAIL);
                    if(realCause != null)
                        downLoadInfo.setRealCauseMsg(realCause.getMessage());
                    DDProviderHelper.getInstance().updateDownload(downLoadInfo);
                    EventBus.getDefault().post(new BigEvent().setEventTypes(EventTypes.DOWNLOAD_FAIL).setData(downLoadInfo));
                    break;
                case FILE_BUSY:
                case ERROR://下载错误
                    //空间不足，弹框提示
                    try {
                        if (0 <= task.getReadBufferSize() && task.getReadBufferSize() > G.getFreeSpaceB()) {
                            DialogStorageLow.showDialog(realCause != null ? realCause.getMessage() : null);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    downLoadInfo = downloadUtil.getDownloadTaskByUrl(task.getUrl());
                    downLoadInfo.setMStatus(DownloadUtil.STATUS_FAIL);
                    if(realCause != null)
                        downLoadInfo.setRealCauseMsg(realCause.getMessage());
                    DDProviderHelper.getInstance().updateDownload(downLoadInfo);
                    EventBus.getDefault().post(new BigEvent().setEventTypes(EventTypes.DOWNLOAD_FAIL).setData(downLoadInfo));
                    break;
                case CANCELED://取消下载
                    downLoadInfo = downloadUtil.setDownloadTaskStatus(task.getUrl(), DownloadUtil.STATUS_PAUSE);
                    EventBus.getDefault().post(new BigEvent().setEventTypes(EventTypes.DOWNLOAD_STOP).setData(downLoadInfo));
                    break;
                case SAME_TASK_BUSY:
                    break;
            }

        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    public static void setDownLoadLongClick(View view, final TaskEty task) {
        if (task != null && task.needDownloadApp())
            setDownLoadLongClick(view, task.getDownload_link(), task.getTask_name());
    }

    public static void setDownLoadLongClick(View view, final Applications task) {
        if (task != null && !TextUtils.isEmpty(task.getDownload_link()))
            setDownLoadLongClick(view, task.getDownload_link(), task.getTask_name());
    }

    public static void setDownLoadLongClick(View view, final String link, final String taskName) {
        view.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                showDownloadType(link, taskName);
                return true;
            }
        });
    }

    private static void showDownloadType(final String link, final String taskName) {
        final Activity activity = ActivityManager.getInstance().currentActivity();
        if (activity == null) {
            return;
        }
        final String[] items = {"复制下载地址", "系统下载", "浏览器下载"};
        AlertDialog dialog = new AlertDialog.Builder(activity).setTitle("请选择操作")
                .setItems(items, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        try {
                            switch (items[which]) {
                                case "复制下载地址":
                                    copyDownloadLink(link);
                                    break;
                                case "系统下载":
                                    sysDownload(activity, link, taskName);
                                    break;
                                case "浏览器下载":
                                    webDownload(activity, link);
                                    break;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            G.showToast(e.getMessage());
                        }
                    }
                }).create();
        dialog.show();
    }

    private static void copyDownloadLink(final String link) {
        if (StringUtils.CopyText(link)) {
            G.showToast("已经复制游戏下载链接");
        }
    }

    public static void sysDownload(final Context context, String link, String taskName) {
        sysDownload(context, link, taskName, String.format(Locale.CHINA, "小绵羊【%s】中的app下载", taskName), taskName + link.hashCode() + ".apk", "系统开始下载apk");
    }

    public static void sysDownload(final Context context, String downloadLink, String title, String description, String fileName, String toast) {
        // 创建下载请求
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadLink));

        /*
         * 设置在通知栏是否显示下载通知(下载进度), 有 3 个值可选:
         *    VISIBILITY_VISIBLE:                   下载过程中可见, 下载完后自动消失 (默认)
         *    VISIBILITY_VISIBLE_NOTIFY_COMPLETED:  下载过程中和下载完成后均可见
         *    VISIBILITY_HIDDEN:                    始终不显示通知
         */
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

        // 设置通知的标题和描述
        request.setTitle(title);
        request.setDescription(description);

        /*
         * 设置允许使用的网络类型, 可选值:
         *     NETWORK_MOBILE:      移动网络
         *     NETWORK_WIFI:        WIFI网络
         *     NETWORK_BLUETOOTH:   蓝牙网络
         * 默认为所有网络都允许
         */
//                     request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);

        // 添加请求头
        // request.addRequestHeader("User-Agent", "Chrome Mozilla/5.0");
        if (fileName != null) {
            // 设置下载文件的保存位置
            File saveFile = new File(DIR, fileName);
            request.setDestinationUri(Uri.fromFile(saveFile));
        }

        /*
         * 2. 获取下载管理器服务的实例, 添加下载任务
         */
        DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        if (manager != null) {
            // 将下载请求加入下载队列, 返回一个下载ID
            long downloadId = manager.enqueue(request);
            if (toast != null)
                G.showToast(toast);
        }
    }

    public static void webDownload(final Context context, String downloadLink) {
        if (context instanceof Activity) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_BROWSABLE);
            intent.setData(Uri.parse(downloadLink));
            context.startActivity(intent);
            G.showToast("浏览器开始下载apk");
        }
    }
}
