package com.convenient.android.common.extension

import android.app.Activity
import android.app.KeyguardManager
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Build
import android.util.DisplayMetrics
import android.view.Surface
import android.view.View
import androidx.annotation.ColorInt
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import com.convenient.android.common.utils.systemui.KeyBoardHide
import com.convenient.android.common.utils.systemui.KeyBoardShow
import com.convenient.android.common.utils.systemui.SoftKeyBoardUtils
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sqrt

/**
 * @classname:
 * @author: LiuXiaoLong
 * @date: 2022/7/29
 * description: 屏幕相关的扩展类
 */

/**
 * 屏幕宽度
 */
fun Context?.getScreenWidth(): Int = this?.resources?.displayMetrics?.widthPixels ?: 0


/**
 * 屏幕高度
 */
fun Context?.getScreenHeight(): Int = this?.resources?.displayMetrics?.heightPixels ?: 0

fun Context?.getScreenWidthDp() : Float = getScreenWidth() / (if (getDensity() <= 0) 1F else getDensity()) + 0.5f

fun Context.getScreenHeightDp() : Float = px2dip(getScreenHeight().toFloat()).toFloat()

/**
 * 获取屏幕密度
 */
fun Context?.getDensity(): Float = this?.resources?.displayMetrics?.density ?: 0F

/**
 * 获取屏幕密度Dpi
 */
fun Context?.getDensityDpi(): Int = this?.resources?.displayMetrics?.densityDpi ?: 0

/**
 * 屏幕X轴方向上的长度（dp)
 */
fun Context.getXDp(): Double {
    return (getScreenWidth().div(getDensity())).toDouble()
}

/**
 * 屏幕Y轴方向的长度（dp)
 */
fun Context.getYDp(): Double {
    return (getScreenHeight().div(getDensity())).toDouble()
}

/**
 * @param ：[context, dpValue]
 * @return : int
 * @methodName ：dip2px created by luozhipeng on 5/12/17 13:57.
 * @description ：根据手机的分辨率从 dp 的单位 转成为 px(像素)
 */
fun Context.dp2px(dpValue: Float): Int {
    val scale = getDensity()
    return (dpValue * scale + 0.5f).toInt()
}

/**
 * @param ：[context, pxValue]
 * @return : int
 * @methodName ：px2dip created by luozhipeng on 5/12/17 14:00.
 * @description ：根据手机的分辨率从 px(像素) 的单位 转成为 dp
 */
fun Context.px2dip(pxValue: Float): Int {
    val scale = getDensity()
    return (pxValue / scale + 0.5f).toInt()
}

/**
 * 获取屏幕最小边
 */
fun Context.screenMinSide(): Int = min(getScreenWidth(), getScreenHeight())


/**
 * 获取屏幕最大边
 */
fun Context.screenMaxSide(): Int = max(getScreenWidth(), getScreenHeight())

/**
 * 是否是平板设备
 */
fun Context.isPadDevice(): Boolean {
    return resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK >= Configuration.SCREENLAYOUT_SIZE_LARGE
}

/**
 * @param ：[context]
 * @return : double
 * @methodName ：getScreenDimension created by luozhipeng on 5/12/17 14:05.
 * @description ：获取屏幕的尺寸（英寸）
 */
fun Context.getScreenDimension(): Double {
    // 得到屏幕的宽(像素)
    val screenX = getScreenWidth()
    // 得到屏幕的高(像素)
    val screenY = getScreenHeight()
    // 每英寸的像素点
    val dpi = getDensityDpi()
    // 得到屏幕的宽(英寸)
    val a = screenX.toFloat() / dpi
    // 得到屏幕的高(英寸)
    val b = screenY.toFloat() / dpi
    // 勾股定理
    return sqrt((a * a + b * b).toDouble())
}

/**
 * 锁定屏幕为竖屏
 */
fun Activity.lockScreenPortrait() {
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}

/**
 * 锁定为横屏
 */
fun Activity.lockScreenLandSpace(activity: Activity) {
    activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}

/**
 * 是否是横屏
 */
fun Activity.isLandscape(): Boolean {
    val display = windowManager?.defaultDisplay
    when (display?.rotation) {
        Surface.ROTATION_0, Surface.ROTATION_180 -> return false
        Surface.ROTATION_90, Surface.ROTATION_270 -> return true
    }
    return false
}

/**
 * @param ：[context]
 * @return : boolean
 * @methodName ：isScreenLock created by luozhipeng on 15/12/17 21:46.
 * @description ：判断是否锁屏
 */
fun Context.isScreenLock(): Boolean {
    val km = applicationContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
    return km.inKeyguardRestrictedInputMode()
}


fun Activity.getWindowInsetsController(): WindowInsetsControllerCompat {
    return WindowCompat.getInsetsController(window, findViewById(android.R.id.content))
}

/**
 * 设置沉浸式状态栏
 * @param isTransparent 是否是透明状态栏 true:透明， false : 不透明
 */
fun Activity.setTransparentStatusBar(
    activity: Activity,
    isTransparent: Boolean = true,
    blackStatusBar: Boolean = false,
    statusBarColor: Int = Color.TRANSPARENT,
) {
    WindowCompat.setDecorFitsSystemWindows(activity.window, isTransparent.not())
    activity.window.statusBarColor = statusBarColor

    getWindowInsetsController().let {
        it.isAppearanceLightStatusBars = blackStatusBar
        it.isAppearanceLightNavigationBars = blackStatusBar
    }
}

