package com.cr.data

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Typeface
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.cr.cruav.CrApplication
import com.cr.cruav.R
import com.cr.dialog.DialogNormal
import dji.sdk.keyvalue.value.camera.CameraExposureCompensation
import dji.sdk.keyvalue.value.camera.CameraISO
import dji.sdk.keyvalue.value.camera.CameraShutterSpeed
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern

const val DEFAULT_STR = "N/A"
const val DEFAULT_TIME = "00:00:00"
const val DEFAULT_LOCATION = "000.00000"
const val DEFAULT_RES_ID = -1
const val IN_INNER_NETWORK_STR = "IN_INNER"
const val IN_OUT_NETWORK_STR = "IN_OUT"
const val NO_NETWORK_STR = "NO_NETWORK"
const val ONLINE_STR = "ONLINE"
const val MAIN_FRAGMENT_PAGE_TITLE = "MAIN_FRAGMENT_PAGE_TITLE"
const val MEDIA_FILE_DETAILS_STR = "MEDIA_FILE_DETAILS"
const val REGISTER_SUCCESS = "Cr"
const val REGISTER_FAILED = "Err"
const val TAG: String = "CrUAVMessage"
const val RES_ERR_FLAG = "RES_ERR"
const val RES_NULL_FLAG = "RES_NO"
const val RES_SUCCESS_FLAG = "RES_OK"
const val RES_CONTENT = "data"
const val RES_ERR_DES = "msg"
const val RES_ERR_CODE = "code"
const val RES_HEAD = "res"

/**
 * 公共类
 */
