package com.lukouguoji.module_base.util

import android.app.Activity
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import android.view.Gravity
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.cretin.www.cretinautoupdatelibrary.interfaces.AppDownloadListener
import com.cretin.www.cretinautoupdatelibrary.model.DownloadInfo
import com.cretin.www.cretinautoupdatelibrary.utils.AppUpdateUtils
import com.github.gzuliyujiang.wheelpicker.DatePicker
import com.github.gzuliyujiang.wheelpicker.DatimePicker
import com.github.gzuliyujiang.wheelpicker.OptionPicker
import com.github.gzuliyujiang.wheelpicker.annotation.DateMode
import com.github.gzuliyujiang.wheelpicker.annotation.TimeMode
import com.github.gzuliyujiang.wheelpicker.contract.OnDatePickedListener
import com.github.gzuliyujiang.wheelpicker.contract.OnDatimePickedListener
import com.github.gzuliyujiang.wheelpicker.contract.OnOptionPickedListener
import com.github.gzuliyujiang.wheelpicker.entity.DateEntity
import com.github.gzuliyujiang.wheelpicker.entity.DatimeEntity
import com.github.gzuliyujiang.wheelpicker.entity.TimeEntity
import com.github.gzuliyujiang.wheelview.annotation.CurtainCorner
import com.lukouguoji.module_base.MyApplication
import com.lukouguoji.module_base.http.system.SystemServiceCreator
import com.lukouguoji.module_base.http.system.`interface`.SystemCommonService
import com.lukouguoji.module_base.model.ConfirmDialogModel
import com.ninetripods.sydialoglib.IDialog
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern


/**
 * 一般的工具类
 */
object Common {

    /**
     * 提示框
     */
    fun showToast(context: Context, content: String) {
        /*val makeText = Toast.makeText(context, content, Toast.LENGTH_SHORT)
        makeText.setGravity(Gravity.CENTER, 0, 0)
        makeText.show()*/
        DialogUtil.createDefaultDialog(
            context, "提示", "$content",
            ""
        ) { dialog ->
            dialog.dismiss()
        }
    }

    /**
     * 提示框
     */
    fun showToastLong(context: Context, content: String) {
        val makeText = Toast.makeText(context, content, Toast.LENGTH_LONG)
        makeText.setGravity(Gravity.CENTER, 0, 0)
        makeText.show()
    }

    /**
     * 单项选择器
     */
    fun singleSelect(
        activity: Activity,
        title: String,
        dataArr: JSONArray,
        defaultValue: String?,
        onOptionPickedListener: OnOptionPickedListener
    ) {
        val picker = OptionPicker(activity)
        picker.setTitle(title)
        picker.setBodyWidth(360)
        picker.setData(dataArr)
        picker.setDefaultPosition(2)
        picker.setOnOptionPickedListener { position, item ->
            onOptionPickedListener.onOptionPicked(position, item)
        }

        val wheelLayout = picker.wheelLayout
        wheelLayout.setIndicatorEnabled(false)
        wheelLayout.setTextSize(15 * MyApplication.context.resources.displayMetrics.scaledDensity)
        //注：建议通过`setStyle`定制样式设置文字加大，若通过`setSelectedTextSize`设置，该解决方案会导致选择器展示时跳动一下
        //wheelLayout.setStyle(R.style.WheelStyleDemo);
        wheelLayout.setSelectedTextSize(17 * MyApplication.context.resources.displayMetrics.scaledDensity)
        wheelLayout.setSelectedTextBold(true)
        wheelLayout.setCurtainEnabled(true)
        wheelLayout.setCurtainCorner(CurtainCorner.ALL)
        wheelLayout.setCurtainRadius(5 * MyApplication.context.resources.displayMetrics.density)
        wheelLayout.setOnOptionSelectedListener { position, item ->
            var jsonObject = item as JSONObject
            picker.titleView.text = jsonObject.getString("name")
        }
        wheelLayout.wheelView.setFormatter {
            var jsonObject = it as JSONObject
            jsonObject.getString("name")
        }

        //获取选中值
        var position = 0
        defaultValue?.let {
            for ((index, obj) in dataArr.withIndex()) {
                val tempObj = obj as JSONObject
                var code = tempObj.getString("code")
                if (defaultValue == code) {
                    position = index
                }
            }
        }
        picker.setDefaultPosition(position)

        picker.show()
    }

