package com.lukouguoji.module_base

import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.content.res.Resources
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.provider.Settings
import android.util.Log
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import com.alibaba.android.arouter.launcher.ARouter
import com.wega.library.loadingDialog.LoadingDialog
import com.yanzhenjie.permission.AndPermission
import com.yanzhenjie.permission.runtime.Permission
import com.yzq.zxinglibrary.android.CaptureActivity
import com.yzq.zxinglibrary.bean.ZxingConfig
import com.yzq.zxinglibrary.common.Constant
import com.lukouguoji.module_base.util.DeviceUtil
import dev.utils.app.HandlerUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import me.jessyan.autosize.AutoSizeCompat
import me.jessyan.autosize.internal.CustomAdapt
import java.util.Timer
import java.util.TimerTask
import kotlin.coroutines.CoroutineContext


open class BaseActivity : AppCompatActivity(), CoroutineScope {
    private val job = Job()
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    private lateinit var loadingDialog: LoadingDialog

    //加载框超时处理
    private var timer: Timer? = null
    private var timerTask: TimerTask? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        // 必须在 super.onCreate 之前设置，避免进入页面后再旋转造成闪屏与重建
        applyDeviceOrientation()
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_base)
        Log.d("BaseActivity", "${javaClass.simpleName} ${DeviceUtil.describe()}")
        ActivityCollector.addActivity(this)
        ARouter.getInstance().inject(this);  /////////必须要写这行，自动注入解析
        loadingDialog = LoadingDialog(this)
    }

    /**
     * 按设备形态锁定屏幕方向 —— **兜底手段**
     *
     * 方向的主控权在 Manifest：各 Activity 统一写
     * `android:screenOrientation="@integer/screen_orientation"`，
     * 由资源限定符取值（`values/` = portrait，`values-sw600dp/` = userLandscape）。
     * 这样方向在**窗口创建阶段**就已确定，不会出现"先横屏、约 1 秒后转竖屏"的闪屏。
     *
     * 本方法只作为安全网：万一某个 Activity 的 Manifest 漏配（仍写死 userLandscape），
     * 至少还能在手机上纠正为竖屏——但那种情况下闪屏依旧存在，应当去补 Manifest。
     *
     * 子类如需特殊方向（如扫码页），覆写 [lockOrientationByDevice] 返回 false 即可跳过。
     */
    protected open fun applyDeviceOrientation() {
        if (!lockOrientationByDevice()) return
        try {
            requestedOrientation = if (DeviceUtil.isPhone(this)) {
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            } else {
                ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
            }
        } catch (e: Exception) {
            // 半透明 / 悬浮类 Activity 不允许指定方向，忽略即可
            Log.w("BaseActivity", "setRequestedOrientation failed: ${e.message}")
        }
    }

    /**
     * 是否由基类按设备形态自动锁定方向，默认开启
     */
    protected open fun lockOrientationByDevice(): Boolean = true

    override fun onDestroy() {
        super.onDestroy()
        job.cancel()
        ActivityCollector.removeActivity(this)
        loadingDialog.cancel()
        timer?.cancel()
    }

    /**
     * 设置左上角back按钮
     */
    open fun setBackArrow(title: String) {
        val toolbar: Toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)
        // 给左上角图标的左边加上一个返回的图标 。对应ActionBar.DISPLAY_HOME_AS_UP
        supportActionBar!!.setDisplayHomeAsUpEnabled(false)
        //设置actionBar的标题是否显示，对应ActionBar.DISPLAY_SHOW_TITLE。
        supportActionBar!!.setDisplayShowTitleEnabled(false)
        val titleName: TextView = findViewById(R.id.title_name)
        titleName.text = title
        val tool_back: View = findViewById(R.id.tool_back)
        tool_back.setOnClickListener {
            finish()
        }
        setResult(RESULT_OK)
    }


    /**
     * 点击左上角的返回按钮，结束本Activity
     * home就是左上角的小箭头，在toolbar上
     *
     * @param item
     * @return
     */
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == android.R.id.home) {
            finish()
            return true
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onBackPressed() {
        finish()
    }

    /**
     * 扫码功能
     */
    fun scanCode(requestCode: Int) {
        AndPermission.with(this)
            .runtime()
            .permission(Permission.CAMERA, Permission.READ_EXTERNAL_STORAGE)
            .onGranted { data: List<String?>? ->
                val intent = Intent(this, CaptureActivity::class.java)
                /*ZxingConfig是配置类
     *可以设置是否显示底部布局，闪光灯，相册，
     * 是否播放提示音  震动
     * 设置扫描框颜色等
     * 也可以不传这个参数
     * */
                val config = ZxingConfig()
                // config.setPlayBeep(false);//是否播放扫描声音 默认为true
                //  config.setShake(false);//是否震动  默认为true
                // config.setDecodeBarCode(false);//是否扫描条形码 默认为true
//                                config.setReactColor(R.color.colorAccent);//设置扫描框四个角的颜色 默认为白色
//                                config.setFrameLineColor(R.color.colorAccent);//设置扫描框边框颜色 默认无色
//                                config.setScanLineColor(R.color.colorAccent);//设置扫描线的颜色 默认白色
                config.isFullScreenScan = false //是否全屏扫描  默认为true  设为false则只会在扫描框中扫描
                intent.putExtra(Constant.INTENT_ZXING_CONFIG, config)
                startActivityForResult(intent, requestCode)
            }
            .onDenied { data: List<String?>? ->
                val packageURI = Uri.parse("package:$packageName")
                val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                startActivity(intent)
                Toast.makeText(this, "没有权限无法扫描呦", Toast.LENGTH_LONG).show()
            }
            .start()
    }

    /**
     * 开始加载
     */
    fun loading() {
        loadingDialog.loading()
        loadingTimerStart()
    }

    /**
     * 结束加载
     */
    fun loadingCancel() {
        loadingDialog.cancel()
        loadingTimerStop()
    }

    /**
     * loading定时任务启动
     */
    private fun loadingTimerStart() {
        loadingTimerStop()

        timer = Timer()
        timerTask = object : TimerTask() {
            override fun run() {
                loadingDialog.loadFail()
            }
        }
        timer?.schedule(timerTask, 30 * 1000)//30秒后执行
    }

    /**
     * loading定时任务启动
     */
    private fun loadingTimerStop() {
        timer?.let {
            it.cancel()
            it.purge()
            timer = null
        }
        timerTask?.let {
            it.cancel()
            timerTask = null
        }
    }

    //region 点击隐藏键盘
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            val view = currentFocus
            if (isHideInput(view, ev)) {
                HideSoftInput(view!!.windowToken)
                view.clearFocus()
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    // 判定是否需要隐藏
    fun isHideInput(v: View?, ev: MotionEvent): Boolean {
        if (v != null && v is EditText) {
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            val left = l[0]
            val top = l[1]
            val bottom = top + v.getHeight()
            val right = (left
                    + v.getWidth())
            return !(ev.x > left && ev.x < right && ev.y > top && ev.y < bottom)
        }
        return false
    }

    // 隐藏软键盘
    fun HideSoftInput(token: IBinder?) {
        if (token != null) {
            val manager: InputMethodManager =
                getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            manager.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS)
        }
    }

    //endregion
    protected val FONT_NOT_SCALE: Float = 1f
    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        if (newConfig.fontScale != FONT_NOT_SCALE) {
            getResources();
        }
    }

    override fun getResources(): Resources? {
        //规避可能的空指针异常
        val res: Resources = super.getResources() ?: return null
        //强制字体大小不随系统改变而改变
        if (res.configuration.fontScale != FONT_NOT_SCALE) {
            val newConfig = Configuration()
            newConfig.setToDefaults()
            res.updateConfiguration(newConfig, res.displayMetrics)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                createConfigurationContext(newConfig)
            } else {
                res.updateConfiguration(newConfig, res.displayMetrics)
            }
        }
        HandlerUtils.postRunnable {
            if (this is CustomAdapt) {
                AutoSizeCompat.autoConvertDensity(res, sizeInDp, isBaseOnWidth)
            } else {
                AutoSizeCompat.autoConvertDensityOfGlobal(res)
            }
        }
        return res
    }
}