class CrUtil {
    companion object {
        @JvmStatic
        val FontPath: String = "fonts/iconfont.ttf"

        @JvmStatic
        var toast: Toast? = null

        // define: 2023/3/31 工程目录
        val PROJECT_NAME: String = "lsquav"

        // define: 2023/3/31 存储主目录 随着App卸载删除
        val CARD_PATH: String = CrApplication.getContext().getExternalFilesDir(null).toString()

        // define: 2023/3/31 工程目录
        val PROJECT_PATH: String = "$CARD_PATH/$PROJECT_NAME"

        // define: 2023/3/31 工程缓存目录
        val PROJECT_CACHE_PATH: String = "$PROJECT_PATH/Cache"

        // define: 2023/3/31 图片存储目录
        val IMAGE_PATH: String = "$PROJECT_PATH/img/"

        // define: 2023/3/31 配置文件存储路径
        val CONFIG_PATH: String = "$PROJECT_PATH/config/"

        // define: 2023/4/3 数据库路径
        val DATABASE_PATH = "$CONFIG_PATH/dinfo.db"

        // define: 2023/4/13 网络下载的飞行库文件名称
        val DATA_FILE_NAME = "data.sqlite"

        // define: 2023/4/13 网络下载的配置库文件名称
        val CONFIG_FILE_NAME = "config.sqlite"

        // define: 2023/4/13 可编辑地图数据集文件名称
        val MAP_EDIT_FILE_NAME = "map.geodatabase"

        // define: 2023/4/13 基础地图数据集文件名称
        val MAP_BASE_FILE_NAME = "base.geodatabase"

        // define: 2023/4/13 配置库文件路径
        val DATABASE_PATH_CONFIG = "${CONFIG_PATH}/${CONFIG_FILE_NAME}"

        // define: 2023/4/13 飞行库文件路径
        val DATABASE_PATH_AIR = "${CONFIG_PATH}/${DATA_FILE_NAME}"

        // define: 2023/4/13 基础地图数据集完整路径
        val MAP_PATH_BASE = "${CONFIG_PATH}/${MAP_BASE_FILE_NAME}"

        // define: 2023/4/13 可编辑地图数据集完整路径
        val MAP_PATH_EDIT = "${CONFIG_PATH}/${MAP_EDIT_FILE_NAME}"


        /**
         * 根据等级数值获取等级
         * @param level Int
         * @return Level
         */
        @JvmStatic
        fun getLevel(level: Int): Level {
            if (level in 1..30) {
                return Level.LEVEL1
            } else if (level in 31..60) {
                return Level.LEVEL2
            } else if (level in 61..80) {
                return Level.LEVEL3
            } else if (level in 81..100) {
                return Level.LEVEL4
            } else {
                return Level.LEVEL1
            }
        }

        /**
         * 获取链路等级
         * @param level Int
         * @return Level
         */
        fun getLinkSignalQuality(level: Int): Level {
            if (level in 1 until 40) {
                return Level.LEVEL2
            } else if (level in 40 until 60) {
                return Level.LEVEL3
            } else if (level in 60..100) {
                return Level.LEVEL4
            } else {
                return Level.LEVEL1
            }
        }

        /**
         * 获取ISO
         * @param iso CameraISO
         * @return String
         */
        fun getISO(iso: CameraISO): String {
            when (iso) {
                CameraISO.ISO_50 -> {
                    return "50"
                }
                CameraISO.ISO_100 -> {
                    return "100"
                }
                CameraISO.ISO_200 -> {
                    return "200"
                }
                CameraISO.ISO_400 -> {
                    return "400"
                }
                CameraISO.ISO_800 -> {
                    return "800"
                }
                CameraISO.ISO_1600 -> {
                    return "1600"
                }
                CameraISO.ISO_3200 -> {
                    return "3200"
                }
                CameraISO.ISO_6400 -> {
                    return "6400"
                }
                CameraISO.ISO_12800 -> {
                    return "12800"
                }
                CameraISO.ISO_25600 -> {
                    return "25600"
                }
                CameraISO.ISO_102400 -> {
                    return "102400"
                }
                CameraISO.ISO_AUTO -> {
                    return "AUTO"
                }
                CameraISO.UNKNOWN -> {
                    return "UNKNOWN"
                }
                CameraISO.ISO_FIXED -> {
                    return "FIXED"
                }
            }
            return DEFAULT_STR
        }

        /**
         * 获取补偿值
         * @param ev CameraExposureCompensation
         * @return String
         */
        fun getEv(ev: CameraExposureCompensation): String {
            when (ev) {
                CameraExposureCompensation.NEG_5P0EV -> {
                    return "-5.0"
                }
                CameraExposureCompensation.NEG_4P7EV -> {
                    return "-4.7"
                }
                CameraExposureCompensation.NEG_4P3EV -> {
                    return "-4.3"
                }
                CameraExposureCompensation.NEG_4P0EV -> {
                    return "-4.0"
                }
                CameraExposureCompensation.NEG_3P7EV -> {
                    return "-3.7"
                }
                CameraExposureCompensation.NEG_3P3EV -> {
                    return "-3.3"
                }
                CameraExposureCompensation.NEG_3P0EV -> {
                    return "-3.0"
                }
                CameraExposureCompensation.NEG_2P7EV -> {
                    return "-2.7"
                }
                CameraExposureCompensation.NEG_2P3EV -> {
                    return "-2.3"
                }
                CameraExposureCompensation.NEG_2P0EV -> {
                    return "-2.0"
                }
                CameraExposureCompensation.NEG_1P7EV -> {
                    return "-1.7"
                }
                CameraExposureCompensation.NEG_1P3EV -> {
                    return "-1.3"
                }
                CameraExposureCompensation.NEG_1P0EV -> {
                    return "-1.0"
                }
                CameraExposureCompensation.NEG_0P7EV -> {
                    return "-0.7"
                }
                CameraExposureCompensation.NEG_0P3EV -> {
                    return "-0.3"
                }
                CameraExposureCompensation.NEG_0EV -> {
                    return "0.0"
                }
                CameraExposureCompensation.POS_0P3EV -> {
                    return "0.3"
                }
                CameraExposureCompensation.POS_0P7EV -> {
                    return "0.7"
                }
                CameraExposureCompensation.POS_1P0EV -> {
                    return "1.0"
                }
                CameraExposureCompensation.POS_1P3EV -> {
                    return "1.3"
                }
                CameraExposureCompensation.POS_1P7EV -> {
                    return "1.7"
                }
                CameraExposureCompensation.POS_2P0EV -> {
                    return "2.0"
                }
                CameraExposureCompensation.POS_2P3EV -> {
                    return "2.3"
                }
                CameraExposureCompensation.POS_2P7EV -> {
                    return "2.7"
                }
                CameraExposureCompensation.POS_3P0EV -> {
                    return "3.0"
                }
                CameraExposureCompensation.POS_3P3EV -> {
                    return "3.3"
                }
                CameraExposureCompensation.POS_3P7EV -> {
                    return "3.7"
                }
                CameraExposureCompensation.POS_4P0EV -> {
                    return "4.0"
                }
                CameraExposureCompensation.POS_4P3EV -> {
                    return "4.3"
                }
                CameraExposureCompensation.POS_4P7EV -> {
                    return "4.7"
                }
                CameraExposureCompensation.POS_5P0EV -> {
                    return "5.0"
                }
                CameraExposureCompensation.FIXED -> {
                    return "FIXED"
                }
                CameraExposureCompensation.UNKNOWN -> {
                    return "UNKNOWN"
                }
            }
            return DEFAULT_STR
        }

        /**
         * 获取快门速度
         * @param shutterSpeed CameraShutterSpeed
         * @return String
         */
        fun getShutterSpeed(shutterSpeed: CameraShutterSpeed): String {
            when (shutterSpeed) {
                CameraShutterSpeed.SHUTTER_SPEED_AUTO -> {
                    return "AUTO"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_20000 -> {
                    return "1/20000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_16000 -> {
                    return "1/16000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_12800 -> {
                    return "1/12800"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_10000 -> {
                    return "1/10000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_8000 -> {
                    return "1/8000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_6400 -> {
                    return "1/6400"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_6000 -> {
                    return "1/6000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_5000 -> {
                    return "1/5000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_4000 -> {
                    return "1/4000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_3200 -> {
                    return "1/3200"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_3000 -> {
                    return "1/3000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_2500 -> {
                    return "1/2500"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_2000 -> {
                    return "1/2000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_1600 -> {
                    return "1/1600"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_1500 -> {
                    return "1/1500"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_1250 -> {
                    return "1/1250"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_1000 -> {
                    return "1/1000"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_800 -> {
                    return "1/800"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_725 -> {
                    return "1/725"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_640 -> {
                    return "1/640"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_500 -> {
                    return "1/500"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_400 -> {
                    return "1/400"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_350 -> {
                    return "1/350"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_320 -> {
                    return "1/320"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_250 -> {
                    return "1/250"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_240 -> {
                    return "1/240"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_200 -> {
                    return "1/200"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_180 -> {
                    return "1/180"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_160 -> {
                    return "1/160"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_125 -> {
                    return "1/125"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_120 -> {
                    return "1/120"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_100 -> {
                    return "1/100"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_90 -> {
                    return "1/90"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_80 -> {
                    return "1/80"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_60 -> {
                    return "1/60"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_50 -> {
                    return "1/50"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_40 -> {
                    return "1/40"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_30 -> {
                    return "1/30"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_25 -> {
                    return "1/25"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_20 -> {
                    return "1/20"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_15 -> {
                    return "1/15"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_12DOT5 -> {
                    return "1/12.5"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_10 -> {
                    return "1/10"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_8 -> {
                    return "1/8"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_6DOT25 -> {
                    return "1/6.25"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_5 -> {
                    return "1/5"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_4 -> {
                    return "1/4"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_3 -> {
                    return "1/3"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_2DOT5 -> {
                    return "1/2.5"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_2 -> {
                    return "1/2"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_1DOT67 -> {
                    return "1/1.67"
                }
                CameraShutterSpeed.SHUTTER_SPEED1_1DOT25 -> {
                    return "1/1.25"
                }
                CameraShutterSpeed.SHUTTER_SPEED1 -> {
                    return "1.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED1DOT3 -> {
                    return "1.3"
                }
                CameraShutterSpeed.SHUTTER_SPEED1DOT6 -> {
                    return "1.6"
                }
                CameraShutterSpeed.SHUTTER_SPEED2 -> {
                    return "2.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED2DOT5 -> {
                    return "2.5"
                }
                CameraShutterSpeed.SHUTTER_SPEED3 -> {
                    return "3.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED3DOT2 -> {
                    return "3.2"
                }
                CameraShutterSpeed.SHUTTER_SPEED4 -> {
                    return "4.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED5 -> {
                    return "5.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED6 -> {
                    return "6.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED7 -> {
                    return "7.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED8 -> {
                    return "8.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED9 -> {
                    return "9.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED10 -> {
                    return "10.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED11 -> {
                    return "11.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED13 -> {
                    return "13.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED15 -> {
                    return "15.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED16 -> {
                    return "16.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED20 -> {
                    return "20.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED23 -> {
                    return "23.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED25 -> {
                    return "25.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED30 -> {
                    return "30.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED40 -> {
                    return "40.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED50 -> {
                    return "50.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED60 -> {
                    return "60.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED80 -> {
                    return "80.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED100 -> {
                    return "100.0"
                }
                CameraShutterSpeed.SHUTTER_SPEED120 -> {
                    return "120.0"
                }
                CameraShutterSpeed.UNKNOWN->{
                    return "UNKNOWN"
                }
            }
            return DEFAULT_STR
        }

        /**
         * Logcat输出消息
         * @param message String
         */
        @JvmStatic
        fun print(message: String) {
            Log.i(TAG, SimpleDateFormat("HH:mm:ss").format(Date()) + " " + message)
        }

        /**
         * 设置显示的字体内容
         * @param context Context 上下文
         * @param textView TextView 文本控件
         * @param fontId Int 字体Id
         */
        @JvmStatic
        fun setFont(context: Context, textView: TextView, fontId: Int) {
            var font: Typeface? = Typeface.createFromAsset(context.assets, CrUtil.FontPath)
            textView!!.typeface = font
            textView!!.text = context.resources.getString(fontId)
        }

        /**
         * 获取字体
         * @param context Context
         * @return Typeface?
         */
        @JvmStatic
        fun getFont(context: Context): Typeface? {
            return Typeface.createFromAsset(context.assets, "fonts/tx.ttf")
        }

        /**
         * 多线程显示提示消息
         * @param message String 消息内容
         */
        @JvmStatic
        fun showToast(message: String) {
            var mainHandler = Handler(Looper.getMainLooper())
            mainHandler.post(Runnable {
                if (toast != null) {
                    toast!!.cancel()
                }
                toast = Toast.makeText(CrApplication.getContext(), message, Toast.LENGTH_LONG)
                toast!!.duration = Toast.LENGTH_LONG
                toast!!.setText(message)
                toast!!.show()
            })
        }

        /**
         * 获取计算值
         * @param dimenId Int
         * @return Float
         */
        @JvmStatic
        fun getDimens(dimenId: Int): Float {
            return CrApplication.getContext().resources.getDimension(dimenId)
        }

        /**
         * 检查Ip地址
         * @param strIP String?
         * @return Boolean?
         */
        fun checkIP(strIP: String?): Boolean? {
            val ip = ("^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") //限定输入格式
            val p = Pattern.compile(ip)
            val m = p.matcher(strIP)
            return m.matches()
        }

        /**
         * 检查端口
         * @param strCOM String?
         * @return Boolean?
         */
        fun checkCOM(strCOM: String?): Boolean? {
            val ip = "^\\d{2,6}$" //限定输入格式
            val p = Pattern.compile(ip)
            val m = p.matcher(strCOM)
            return m.matches()
        }

        /**
         * 获取版本名称
         * @param context Context 上下文
         * @return String
         */
        fun getVersionName(context: Context): String {
            var packageInfo: PackageInfo = getPackageInfo(context)
            return packageInfo.versionName
        }

        /**
         * 获取版本号
         * @param context Context 上下文
         * @return Long
         */
        @RequiresApi(Build.VERSION_CODES.P)
        fun getVersionCode(context: Context): Long {
            var packageInfo: PackageInfo = getPackageInfo(context)
            return packageInfo.longVersionCode
        }

        /**
         * 获取包信息
         * @param context Context 上下文
         * @return PackageInfo
         */
        fun getPackageInfo(context: Context): PackageInfo {
            var pm: PackageManager = context.packageManager
            var packageInfo: PackageInfo =
                pm.getPackageInfo(context.packageName, PackageManager.GET_CONFIGURATIONS)
            return packageInfo
        }

        /**
         * 扩展函数 判断TextView内容是否为空
         * @receiver TextView 文本框
         * @param message String 错误消息
         * @return String?
         */
        fun TextView.checkBlank(message: String): String? {
            val text = this.text.toString()
            if (text.isBlank()) {
                DialogNormal(this.context, "警告", message).show()
                return null
            } else {
                return text
            }
        }

        /**
         * 扩展函数
         * 启动窗体
         * @receiver Context
         */
        inline fun <reified T : Activity> Context.onStart() {
            startActivity(Intent(this, T::class.java))
        }

        /**
         * 秒转时分秒
         * @param seconds Int 秒
         * @return String 时:分:秒
         */
        fun secondsToHMS(seconds:Int):String{
            var hours = seconds/3600
            var minutes = (seconds % 3600)/60
            var rSeconds = seconds % 60
            return String.format("%d:%02d:%02d",hours,minutes,rSeconds)
        }
    }
}

/**
 * 等级枚举
 * @property index Int
 * @constructor
 */
enum class Level(var index: Int) {
    // todo: 2023/3/9 0-30
    LEVEL1(1),

    // todo: 2023/3/9 30-60
    LEVEL2(2),

    // todo: 2023/3/9 60-80
    LEVEL3(3),

    // todo: 2023/3/9 80-100
    LEVEL4(4)
}