/**
 * 显示系统UI(状态栏、导航栏)
 */
fun Activity.showSystemUI() {
    WindowCompat.setDecorFitsSystemWindows(window, true)
    getWindowInsetsController().show(WindowInsetsCompat.Type.systemBars())
}

/**
 * 隐藏系统UI(状态栏、导航栏)
 */
fun Activity.hideSystemUI() {
    WindowCompat.setDecorFitsSystemWindows(window, false)
    getWindowInsetsController().let {
        it.hide(WindowInsetsCompat.Type.systemBars())
        it.systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }
}

/**
 * 设置状态栏
 * @param statusBarColor 状态栏颜色
 * @param blackStatusBar true:状态栏文字黑色， false:状态栏文字白色
 */
fun Activity.setStatusBar(@ColorInt statusBarColor: Int, blackStatusBar: Boolean = false) {
    window.statusBarColor = statusBarColor
    getWindowInsetsController().let {
        it.show(WindowInsetsCompat.Type.statusBars())
        it.isAppearanceLightStatusBars = blackStatusBar
    }
}

/**
 * 隐藏状态栏
 */
fun Activity.hideStatusBar() {
    getWindowInsetsController().hide(WindowInsetsCompat.Type.statusBars())
}

/**
 * 显示状态栏
 */
fun Activity.showStatusBar(){
    getWindowInsetsController().show(WindowInsetsCompat.Type.statusBars())
}


/**
 * 显示导航栏
 * @param iconIsBlack icon颜色：true:黑色， false:白色
 */
fun Activity.showNavigationBar(iconIsBlack: Boolean = true) {
    getWindowInsetsController().let {
        it.show(WindowInsetsCompat.Type.navigationBars())
        it.isAppearanceLightNavigationBars = iconIsBlack
    }
}

/**
 * 移除导航栏
 */
fun Activity.hideNavigationBar(activity: Activity) {
    getWindowInsetsController().let {
        it.hide(WindowInsetsCompat.Type.navigationBars())
        it.systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }
}

private fun Activity.getWindowInsetsCompat(): WindowInsetsCompat? {
    return ViewCompat.getRootWindowInsets(findViewById(android.R.id.content))
}

/**
 * 判断导航栏是否显示
 */
fun Activity.navigationBarsIsVisible(): Boolean {
    val windowInsetsCompat: WindowInsetsCompat = getWindowInsetsCompat() ?: return false

    return windowInsetsCompat.isVisible(WindowInsetsCompat.Type.navigationBars())
            && windowInsetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom > 0
}

/**
 * 获取导航栏高度
 */
fun Activity.getNavigationBarsHeight(): Int {
    val windowInsetsCompat = getWindowInsetsCompat() ?: return 0
    return windowInsetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
}

/**
 * 获取状态栏高度
 */
fun Activity.getStatusBarHeight(): Int {
    val windowInsetsCompat = getWindowInsetsCompat() ?: return 0
    return windowInsetsCompat.getInsets(WindowInsetsCompat.Type.statusBars()).top
}


/**
 * 添加软键盘状态监听
 * @param show 软件盘展示
 * @param hide 软键盘隐藏
 */
fun Activity.addKeyBoardStatusChangeListener(show: KeyBoardShow, hide: KeyBoardHide){
    SoftKeyBoardUtils.setListener(this, show, hide)
}

/**
 * 截屏
 */
fun Activity.screenShot(isDeleteStatusBar: Boolean = false): Bitmap {
    val decorView = window.decorView
    decorView.isDrawingCacheEnabled = true
    decorView.buildDrawingCache()
    val bmp = decorView.drawingCache
    val dm = DisplayMetrics()
    windowManager.defaultDisplay.getMetrics(dm)
    val ret: Bitmap = if (isDeleteStatusBar) {
        val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
        val statusBarHeight = resources.getDimensionPixelSize(resourceId)
        Bitmap.createBitmap(bmp, 0, statusBarHeight, dm.widthPixels, dm.heightPixels - statusBarHeight)
    } else {
        Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels)
    }
    decorView.destroyDrawingCache()
    return ret
}


/**
 * 屏幕锁定
 * @param isLock 是否锁定方向
 * @param isSystemOrientation 是否跟随系统方向设定
 */
fun Activity.lockScreenOrientation(isLock: Boolean, isSystemOrientation: Boolean) {
    try {

        if (isLock) {
            /****** 锁定 ******/
            val display = windowManager.defaultDisplay
            val rotation = display.rotation
            when (rotation) {
                Surface.ROTATION_0 -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
                Surface.ROTATION_90 -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                Surface.ROTATION_180 -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
                Surface.ROTATION_270 -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                else -> requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }

        } else {
            if (isSystemOrientation) {
                /****** 跟随系统的方向设定 ******/
                requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
            } else {
                /****** 根据手机陀螺仪来设定方向 ******/
                requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
            }
        }

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

/**
 * 是否为RTL
 */
fun View.isLayoutRTL() : Boolean{
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
        View.LAYOUT_DIRECTION_RTL == layoutDirection
    }else{
        false
    }
}