    /**
     * 二次确认 对话框
     */
    fun secondConfirmDialog(
        activity: Activity,
        titleStr: String,
        listener: IDialog.OnClickListener
    ) {
        ConfirmDialogModel(
            message = titleStr,
        ) {
            listener.onClick(object : IDialog {
                override fun dismiss() {}
                override fun getContext() = activity
            })
        }.show(activity)
    }

    /**
     * 提示框
     */
    fun alertDialog(activity: Activity, titleStr: String, listener: IDialog.OnClickListener) {
        /*// 这里的属性可以一直设置，因为每次设置后返回的是一个builder对象
        val builder: AlertDialog.Builder = AlertDialog.Builder(activity)
        // 设置提示框的标题
        builder.setPositiveButton("确定") { dialog, which ->
            listener.onClick(dialog, which)
        }

        // 生产对话框
        val alertDialog: AlertDialog = builder.create()

        val title = TextView(activity)
        title.text = "$titleStr"
        title.setPadding(10, 30, 10, 10)
        title.gravity = Gravity.CENTER
        title.textSize = 18f
        title.setTextColor(MyApplication.context.resources.getColor(R.color.colorPrimary,MyApplication.context.theme))
        alertDialog.setCustomTitle(title)

        // 显示对话框
        alertDialog.show()

        val button: Button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
        val button2: Button = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE)
        button.setTextColor(MyApplication.context.resources.getColor(R.color.colorPrimary, activity.theme))
        button2.setTextColor(MyApplication.context.resources.getColor(R.color.colorPrimary, activity.theme))*/


        DialogUtil.createDefaultDialog(
            activity, "提示", titleStr,
            ""
        ) { dialog ->
            listener.onClick(dialog)
            dialog.dismiss()
        }

    }

