package com.zxhl.cms.down

import android.app.DownloadManager
import android.content.Context.DOWNLOAD_SERVICE
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.text.TextUtils
import com.zxhl.cms.AppContext
import com.zxhl.cms.common.Constant
import com.zxhl.cms.net.ApiClient
import com.zxhl.cms.net.RxSchedulers
import com.zxhl.cms.net.SettingPreference
import com.zxhl.cms.net.callback.BaseObserver
import com.zxhl.cms.net.model.uc.VersionEntity
import com.zxhl.cms.utils.PhoneUtils
import com.zxhl.cms.utils.Utils
import io.reactivex.disposables.Disposable
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit


class UpdateVersionPresenter : UpdateVersionContract.Presenter {
    private lateinit var mView: UpdateVersionContract.View
    private var disposable: Disposable? = null
    private var mUrl: String = ""

    private val downloadManager: DownloadManager
    private var scheduledExecutorService: ScheduledExecutorService? = null

    constructor(mView: UpdateVersionContract.View) {
        this.mView = mView
        downloadManager = AppContext.get().getSystemService(DOWNLOAD_SERVICE) as DownloadManager

    }

    private val command = Runnable {
        kotlin.run {
            val size = getBytesAndStatus(downloadId)
            val progress = (size[0].toLong() * 100 / size[1].toLong())
            mView?.onDownloadProgress(100, progress)
            if (size[2] == DownloadManager.STATUS_SUCCESSFUL) {
                mView?.onDownloadComplete(downloadId.toString())
                scheduledExecutorService?.shutdown()
                scheduledExecutorService = null
            } else if (size[2] == DownloadManager.STATUS_PAUSED) {
                mView?.onDownloadError()
                scheduledExecutorService?.shutdown()
                scheduledExecutorService = null
            }
        }
    }

    override fun downloadApk() {
        if (TextUtils.isEmpty(mUrl)) {
            return
        }
        if (downloadId > 0) {
            try {
                downloadManager.remove(downloadId)
            } catch (ex: IllegalArgumentException) {
                ex.printStackTrace()
            }
        }
        val request = DownloadManager.Request(Uri.parse(mUrl))
        request.setDestinationInExternalFilesDir(
            AppContext.get(),
            Environment.DIRECTORY_DOWNLOADS,
            Constant.Param.mPacketName + ".apk"
        )
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE or DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            request.setRequiresDeviceIdle(false)
            request.setRequiresCharging(false)
        }
        //大于11版本手机允许扫描
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            //表示允许MediaScanner扫描到这个文件，默认不允许。
            request.allowScanningByMediaScanner()
        }
        request.setTitle(Constant.Param.mPacketName)
        request.setMimeType("application/vnd.android.package-archive")
        downloadId = downloadManager.enqueue(request)
        if (scheduledExecutorService == null) {
            scheduledExecutorService = Executors.newScheduledThreadPool(3)
        }
        scheduledExecutorService?.scheduleAtFixedRate(command, 0, 1, TimeUnit.SECONDS)
    }

    private var downloadId = 0L
    //三秒定时刷新一次

    override fun checkVersion(isShowToast: Boolean) {

        ApiClient.homeApi.getVersion().compose(RxSchedulers.observableIO2Main())
            .subscribe(object : BaseObserver<VersionEntity?>() {
                override fun onSuccess(dataBean: VersionEntity?) {
                    if (dataBean != null) {
                        if (dataBean.vc > PhoneUtils.getAppVersionCode(AppContext.get()) && "" != dataBean.dl_url) {
                            mUrl = dataBean.dl_url
                            if (dataBean.type == 1) {
                                SettingPreference.setCancelUpdateDate(AppContext.get(), "")
                                mView?.showMandatoryUpdateDialog(dataBean.vn, dataBean.description)
                            } else {
                                mView?.showNonMandatoryUpdateDialog(
                                    dataBean.vn,
                                    dataBean.description
                                )
                            }
                        } else {
                            if (isShowToast) {
                                mView?.onNoUpdate()
                            }
                        }
                    }else {
                        if (isShowToast) {
                            mView?.onNoUpdate()
                        }
                    }
                }

                override fun onFailure(e: Throwable, code: String, errorMsg: String?) {
                    if (isShowToast) {
                        mView?.onNoUpdate()
                    }
                    if (TextUtils.equals("105", code)) {
                        Utils.showToast(AppContext.get(), errorMsg)
                    }
                }
            })
    }

    fun getBytesAndStatus(downloadId: Long): IntArray {
        val bytesAndStatus = intArrayOf(-1, -1, 0)
        val query = DownloadManager.Query().setFilterById(downloadId)
        var c: Cursor? = null
        try {
            c = downloadManager.query(query)
            if (c != null && c?.moveToFirst()) {
                bytesAndStatus[0] =
                    c?.getInt(c?.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
                bytesAndStatus[1] =
                    c?.getInt(c?.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
                bytesAndStatus[2] = c?.getInt(c?.getColumnIndex(DownloadManager.COLUMN_STATUS))
            }
        } finally {
            if (c != null) {
                c?.close()
            }
        }
        return bytesAndStatus
    }


    private fun dispose() {
        if (disposable != null && !disposable?.isDisposed!!) {
            disposable?.dispose()
        }
    }

    override fun unsubscribe() {
        dispose()
    }

}

