package com.rdiot.yx485.util

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.IBinder
import android.provider.Settings
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.drake.net.utils.TipUtils
import com.lindroy.iosdialog.ICustomDialog
import com.permissionx.guolindev.PermissionX
import com.rdiot.yx485.BuildConfig
import com.rdiot.yx485.R
import com.rdiot.yx485.base.LocalData
import com.rdiot.yx485.bean.AppVersionData
import com.rdiot.yx485.net.update.ProgressDownloadListener
import com.rdiot.yx485.net.update.UpdateAgent
import com.rdiot.yx485.net.update.UpdateInfo
import com.rdiot.yx485.net.update.UpdateManager
import java.text.Format
import java.text.SimpleDateFormat
import java.util.*


/**
 * 获取当前系统时间戳，单位毫秒
 */
val curTime: Long
    get() = System.currentTimeMillis()

/** 跳转下一个页面，如果栈中有相同的ACT会只保留最新一个到前台 */
fun Activity.clearGoTo(clz: Class<*>) {
    val intent = getClearTopIntent(clz)
    startActivity(intent)
//    overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
}

/** 跳转下一个页面，如果栈中有相同的ACT会只保留最新一个到前台 */
fun Activity.clearGoTo(intent: Intent) {
    startActivity(intent)
//    overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
}

/**
 * 获取跳转页面Intent
 * @param clz 跳转页面
 * @return [Intent] Intent
 */
fun Context.getClearTopIntent(clz: Class<*>): Intent {
    val intent = Intent(this, clz)
    intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
    return intent
}

/**
 * 关闭当前页面并跳转下一个页面
 * @param intent 跳转页面
 */
fun Activity.finishGoTo(intent: Intent) {
    startActivity(intent)
    finish()
}

/**
 * 关闭当前页面并跳转下一个页面
 * @param clz 跳转页面
 */
fun Activity.finishGoTo(clz: Class<*>) {
    goTo(clz)
    finish()
}


/**
 * 跳转下一个页面，如果栈中有相同的ACT会只保留最新一个到前台
 * @param clz 跳转页面
 */
fun Activity.goTo(clz: Class<*>) {
    val intent = getClearTopIntent(clz)
    startActivity(intent)
}

/**
 * 打开App设置页面
 * @param justGo 直接跳转
 * @return [Intent] 意图
 */
fun Activity.goToAppSetting(justGo: Boolean): Intent {
    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
    val uri = Uri.fromParts("package", packageName, null)
    intent.data = uri
    if (justGo) startActivity(intent)
    return intent
}


/**
 * 打开Wi-Fi设置页面
 * @param justGo 直接跳转
 * @return [Intent] 意图
 */
fun Activity.goToSystemWifiSetting(justGo: Boolean): Intent {
    val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
    intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
    if (justGo) startActivity(intent)
    return intent
}

/**
 * 打开位置信息设置页面
 * @param justGo 直接跳转
 * @return [Intent] 意图
 */
fun Activity.goToSystemLocationSetting(justGo: Boolean): Intent {
    val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
    intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
    if (justGo) startActivity(intent)
    return intent
}


interface ClickLimitListener {
    fun onClickLimit(view: View)
}

interface ClickAlphaListener {
    fun onClickAlpha(view: View)
}


/**
 * 防止快速点击-并且添加按下变暗效果
 */
@SuppressLint("ClickableViewAccessibility")
fun View.setClickLimitListener(listener: ClickLimitListener?) {
   val minTime = 500L
    var lastTime = 0L
    if (listener == null) {
        this.setOnClickListener(null)
        this.setOnTouchListener(null)
    } else {
        this.setOnClickListener {
            val tmpTime = System.currentTimeMillis()
            if (tmpTime - lastTime > minTime) {
                lastTime = tmpTime
                listener.onClickLimit(this)
            }
        }
        this.setOnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    view.alpha = 0.7f
                }
                MotionEvent.ACTION_UP -> {
                    view.alpha = 1f
                }
                MotionEvent.ACTION_CANCEL -> {
                    view.alpha = 1f
                }
            }
            return@setOnTouchListener false
        }
    }

}

@SuppressLint("ClickableViewAccessibility")
fun View.setClickAlpha(listener: ClickAlphaListener?) {
    if (listener == null) {
        this.setOnClickListener(null)
        this.setOnTouchListener(null)
    } else {
        this.setOnClickListener {
            listener.onClickAlpha(this)
        }
        this.setOnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    view.alpha = 0.7f
                }
                MotionEvent.ACTION_UP -> {
                    view.alpha = 1f
                }
                MotionEvent.ACTION_CANCEL -> {
                    view.alpha = 1f
                }
            }
            return@setOnTouchListener false
        }
    }

}


@SuppressLint("ClickableViewAccessibility")
        /** 点击效果 */
fun View.setClickAlpha(action: () -> Unit) {
    this.setClickAlpha(object : ClickAlphaListener {
        override fun onClickAlpha(view: View) {
            action.invoke()
        }
    })
}