    /**
     * 升级安卓程序
     */
    fun getAndroidLatestVer() {
        val commonService = SystemServiceCreator.create<SystemCommonService>()
        commonService.getAndroidLatestVer().enqueue(object : Callback<JSONObject> {
            override fun onResponse(
                call: Call<JSONObject>,
                response: Response<JSONObject>
            ) {
                val data = response.body()
                data?.let {
                    var build = it.getString("build")
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && build != null && build.toInt() > getVersionCode().toInt()) {
                        //强制更新
                        val changeLog = it.getString("changelog") ?: ""
                        var forceUpdate = false
                        if (changeLog.contains("**重要版本**")) {
                            forceUpdate = true
                        }
                        val url = it.getString("installUrl")
                        val versionCode = it.getString("version")
                        val versionName = it.getString("versionShort")
                        val fileSize = it.getJSONObject("binary").getLong("fsize")

                        autoUpdateApp(url, versionCode.toInt(), versionName, changeLog, fileSize)
                    } else {
                        //版本号和构建号小于 当前版本，不更新
                    }
                }
            }

            override fun onFailure(call: Call<JSONObject>, t: Throwable) {
                t.printStackTrace()
            }
        })
    }

    /**
     * 获取当前程序的版本号
     */
    @RequiresApi(Build.VERSION_CODES.P)
    @Throws(java.lang.Exception::class)
    fun getVersionCode(): Long {
        //获取packagemanager的实例
        val packageManager: PackageManager = MyApplication.context.packageManager
        //getPackageName()是你当前类的包名，0代表是获取版本信息
        val packInfo: PackageInfo =
            packageManager.getPackageInfo(MyApplication.context.packageName, 0)
        Log.i("TAG", "版本号" + packInfo.longVersionCode)
        Log.i("TAG", "版本名" + packInfo.versionName)
        return packInfo.longVersionCode
    }

    /**
     * 自动更新
     */
    fun autoUpdateApp(
        url: String,
        versionCode: Int,
        versionName: String,
        content: String,
        fileSize: Long
    ) {
        //0不强制更新，1强制更新
        var forceUpdate = 0
        if (content.contains("**重要版本**")) {
            forceUpdate = 1
        }

        val info = DownloadInfo()
            /* .setApkUrl("http://jokesimg.cretinzp.com/apk/app-release_231_jiagu_sign.apk")
             .setProdVersionCode(10)
             .setProdVersionName("2.3.1")
             .setUpdateLog("1、优化细节和体验，更加稳定\n2、引入大量优质用户\r\n3、修复已知bug\n4、风格修改")*/
            .setFileSize(fileSize)
            .setApkUrl(url)
            .setProdVersionCode(versionCode)
            .setProdVersionName(versionName)
            .setForceUpdateFlag(forceUpdate) //0不强制更新，1强制更新
            .setUpdateLog(content)
        //打开文件MD5校验
        /**可再次重新设置更新的ui样式
        // AppUpdateUtils.getInstance().updateConfig.uiThemeType = TypeConfig.UI_THEME_L
         */
        AppUpdateUtils.getInstance()
            .addAppUpdateInfoListener { isLatest -> Log.e("HHHHHHHHHHHHHHH", "isLatest:$isLatest") }
            .addAppDownloadListener(object : AppDownloadListener {
                override fun downloading(progress: Int) {
                    Log.e("HHHHHHHHHHHHHHH", "progress:$progress")
                }

                override fun downloadFail(msg: String) {
                    Log.e("HHHHHHHHHHHHHHH", "msg:$msg")
                }

                override fun downloadComplete(path: String) {
                    Log.e("HHHHHHHHHHHHHHH", "path:$path")
                }

                override fun downloadStart() {
                    Log.e("HHHHHHHHHHHHHHH", "start")
                }

                override fun reDownload() {}
                override fun pause() {}
            })
            .checkUpdate(info)
    }

    /**
     * 日期
     * date yyyy-MM-dd
     */
    fun onYearMonthDay(
        activity: Activity,
        date: String?,
        onDatePickedListener: OnDatePickedListener
    ) {
        val picker = DatePicker(activity)
        val wheelLayout = picker.wheelLayout
        //监听
        picker.setOnDatePickedListener { year, month, day ->
            onDatePickedListener.onDatePicked(year, month, day)
        }
        //支持年月日、时分秒
        wheelLayout.setDateMode(DateMode.YEAR_MONTH_DAY)
        //选择范围
        val selDate = DateEntity.target(1999, 1, 1)
        wheelLayout.setRange(selDate, DateEntity.yearOnFuture(50))
        //年月日时分秒
        wheelLayout.setDateLabel("年", "月", "日")
        //内间距，向右远离60
        wheelLayout.setPadding(0, 0, 60, 0)
        //设置打开组件的时间
        if (date != null && date != "") {
            var simpleDateFormat = SimpleDateFormat("yyyy-MM-dd")
            var fdate = simpleDateFormat.parse(date)
            var calendar = Calendar.getInstance()
            calendar.time = fdate
            val datimeEntity = DateEntity.target(
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DAY_OF_MONTH)
            )
            wheelLayout.setDefaultValue(datimeEntity)
        } else {
            wheelLayout.setDefaultValue(DateEntity.today())
        }

        //展示
        picker.show()
    }

    /**
     * 日期
     * date yyyy-MM-dd HH:mm:ss
     */
    fun onYearMonthDayTime(
        activity: Activity,
        date: String?,
        onDatimePickedListener: OnDatimePickedListener
    ) {
        val picker = DatimePicker(activity)
        val wheelLayout = picker.wheelLayout
        //监听
        picker.setOnDatimePickedListener { year, month, day, hour, minute, second ->
            onDatimePickedListener.onDatimePicked(year, month, day, hour, minute, second)
        }
        //支持年月日、时分秒
        wheelLayout.setDateMode(DateMode.YEAR_MONTH_DAY)
        wheelLayout.setTimeMode(TimeMode.HOUR_24_HAS_SECOND)
        //选择范围
        val selDate = DatimeEntity()
        selDate.date = DateEntity.target(1999, 1, 1)
        selDate.time = TimeEntity.target(0, 0, 0)
        wheelLayout.setRange(selDate, DatimeEntity.yearOnFuture(100))
        //年月日时分秒
        wheelLayout.setDateLabel("年", "月", "日")
        wheelLayout.setTimeLabel("时", "分", "秒")
        //内间距，向右远离60
        wheelLayout.setPadding(0, 0, 60, 0)
        //设置打开组件的时间
        if (date != null && date != "") {
            var simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
            var fdate = simpleDateFormat.parse(date)
            var calendar = Calendar.getInstance()
            calendar.time = fdate
            val datimeEntity = DatimeEntity()
            datimeEntity.date = DateEntity.target(
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DAY_OF_MONTH)
            )
            datimeEntity.time = TimeEntity.target(
                calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE),
                calendar.get(Calendar.SECOND)
            )
            wheelLayout.setDefaultValue(datimeEntity)
        } else {
            wheelLayout.setDefaultValue(DatimeEntity.now())
        }

        //展示
        picker.show()
    }

    /**
     * 手机号码正则判断
     */
    fun isPhoneNum(phone: String): Boolean {
        val compile = Pattern.compile("^(13|14|15|16|17|18|19)\\d{9}$")
        val matcher = compile.matcher(phone)
        return matcher.matches()
    }

    /**
     * 省份证id正则校验
     */
    fun isIDNumber(IDNumber: String?): Boolean {
        if (IDNumber == null || "" == IDNumber) {
            return false
        }
        // 定义判别用户身份证号的正则表达式（15位或者18位，最后一位可以为字母）
        val regularExpression =
            "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"
        //假设18位身份证号码:41000119910101123X  410001 19910101 123X
        //^开头
        //[1-9] 第一位1-9中的一个      4
        //\\d{5} 五位数字           10001（前六位省市县地区）
        //(18|19|20)                19（现阶段可能取值范围18xx-20xx年）
        //\\d{2}                    91（年份）
        //((0[1-9])|(10|11|12))     01（月份）
        //(([0-2][1-9])|10|20|30|31)01（日期）
        //\\d{3} 三位数字            123（第十七位奇数代表男，偶数代表女）
        //[0-9Xx] 0123456789Xx其中的一个 X（第十八位为校验值）
        //$结尾

        //假设15位身份证号码:410001910101123  410001 910101 123
        //^开头
        //[1-9] 第一位1-9中的一个      4
        //\\d{5} 五位数字           10001（前六位省市县地区）
        //\\d{2}                    91（年份）
        //((0[1-9])|(10|11|12))     01（月份）
        //(([0-2][1-9])|10|20|30|31)01（日期）
        //\\d{3} 三位数字            123（第十五位奇数代表男，偶数代表女），15位身份证不含X
        //$结尾


        val matches = IDNumber.matches(regularExpression.toRegex())

        //判断第18位校验值
        if (matches) {

            if (IDNumber.length == 18) {
                try {
                    val charArray = IDNumber.toCharArray()
                    //前十七位加权因子
                    val idCardWi = intArrayOf(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
                    //这是除以11后，可能产生的11位余数对应的验证码
                    val idCardY = arrayOf("1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2")
                    var sum = 0
                    for (i in idCardWi.indices) {
                        val current = Integer.parseInt(charArray[i].toString())
                        val count = current * idCardWi[i]
                        sum += count
                    }
                    val idCardLast = charArray[17]
                    val idCardMod = sum % 11
                    if (idCardY[idCardMod].toUpperCase() == idCardLast.toString().toUpperCase()) {
                        return true
                    } else {
                        println(
                            "身份证最后一位:" + idCardLast.toString().toUpperCase() +
                                    "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()
                        )
                        return false
                    }

                } catch (e: Exception) {
                    e.printStackTrace()
                    println("异常:$IDNumber")
                    return false
                }

            }

        }
        return matches
    }
}

