package com.lukouguoji.module_base.util

import android.content.Context
import android.content.res.Resources
import androidx.annotation.LayoutRes
import com.lukouguoji.module_base.MyApplication

/**
 * 设备形态判定工具
 *
 * 用于「平板（10 寸横屏）」与「手机（5.5 寸竖屏）」双形态适配：
 * 1. 识别当前设备是平板还是手机
 * 2. 提供按形态选择布局的入口（Activity 布局 / RecyclerView item 布局通用）
 * 3. 提供手机端 AutoSize 设计基准尺寸常量
 *
 * 判定依据：`smallestScreenWidthDp`（最小屏幕宽度，与横竖屏无关，是 Android 官方推荐的设备分类维度）
 * - 5.5 寸手机 ≈ 360dp
 * - 10 寸平板 ≈ 800dp
 * - 分界线取官方标准 600dp
 *
 * 注意：这里读取的是 [Resources.getSystem]（系统资源）而非应用 Resources，
 * 目的是绕开 AndroidAutoSize 对 density 的动态改写，保证判定结果稳定。
 */
object DeviceUtil {

    /** 平板判定阈值：最小屏幕宽度 >= 600dp 视为平板 */
    private const val TABLET_MIN_WIDTH_DP = 600

    /** 手机端设计稿基准尺寸（对应 5.5 寸手持端设计稿画布 390 × 844） */
    const val PHONE_DESIGN_WIDTH_DP = 390
    const val PHONE_DESIGN_HEIGHT_DP = 844

    /** 平板端设计稿基准尺寸（沿用现有配置） */
    const val TABLET_DESIGN_WIDTH_DP_LAND = 1152
    const val TABLET_DESIGN_HEIGHT_DP_LAND = 720
    const val TABLET_DESIGN_WIDTH_DP_PORT = 720
    const val TABLET_DESIGN_HEIGHT_DP_PORT = 1280

    /**
     * 调试用：强制指定设备形态
     *
     * 开发阶段可在平板上强制走手机布局做验证，正式发布保持 [ForceMode.AUTO]。
     * 用法：`DeviceUtil.forceMode = DeviceUtil.ForceMode.PHONE`
     */
    enum class ForceMode { AUTO, PHONE, TABLET }

    @JvmStatic
    var forceMode: ForceMode = ForceMode.AUTO

    /** 缓存自动判定结果，避免每次都读 Configuration */
    private var cachedIsTablet: Boolean? = null

    /**
     * 是否平板
     * @param context 可不传，默认用 Application 上下文（判定与具体 Activity 无关）
     */
    @JvmStatic
    @JvmOverloads
    fun isTablet(context: Context? = null): Boolean = when (forceMode) {
        ForceMode.PHONE -> false
        ForceMode.TABLET -> true
        ForceMode.AUTO -> cachedIsTablet ?: (smallestWidthDp(context) >= TABLET_MIN_WIDTH_DP)
            .also { cachedIsTablet = it }
    }

    /** 是否手机 */
    @JvmStatic
    @JvmOverloads
    fun isPhone(context: Context? = null): Boolean = !isTablet(context)

    /**
     * 获取最小屏幕宽度(dp)
     *
     * 优先读系统资源（不受 AutoSize 影响）；异常时回退到应用资源。
     */
    @JvmStatic
    @JvmOverloads
    fun smallestWidthDp(context: Context? = null): Int {
        val fromSystem = Resources.getSystem()?.configuration?.smallestScreenWidthDp ?: 0
        if (fromSystem > 0) return fromSystem

        val res = (context ?: runCatching { MyApplication.context }.getOrNull())?.resources
        return res?.configuration?.smallestScreenWidthDp ?: TABLET_MIN_WIDTH_DP
    }

    /**
     * 按设备形态选择布局
     *
     * @param tabletLayout 平板布局（现有布局，必填）
     * @param phoneLayout  手机布局；传 0 或未提供时，手机上回退使用平板布局
     * @return 当前设备应加载的布局 id
     *
     * 用法（ViewModel 中选择 item 布局）：
     * ```
     * val itemLayoutId = DeviceUtil.layout(R.layout.item_xxx, R.layout.item_xxx_phone)
     * ```
     */
    @JvmStatic
    @JvmOverloads
    fun layout(
        @LayoutRes tabletLayout: Int,
        @LayoutRes phoneLayout: Int = 0,
        context: Context? = null
    ): Int = if (phoneLayout != 0 && isPhone(context)) phoneLayout else tabletLayout

    /** 配置发生变化时清空缓存（如分屏、折叠屏形态切换） */
    @JvmStatic
    fun clearCache() {
        cachedIsTablet = null
    }

    /** 设备形态描述，用于日志排查 */
    @JvmStatic
    fun describe(): String =
        "${if (isTablet()) "TABLET" else "PHONE"}(sw=${smallestWidthDp()}dp, force=$forceMode)"
}