/** 点击防抖+效果 */
fun View.setClickLimitListener(action: () -> Unit) {
    this.setClickLimitListener(object : ClickLimitListener {
        override fun onClickLimit(view: View) {
            action.invoke()
        }
    })
}


/**
 * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
 * @param event 点击事件
 * @return [Boolean] 是否需要隐藏输入法
 */
fun View.isShouldHideKeyboard(event: MotionEvent): Boolean {
    if (this is EditText) {
        val l = intArrayOf(0, 0)
        this.getLocationInWindow(l)
        val left = l[0]
        val top = l[1]
        val bottom = top + this.getHeight()
        val right = left + this.getWidth()
        return !(event.x > left && event.x < right && event.y > top && event.y < bottom)
    }
    // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，
    // 第一个焦点不在EditText上，和用户用轨迹球选择其他的焦点
    return false
}

/**
 * 隐藏软键盘
 * @param token View.windowToken
 * @return [Boolean] true:成功; false:失败;
 */
fun Context.hideKeyboard(token: IBinder): Boolean {
    val im = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    return im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS)
}

/**
 * 请求权限
 * @receiver Fragment
 * @param isAskBle Boolean true请求蓝牙权限,false请求相机权限
 */
fun AppCompatActivity.askPermission(
    isAskBle: Boolean,
    callBack: (allGranted: Boolean?, deniedList: (MutableList<String>)?) -> Unit
) {
    val requestList = ArrayList<String>()

    if (isAskBle) {
        requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            requestList.add(Manifest.permission.BLUETOOTH_SCAN)
            requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE)
            requestList.add(Manifest.permission.BLUETOOTH_CONNECT)
        }
    } else {
        requestList.add(Manifest.permission.CAMERA)
    }

    PermissionX.init(this)
        .permissions(requestList)
        .onExplainRequestReason { _, deniedList, _ ->
//            LogUtils.w("onExplainRequestReason")
            callBack(false, deniedList)
        }
        .onForwardToSettings { _, _ ->
//            LogUtils.w("onForwardToSettings")

            callBack(null, null)
        }
        .request { allGranted, _, deniedList ->
//            LogUtils.w("request")

            callBack(allGranted, deniedList)
        }
}

/** 检查更新 */
fun AppCompatActivity.checkUpdate(data: AppVersionData?, isUserCheck: Boolean = false) {

    data?.let {
        if (!data.needUpdate&&isUserCheck){
            TipUtils.toast(getString(R.string.update_no_newer))
        }else{

            UpdateManager.setChecker {
                UpdateInfo(
                    hasUpdate = data.needUpdate,
                    isForce = data.updateInfo.forceUpdate,
                    isShowNotification = true,
                    updateContent = data.updateInfo.content,
                    url = data.updateInfo.downloadUrl,
                    isIgnorable = false,
                    hash = data.updateInfo.version,
                    isUserCheck = isUserCheck
                )
            }
            UpdateManager.check(this)
        }

    }
}

fun AppCompatActivity.showFoundNewVersionDialog(agent: UpdateAgent) {
    val sdf: Format = SimpleDateFormat("dd", Locale.getDefault())
    val today = sdf.format(Date()).toInt()

    //如果不是日期不相同 则弹出提醒（避免单日重复提醒）
    //或 如果用户点击【检查更新】则弹出提醒
    //或 强制更新则弹出提醒
    LocalData.appVersionData.value?.let { data ->
        if (today != LocalData.noReminderToday || agent.info.isUserCheck || data.updateInfo.forceUpdate) {
            ICustomDialog.build(this)
                .apply {
                    setCancelOutside(BuildConfig.DEBUG)
                }
                .setAlpha(1.0F)
                .setWidthScale(0.7F)
                .setBackgroundColorRes(R.color.white)
                .setView(R.layout.dialog_simple_msg)
                .setOnViewHandler { holder, dialog ->
                    //强制更新
                    holder.setVisibility(
                        R.id.btnCancel,
                        if (data.updateInfo.forceUpdate) View.GONE else View.VISIBLE
                    )
                    // 设置标题
                    holder.setText(R.id.tv_title, R.string.found_new_version)
                    // 设置内容
                    holder.setText(R.id.tv_msg, data.updateInfo.content)

                    //暂不更新
                    holder.setOnClickListener(R.id.btnCancel) {
                        agent.cancel()
                        dialog.dismiss()
                        LocalData.noReminderToday = today
                    }

                    //马上更新
                    holder.setOnClickListener(R.id.btnConfirm) {
                        holder.setVisibility(R.id.pb, View.VISIBLE)
                        holder.setVisibility(R.id.btnCancel, View.GONE)

                        val pb: ProgressBar = holder.getView(R.id.pb)

                        (it as TextView).apply {
                            isEnabled = false
                            setTextColor(getColor(R.color.main_sub_text_color))
                            text = getString(R.string.downloading)
                            agent.update()
                            agent.addDownloadListener(ProgressDownloadListener(pb, it))
                        }
                    }

                }
                .show()
        }

    }

}
