package com.narutohuo.xindazhou.common.ui

import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.narutohuo.xindazhou.common.dialog.DialogHelper
import com.narutohuo.xindazhou.common.permission.PermissionHelper
import kotlinx.coroutines.launch

/**
 * 基础 Activity
 * 
 * 封装 UI 通用功能：
 * - ViewBinding 支持
 * - ActivityManager 集成（自动注册/注销）
 * - 屏幕方向统一管理（默认竖屏，子类可重写）
 * - 统一的加载状态管理
 * - 统一的错误提示
 * - 权限请求封装
 * - Activity 跳转封装
 * - 返回键处理
 * - 状态栏管理
 * - 生命周期管理
 * 
 * 使用方式：
 * ```kotlin
 * // 默认竖屏
 * class LoginActivity : BaseActivity<ActivityLoginBinding>() {
 *     override fun initView() {
 *         binding.btnLogin.setOnClickListener {
 *             startActivity<MainActivity>()
 *         }
 *     }
 * }
 * 
 * // 横屏 Activity
 * class VideoPlayerActivity : BaseActivity<ActivityVideoPlayerBinding>() {
 *     override val screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
 *     
 *     override fun onScreenOrientationChanged(orientation: Int) {
 *         // 处理屏幕方向变更
 *     }
 * }
 * 
 * // 跟随传感器
 * class CameraActivity : BaseActivity<ActivityCameraBinding>() {
 *     override val screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
 * }
 * ```
 */
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
    
    protected lateinit var binding: VB
    protected abstract fun getViewBinding(): VB
    
    // 是否启用返回键拦截（默认 false）
    protected open val enableBackKeyIntercept: Boolean = false
    
    // 是否启用沉浸式状态栏（默认 false）
    protected open val enableImmersiveStatusBar: Boolean = false
    
    // 屏幕方向设置（子类可重写）
    // 可选值：
    // - ActivityInfo.SCREEN_ORIENTATION_PORTRAIT（竖屏，默认）
    // - ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE（横屏）
    // - ActivityInfo.SCREEN_ORIENTATION_SENSOR（跟随传感器）
    // - ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED（跟随系统）
    // - ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT（竖屏，但允许180度旋转）
    // - ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE（横屏，但允许180度旋转）
    // 
    // 注意：
    // 1. 如果设置为固定方向（PORTRAIT 或 LANDSCAPE），屏幕旋转时不会触发配置变更
    // 2. 如果需要处理屏幕旋转，请使用 SENSOR 相关选项，并在 AndroidManifest 中声明 configChanges
    // 3. 建议在 app 模块的 AndroidManifest.xml 中为所有 Activity 添加：
    //    android:configChanges="orientation|keyboardHidden|screenSize"
    protected open val screenOrientation: Int = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    
    // 权限请求 Launcher
    private var permissionLauncher: ActivityResultLauncher<Array<String>>? = null
    
    // Activity 结果 Launcher
    private val activityResultLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        onActivityResult(result.resultCode, result.data)
    }
    
    // 加载状态（子类可重写自定义实现）
    protected open fun showLoading() {
        // 默认实现：显示加载提示
        // 子类可重写自定义加载UI
    }
    
    protected open fun hideLoading() {
        // 默认实现：隐藏加载提示
        // 子类可重写自定义加载UI
    }
    
    // 错误提示（子类可重写自定义实现）
    protected open fun showError(message: String) {
        MessageHelper.showToast(binding.root, message)
    }
    
    protected open fun showSuccess(message: String) {
        MessageHelper.showToast(binding.root, message)
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 注册到 ActivityManager
        ActivityManager.addActivity(this)
        
        // 设置屏幕方向（必须在 setContentView 之前设置）
        requestedOrientation = screenOrientation
        
        // 初始化 ViewBinding
        binding = getViewBinding()
        setContentView(binding.root)
        
        // 初始化状态栏
        if (enableImmersiveStatusBar) {
            StatusBarHelper.setImmersiveStatusBar(this)
        }
        
        // 初始化权限请求
        initPermissionLauncher()
        
        // 初始化视图和观察者
        initView()
        initObserver()
    }
    
    /**
     * 配置变更处理（屏幕旋转、键盘显示等）
     * 
     * 注意：此方法只有在 AndroidManifest.xml 中声明了 configChanges 时才会被调用
     * 建议在 app 模块的 AndroidManifest.xml 中为所有 Activity 添加：
     * android:configChanges="orientation|keyboardHidden|screenSize"
     * 
     * 如果未声明 configChanges，屏幕旋转时会重建 Activity（onCreate 会重新调用）
     */
    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        
        // 处理屏幕旋转等配置变更
        onScreenOrientationChanged(newConfig.orientation)
    }
    
    /**
     * 屏幕方向变更回调（子类可重写）
     * 
     * 当屏幕方向改变时调用（需要 AndroidManifest 中声明 configChanges）
     * 
     * @param orientation Configuration.ORIENTATION_PORTRAIT（竖屏）或 Configuration.ORIENTATION_LANDSCAPE（横屏）
     */
    protected open fun onScreenOrientationChanged(orientation: Int) {
        // 子类可重写处理屏幕方向变更
        // 例如：重新布局、刷新数据等
    }
    
    override fun onDestroy() {
        super.onDestroy()
        // 从 ActivityManager 中移除
        ActivityManager.removeActivity(this)
    }
    
    /**
     * 初始化权限请求 Launcher
     */
    private fun initPermissionLauncher() {
        permissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()
        ) { permissions ->
            onPermissionResult(permissions)
        }
    }
    
    /**
     * 权限请求结果回调（子类可重写）
     */
    protected open fun onPermissionResult(permissions: Map<String, Boolean>) {
        // 子类可重写处理权限结果
    }
    
    /**
     * Activity 结果回调（子类可重写）
     */
    protected open fun onActivityResult(resultCode: Int, data: Intent?) {
        // 子类可重写处理 Activity 结果
    }
    
    /**
     * 初始化视图（子类实现）
     */
    protected open fun initView() {}
    
    /**
     * 初始化观察者（子类实现）
     */
    protected open fun initObserver() {}
    
    // ========== Activity 跳转封装 ==========
    
    /**
     * 启动 Activity（泛型方式）
     */
    fun <T : AppCompatActivity> startActivity(clazz: Class<T>) {
        ActivityManager.startActivity(this, clazz)
    }
    
    /**
     * 启动 Activity（泛型方式，带参数）
     */
    fun <T : AppCompatActivity> startActivity(
        clazz: Class<T>,
        block: Intent.() -> Unit
    ) {
        ActivityManager.startActivity(this, clazz, block)
    }
    
    /**
     * 启动 Activity 并关闭当前
     */
    fun <T : AppCompatActivity> startActivityAndFinish(clazz: Class<T>) {
        ActivityManager.startActivityAndFinish(this, clazz)
    }
    
    /**
     * 启动 Activity 并关闭当前（带参数）
     */
    fun <T : AppCompatActivity> startActivityAndFinish(
        clazz: Class<T>,
        block: Intent.() -> Unit
    ) {
        ActivityManager.startActivityAndFinish(this, clazz, block)
    }
    
    /**
     * 启动 Activity 并清空栈
     */
    fun <T : AppCompatActivity> startActivityAndClearTask(clazz: Class<T>) {
        ActivityManager.startActivityAndClearTask(this, clazz)
    }
    
    /**
     * 启动 Activity 并清空栈（带参数）
     */
    fun <T : AppCompatActivity> startActivityAndClearTask(
        clazz: Class<T>,
        block: Intent.() -> Unit
    ) {
        ActivityManager.startActivityAndClearTask(this, clazz, block)
    }
    
    /**
     * 启动 Activity 并获取结果
     */
    fun <T : AppCompatActivity> startActivityForResult(
        clazz: Class<T>,
        block: Intent.() -> Unit = {}
    ) {
        val intent = Intent(this, clazz).apply(block)
        activityResultLauncher.launch(intent)
    }
    
    // ========== 权限请求封装 ==========
    
    /**
     * 请求权限
     */
    protected fun requestPermissions(vararg permissions: String) {
        permissionLauncher?.launch(arrayOf(*permissions))
    }
    
    /**
     * 请求权限（带说明）
     * 注意：此方法需要先注册权限请求器
     */
    protected fun requestPermissionsWithRationale(
        launcher: ActivityResultLauncher<Array<String>>,
        vararg permissions: String,
        rationale: String = "需要相关权限才能使用此功能",
        onResult: (Map<String, Boolean>) -> Unit = {}
    ) {
        // 检查权限是否已授予
        val allGranted = permissions.all { permission ->
            PermissionHelper.checkPermission(this, permission)
        }
        
        if (allGranted) {
            val result = permissions.associateWith { true }
            onPermissionResult(result)
            onResult(result)
            return
        }
        
        // 检查是否需要显示说明
        val needRationale = permissions.any { permission ->
            PermissionHelper.shouldShowRequestPermissionRationale(this, permission)
        }
        
        val permissionsArray = permissions.toList().toTypedArray()
        
        if (needRationale) {
            // 显示说明对话框
            showConfirm(
                title = "权限说明",
                message = rationale,
                onConfirm = {
                    PermissionHelper.requestPermissions(launcher, permissionsArray)
                },
                onCancel = {
                    val result = permissions.associateWith { false }
                    onPermissionResult(result)
                    onResult(result)
                }
            )
        } else {
            // 直接请求权限
            PermissionHelper.requestPermissions(launcher, permissionsArray)
        }
    }
    
    // ========== 对话框封装 ==========
    
    /**
     * 显示提示框（只有一个确定按钮）
     */
    protected fun showAlert(
        title: String? = null,
        message: String,
        confirmText: String = "确定",
        onConfirm: (() -> Unit)? = null
    ) {
        DialogHelper.showAlert(this, title, message, confirmText, onConfirm)
    }
    
    /**
     * 显示确认框
     */
    protected fun showConfirm(
        title: String? = null,
        message: String,
        confirmText: String = "确定",
        cancelText: String = "取消",
        onConfirm: (() -> Unit)? = null,
        onCancel: (() -> Unit)? = null
    ) {
        DialogHelper.showConfirm(this, title, message, confirmText, cancelText, onConfirm ?: {}, onCancel)
    }
    
    // ========== 返回键处理 ==========
    
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (enableBackKeyIntercept && keyCode == KeyEvent.KEYCODE_BACK) {
            return onBackKeyPressed() || super.onKeyDown(keyCode, event)
        }
        return super.onKeyDown(keyCode, event)
    }
    
    /**
     * 返回键按下处理（子类可重写）
     * @return true 表示已处理，false 表示未处理（继续默认行为）
     */
    protected open fun onBackKeyPressed(): Boolean {
        return false
    }
    
    /**
     * 双击返回键退出（子类可重写实现）
     */
    private var lastBackPressTime = 0L
    protected fun handleDoubleBackToExit(message: String = "再按一次退出应用"): Boolean {
        val currentTime = System.currentTimeMillis()
        if (currentTime - lastBackPressTime > 2000) {
            lastBackPressTime = currentTime
            showError(message)
            return true
        }
        return false
    }
    
    // ========== 状态栏管理 ==========
    
    /**
     * 设置状态栏颜色
     */
    protected fun setStatusBarColor(color: Int) {
        StatusBarHelper.setStatusBarColor(this, color)
    }
    
    /**
     * 设置状态栏文字颜色（浅色/深色模式）
     */
    protected fun setStatusBarLightMode(isLight: Boolean) {
        StatusBarHelper.setStatusBarLightMode(this, isLight)
    }
    
    /**
     * 设置沉浸式状态栏
     */
    protected fun setImmersiveStatusBar(isLight: Boolean = false) {
        StatusBarHelper.setImmersiveStatusBar(this, isLight)
    }
    
    // ========== 网络请求封装 ==========
    
    /**
     * 统一执行网络请求
     * 
     * 自动处理加载状态和错误提示
     */
    protected fun <T> executeRequest(
        request: suspend () -> Result<T>,
        onSuccess: (T) -> Unit,
        onError: ((String) -> Unit)? = null,
        showLoading: Boolean = true
    ) {
        lifecycleScope.launch {
            try {
                if (showLoading) showLoading()
                
                request()
                    .onSuccess { data ->
                        hideLoading()
                        onSuccess(data)
                    }
                    .onFailure { throwable ->
                        hideLoading()
                        val errorMsg = throwable.message ?: "操作失败"
                        if (onError != null) {
                            onError(errorMsg)
                        } else {
                            showError(errorMsg)
                        }
                    }
            } catch (e: Exception) {
                hideLoading()
                val errorMsg = e.message ?: "操作失败"
                if (onError != null) {
                    onError(errorMsg)
                } else {
                    showError(errorMsg)
                }
            }
        }
    }
    
    // ========== 其他便捷方法 ==========
    
    /**
     * 关闭当前 Activity
     */
    protected fun finishActivity() {
        finish()
    }
    
    /**
     * 关闭指定类型的 Activity
     */
    protected fun finishActivity(clazz: Class<out AppCompatActivity>) {
        ActivityManager.finishActivity(clazz)
    }
    
    /**
     * 返回到指定 Activity
     */
    protected fun backToActivity(clazz: Class<out AppCompatActivity>) {
        ActivityManager.backToActivity(clazz)
    }
    
    /**
     * 退出应用
     */
    protected fun exitApp() {
        ActivityManager.exitApp()
    }
}

