package com.ifavine.pay.utils;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;


import com.ifavine.pay.R;
import com.ifavine.pay.common.AppConfig;
import com.ifavine.pay.ui.activity.MainActivity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by tree on 10/8/2016.
 */

public class DownloadService extends Service {

    public static final String BUNDLE_KEY_DOWNLOAD_URL = "URL";
    public static final String BUNDLE_KEY_DOWNLOAD_FILE = "FILE";
    public static final String BUNDLE_KEY_TITLE = "title";
    private static final int NOTIFY_ID = 0;
    private static final int APP_DOWN_ERROR = 123;
    private int progress;
    private NotificationManager mNotificationManager;
    private boolean canceled;

    private String downloadUrl = "";

    private String mTitle = null;

    private String filePath = AppConfig.DEFAULT_SAVE_FILE_PATH;
    private String fileName = "TopOA.apk";

    private ICallbackResult callback;

    private DownloadBinder binder;

    private boolean serviceIsDestroy = false;

    private Context mContext = this;

    private Thread mDownLoadThread;

    private Notification mNotification;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    // 下载完毕
                    mNotificationManager.cancel(NOTIFY_ID);
                    installApk();
                    break;
                case 2:
                    // 取消通知
                    mNotificationManager.cancel(NOTIFY_ID);
                    break;
                case 1:
                    int rate = msg.arg1;
                    if (rate < 100) {
                        RemoteViews contentview = mNotification.contentView;
                        contentview.setTextViewText(R.id.tv_download_state,
                                mTitle + "(" + rate + "%" + ")");
                        contentview.setProgressBar(R.id.pb_download, 100, rate, false);
                    } else {
                        // 下载完毕后变换通知形式
                        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
                        mNotification.contentView = null;
                        Intent intent = new Intent(mContext, MainActivity.class);
                        // 告知已完成
                        intent.putExtra("completed", "yes");
                        // 更新参数，注意flags要使用 FLAG_UPDATE_CURRRENT
                        PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent,
                                PendingIntent.FLAG_UPDATE_CURRENT);
                        serviceIsDestroy = true;
                        stopSelf();  // 停掉服务自身
                    }
                    mNotificationManager.notify(NOTIFY_ID, mNotification);
                    break;
                case APP_DOWN_ERROR:
                    mNotificationManager.cancel(NOTIFY_ID);
                    Intent i = new Intent();
                    i.putExtra("URL", downloadUrl);
                    i.putExtra("FILE", fileName);
                    i.setClass(DownloadService.this, DownloadService.class);
                    RemoteViews contentView =
                            new RemoteViews(getPackageName(), R.layout.download_notification_show);
                    contentView.setTextViewText(R.id.tv_download_state, getString(R.string.app_download_fail));
                    // 指定个性化视图
                    mNotification.contentView = contentView;
                    PendingIntent pdi = PendingIntent.getService(
                            DownloadService.this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
                    mNotification.contentIntent = pdi;
                    mNotificationManager.notify(NOTIFY_ID, mNotification);
                    break;
            }
        }
    };


    @Override
    public IBinder onBind(Intent intent) {


        return binder;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        mTitle = getResources().getString(R.string.app_downloading);
        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        stopForeground(true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        downloadUrl = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_URL);
        fileName = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_FILE);
        binder = new DownloadBinder();
        binder.start();
        return super.onStartCommand(intent, flags, startId);
    }

    private void startDownload() {
        canceled = false;
        downloadApk();
    }

    /**
     * 创建通知
     */
    private void setUpNotification() {
        int icon = R.mipmap.icon;
        CharSequence tickerText = "准备下载";
        long when = System.currentTimeMillis();
        mNotification = new Notification(icon, tickerText, when);

        //    放置在"正在运行"栏目中
        mNotification.flags = Notification.FLAG_ONGOING_EVENT;

        RemoteViews contentView =
                new RemoteViews(getPackageName(), R.layout.download_notification_show);
        contentView.setTextViewText(R.id.tv_download_state, mTitle);

        // 指定个性化视图
        mNotification.contentView = contentView;

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent contentIntent =
                PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        // 指定内容意图
        mNotification.contentIntent = contentIntent;
        mNotificationManager.notify(NOTIFY_ID, mNotification);
    }

    private void downloadApk() {
        mDownLoadThread = new Thread(mDownApkRunnable);
        mDownLoadThread.start();
    }

    /**
     * 安装apk
     */
    private void installApk() {
        File apkfile = new File(filePath + fileName);
        TLog.log("aaa", apkfile.getAbsolutePath());
        if (!apkfile.exists()) {
            return;
        }
        TDevice.installAPK(mContext, apkfile);
    }

    private Runnable mDownApkRunnable = new Runnable() {
        @Override
        public void run() {
            File file = new File(AppConfig.DEFAULT_SAVE_FILE_PATH);
            if (!file.exists()) {
                file.mkdirs();
            }
            File saveFile = new File(filePath + fileName);
            try {
                downloadUpdateFile(downloadUrl, saveFile);
            } catch (Exception e) {
                e.printStackTrace();
                Message message = new Message();
                message.what = APP_DOWN_ERROR;
                mHandler.sendMessage(message);
            }
        }
    };

    public long downloadUpdateFile(String downloadUrl, File saveFile) throws Exception {
        int downloadCount = 0;
        int currentSize = 0;
        long totalSize = 0;
        int updateTotalSize = 0;

        HttpURLConnection httpConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;

        try {
            URL url = new URL(downloadUrl);
            httpConnection = (HttpURLConnection) url.openConnection();
            httpConnection.setRequestProperty("User-Agent", "PacificHttpClient");
            if (currentSize > 0) {
                httpConnection.setRequestProperty("RANGE", "bytes=" + currentSize + "-");
            }
            httpConnection.setConnectTimeout(10000);
            httpConnection.setReadTimeout(20000);
            updateTotalSize = httpConnection.getContentLength();
            if (httpConnection.getResponseCode() == 404) {
                throw new Exception("fail");
            }
            is = httpConnection.getInputStream();
            fos = new FileOutputStream(saveFile, false);
            byte buffer[] = new byte[1024];
            int readsize = 0;
            while ((readsize = is.read(buffer)) > 0) {
                fos.write(buffer, 0, readsize);
                totalSize += readsize;
                //    为了防止频繁的通知导致应用吃紧， 百分比增加10才通知一次
                if ((downloadCount == 0)
                        || (int) (totalSize * 100 / updateTotalSize) - 4 > downloadCount) {
                    downloadCount += 4;
                    //更新进度
                    Message msg = mHandler.obtainMessage();
                    msg.what = 1;
                    msg.arg1 = downloadCount;
                    mHandler.sendMessage(msg);
                    if (callback != null)
                        callback.OnBackResult(progress);
                }
            }

            // 下载完成通知安装
            mHandler.sendEmptyMessage(0);
            // 下载完了，cancelled也要设置
            canceled = true;
        } finally {
            if (httpConnection != null) {
                httpConnection.disconnect();
            }
            if (is != null) {
                is.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
        return totalSize;
    }

    public class DownloadBinder extends Binder {
        public void start() {
            if (mDownLoadThread == null || !mDownLoadThread.isAlive()) {
                progress = 0;
                setUpNotification();
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        // 下载
                        Log.i("aaaaaa", "DownloadBinder start");
                        startDownload();
                    }
                }.start();
            }
        }

        public void cancel() {
            canceled = true;
        }

        public int getProgress() {
            return progress;
        }

        public boolean isCanceled() {
            return canceled;
        }

        public boolean serviceIsDestroy() {
            return serviceIsDestroy;
        }

        public void cancelNotification() {
            mHandler.sendEmptyMessage(2);
        }

        public void addCallback(ICallbackResult callback) {
            DownloadService.this.callback = callback;
        }
    }

    public interface ICallbackResult {
        public void OnBackResult(Object s);
    }


}
