package com.remax.notification.newUtil

import android.Manifest
import android.app.*
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import android.provider.Settings
import android.widget.RemoteViews
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.ama.core.architecture.BaseApp
import com.ama.core.architecture.util.permission.PermissionUtil
import com.gamedog.statisticreporter.StatisticUtil
import com.remax.notification.NotifyConst
import com.remax.notification.R

class NotificationUtil private constructor() {

    companion object {
        private var instance: NotificationUtil? = null

        fun getInstance(): NotificationUtil {
            return instance ?: synchronized(this) {
                instance ?: NotificationUtil().also { instance = it }
            }
        }
    }

    private var mContext = BaseApp.appContext()
    private var notificationManager: NotificationManager = mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager


    /**
     * 创建通知渠道（Android 8.0+必需）
     */
    fun createNotificationChannel(channelId: String, channelName: String, importance: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(channelId, channelName, importance).apply {
                description = channelName
                enableLights(true)
                lightColor = Color.RED
                enableVibration(true)
            }
            notificationManager.createNotificationChannel(channel)
        }
    }

    /**
     * 1. 基本通知
     */
    fun showBasicNotification(notifiConfig: NotificationConfig) {
        val notificationId = notifiConfig.notificationId
        val channelId = notifiConfig.channelId
        val channelName = notifiConfig.channelName
        val title = notifiConfig.title
        val content = notifiConfig.content
        val smallIcon = notifiConfig.smallIcon
        val pendingIntent = notifiConfig.intent

        val notification = NotificationCompat.Builder(mContext, channelId)
            .setContentTitle(title)
            .setContentText(content)
            .setSmallIcon(smallIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()

        showNotification(notificationId, notification, channelName)
    }

    fun showBasicNotification_old(
        channelId: String,
        title: String,
        content: String,
        smallIcon: Int,
        intent: Intent? = null,
        notificationId: Int = System.currentTimeMillis().toInt()
    ) {
        val pendingIntent = intent?.let {
            PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
        }

        val notification = NotificationCompat.Builder(mContext, channelId)
            .setContentTitle(title)
            .setContentText(content)
            .setSmallIcon(smallIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()

        showNotification(notificationId, notification, "name")
    }

    /**
     * 2. 大文本样式通知
     */
    fun showBigTextNotification(
        channelId: String,
        title: String,
        content: String,
        bigText: String,
        smallIcon: Int,
        intent: Intent? = null,
        notificationId: Int = System.currentTimeMillis().toInt()
    ) {
        val pendingIntent = intent?.let {
            PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
        }

        val bigTextStyle = NotificationCompat.BigTextStyle()
            .bigText(bigText)
            .setBigContentTitle(title)
            .setSummaryText(content)

        val notification = NotificationCompat.Builder(mContext, channelId)
            .setStyle(bigTextStyle)
            .setContentTitle(title)
            .setContentText(content)
            .setSmallIcon(smallIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()

        showNotification(notificationId, notification, "name")
    }

    /**
     * 3. 大图片样式通知
     */
    fun showBigPictureNotification(
        channelId: String,
        title: String,
        content: String,
        bigPictureResId: Int,
        smallIcon: Int,
        intent: Intent? = null,
        notificationId: Int = System.currentTimeMillis().toInt()
    ) {
        val pendingIntent = intent?.let {
            PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
        }

        val bigPicture = BitmapFactory.decodeResource(mContext.resources, bigPictureResId)
        val bigPictureStyle = NotificationCompat.BigPictureStyle()
            .bigPicture(bigPicture)
            .setBigContentTitle(title)
            .setSummaryText(content)

        val notification = NotificationCompat.Builder(mContext, channelId)
            .setStyle(bigPictureStyle)
            .setContentTitle(title)
            .setContentText(content)
            .setSmallIcon(smallIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()

        showNotification(notificationId, notification, "name")
    }

    /**
     * 4. 进度条通知
     */
    fun showProgressNotification(
        channelId: String,
        title: String,
        content: String,
        smallIcon: Int,
        maxProgress: Int,
        currentProgress: Int,
        indeterminate: Boolean = false,
        notificationId: Int = System.currentTimeMillis().toInt()
    ) {
        val notification = NotificationCompat.Builder(mContext, channelId)
            .setContentTitle(title)
            .setContentText(content)
            .setSmallIcon(smallIcon)
            .setProgress(maxProgress, currentProgress, indeterminate)
            .setOngoing(!indeterminate) // 确定进度的通知持续显示
            .setAutoCancel(true)
            .build()

        showNotification(notificationId, notification, "name")
    }

    /**
     * 5. 带操作按钮的通知
     */
    fun showActionNotification(
        channelId: String,
        title: String,
        content: String,
        smallIcon: Int,
        actions: List<NotificationAction>,
        intent: Intent? = null,
        notificationId: Int = System.currentTimeMillis().toInt()
    ) {
        val pendingIntent = intent?.let {
            PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
        }

        val builder = NotificationCompat.Builder(mContext, channelId)
            .setContentTitle(title)
            .setContentText(content)
            .setSmallIcon(smallIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)

        // 添加操作按钮（最多3个）
        actions.take(3).forEach { action ->
            val actionPendingIntent = PendingIntent.getActivity(
                mContext,
                action.requestCode,
                action.intent,
                PendingIntent.FLAG_IMMUTABLE
            )
            builder.addAction(action.smallIcon, action.title, actionPendingIntent)
        }

        showNotification(notificationId, builder.build(), "name")
    }

    /**
     * 6. 收件箱样式通知（多行文本）
     */
    fun showInboxNotification(
        channelId: String,
        title: String,
        lines: List<String>,
        smallIcon: Int,
        intent: Intent? = null,
        notificationId: Int = System.currentTimeMillis().toInt()
    ) {
        val pendingIntent = intent?.let {
            PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
        }

        val inboxStyle = NotificationCompat.InboxStyle()
            .setBigContentTitle(title)
            .setSummaryText("${lines.size}条新消息")

        lines.take(7).forEach { line -> // 最多显示7行
            inboxStyle.addLine(line)
        }

        val notification = NotificationCompat.Builder(mContext, channelId)
            .setStyle(inboxStyle)
            .setContentTitle(title)
            .setContentText("您有${lines.size}条新消息")
            .setSmallIcon(smallIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setNumber(lines.size) // 显示消息数量
            .build()

        showNotification(notificationId, notification, "name")
    }

    /**
     * 7. 自定义布局通知
     */
    fun showCustomNotification(
        channelId: String,
        layoutResId: Int,
        smallIcon: Int,
        customViews: Map<Int, Any>, // viewId to value
        intent: Intent? = null,
        notificationId: Int = System.currentTimeMillis().toInt()
    ) {
        val pendingIntent = intent?.let {
            PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
        }

        val remoteViews = RemoteViews(mContext.packageName, layoutResId)

        // 设置自定义视图内容
        customViews.forEach { (viewId, value) ->
            when (value) {
                is String -> remoteViews.setTextViewText(viewId, value)
                is Int -> remoteViews.setImageViewResource(viewId, value)
                // 可以扩展其他类型...
            }
        }

        val notification = NotificationCompat.Builder(mContext, channelId)
            .setContent(remoteViews)
            .setSmallIcon(smallIcon)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setCustomContentView(remoteViews) // 设置自定义视图
            .build()

        showNotification(notificationId, notification, "name")
    }



    /**
     * 显示应用在后台时的顶部悬浮通知（Heads-up Notification）
     * 此方法会自动处理Android版本的兼容性
     *
     * @param channelId 通知渠道ID（Android 8.0+必须）
     * @param channelName 通知渠道名称（Android 8.0+必须）
     * @param title 通知标题
     * @param content 通知内容
     * @param smallIcon 小图标资源ID
     * @param intent 点击通知后要执行的Intent（可选）
     * @param useFullScreenIntent 是否使用全屏意图（来电等高优先级场景）
     * @param notificationId 通知ID
     */
    fun showHeadsUpNotification(notifiConfig: NotificationConfig) {
        val notificationId = notifiConfig.notificationId
        val channelId = notifiConfig.channelId
        val channelName = notifiConfig.channelName
        val title = notifiConfig.title
        val content = notifiConfig.content
        val smallIcon = notifiConfig.smallIcon
        val pendingIntent = notifiConfig.intent
        val useFullScreenIntent = notifiConfig.useFullScreenIntent



        // 1. 确保初始化
        val builder = NotificationCompat.Builder(mContext, channelId)

        // 2. 设置通知基本内容
        builder.setContentTitle(title)
            .setContentText(content)
            .setSmallIcon(smallIcon)
            .setAutoCancel(true)
            .setWhen(System.currentTimeMillis())

        // 3. 处理点击意图
        pendingIntent?.let { builder.setContentIntent(it) }

        // 4. 版本兼容性配置 - 这是触发Heads-up的关键
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android 8.0+ 使用通知渠道
            createHeadsUpNotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
            // 设置高重要性（会触发顶部悬浮）
            builder.setPriority(NotificationCompat.PRIORITY_MAX)
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // Android 5.0-7.1 使用优先级设置
            builder.setPriority(NotificationCompat.PRIORITY_MAX)
            // 添加声音和振动确保触发顶部悬浮
            builder.setDefaults(NotificationCompat.DEFAULT_ALL)
        } else {
            // Android 5.0以下版本不支持Heads-up，使用普通高优先级通知
            builder.setPriority(NotificationCompat.PRIORITY_HIGH)
            builder.setDefaults(NotificationCompat.DEFAULT_ALL)
        }


        // 5. 可选：全屏意图（用于最高优先级场景）
        if (useFullScreenIntent && pendingIntent != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            builder.setFullScreenIntent(pendingIntent, true)
        }

        // 6. 发送通知
        showNotification(notificationId, builder.build(), channelName)
    }

    /**
     * 创建用于顶部悬浮的高重要性通知渠道（Android 8.0+）
     */
    @RequiresApi(Build.VERSION_CODES.O)
    private fun createHeadsUpNotificationChannel(channelId: String, channelName: String, importance: Int) {
        // 检查是否已存在相同ID的渠道，避免重复创建
        if (notificationManager.getNotificationChannel(channelId) != null) {
            return
        }

        val channel = NotificationChannel(
            channelId,
            channelName,
            importance
        ).apply {
            description = "应用在后台时的重要通知，会以悬浮形式显示"
            enableLights(true)
            lightColor = Color.RED
            enableVibration(true)
            vibrationPattern = longArrayOf(0, 250, 250, 250)
            lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            // 设置锁定屏幕上的可见性
        }

        notificationManager.createNotificationChannel(channel)


    }

    fun showExpandableNotification(notifiConfig: NotificationConfig) {
        val notificationId = notifiConfig.notificationId
        val channelId = notifiConfig.channelId
        val channelName = notifiConfig.channelName
        val title = notifiConfig.title
        val content = notifiConfig.content
        val smallIcon = notifiConfig.smallIcon
        val pendingIntent = notifiConfig.intent
        val useFullScreenIntent = notifiConfig.useFullScreenIntent

        // 1. collapse
        val collapsedView = RemoteViews(mContext.packageName, R.layout.layout_notification_withdraw)
        collapsedView.setTextViewText(R.id.tvTitle, title)
        collapsedView.setTextViewText(R.id.tvDesc, content)
        collapsedView.setOnClickPendingIntent(R.id.tvAction, pendingIntent)

        // 2. expand
        val expandedView = RemoteViews(mContext.packageName, R.layout.layout_notification_withdraw_big)
        expandedView.setTextViewText(R.id.tvTitle, title)
        expandedView.setTextViewText(R.id.tvDesc, content)
        expandedView.setImageViewResource(R.id.ivBottom, R.mipmap.icon_withdraw_pt)
        expandedView.setOnClickPendingIntent(R.id.tvAction, pendingIntent)
        expandedView.setOnClickPendingIntent(R.id.ivBottom, pendingIntent)

        // 3. build
        val builder = NotificationCompat.Builder(mContext, channelId)
            .setSmallIcon(smallIcon)
            .setCustomContentView(collapsedView)
            .setCustomBigContentView(expandedView)
            .setStyle(NotificationCompat.DecoratedCustomViewStyle())
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)

        showNotification(notificationId, builder.build(), channelName, NotificationManager.IMPORTANCE_HIGH)
    }





















    private fun showNotification(notificationId: Int = System.currentTimeMillis().toInt(),
                                 notification: Notification,
                                 channelName: String,
                                 importance: Int = NotificationManager.IMPORTANCE_DEFAULT) {
        if (!isNotificationsEnabled()) {
            StatisticUtil.reportEvents(StatisticUtil.KEY_Push_Show)
            PermissionUtil.checkPermission(Manifest.permission.POST_NOTIFICATIONS, object : PermissionUtil.ICallback() {
                override fun onAllGranted() {
                    doShowNotification(notificationId, notification, channelName, importance)
                    StatisticUtil.reportEvents(StatisticUtil.KEY_Push_Request_Result, mapOf("Push_Result" to 1))
                }

                override fun onPartialGranted() {
                    StatisticUtil.reportEvents(StatisticUtil.KEY_Push_Request_Result, mapOf("Push_Result" to 0))
                }

                override fun onAllRejected() {
                    StatisticUtil.reportEvents(StatisticUtil.KEY_Push_Request_Result, mapOf("Push_Result" to 0))
                }
            })
        } else {
            doShowNotification(notificationId, notification, channelName, importance)
        }
    }

    @RequiresPermission(Manifest.permission.POST_NOTIFICATIONS)
    private fun doShowNotification(notificationId: Int = System.currentTimeMillis().toInt(), notification: Notification, channelName: String, importance: Int = NotificationManager.IMPORTANCE_DEFAULT) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && notificationManager.getNotificationChannel(notification.channelId) == null) {
            createNotificationChannel(notification.channelId, channelName, importance)
        }
        NotificationManagerCompat.from(mContext).notify(notificationId, notification)

        StatisticUtil.reportEvents(StatisticUtil.KEY_Push_Show, mapOf(
            "Push_Position" to 1,
            "Push_Type" to 1
        ))
    }


    /**
     * 检查通知权限
     */
    fun isNotificationsEnabled(): Boolean {
        return NotificationManagerCompat.from(mContext).areNotificationsEnabled()
    }

    /**
     * 检查特定渠道是否启用（Android 8.0+）
     */
    fun isNotificationChannelEnabled(channelId: String): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = notificationManager.getNotificationChannel(channelId)
            return channel?.importance != NotificationManager.IMPORTANCE_NONE
        }
        return true
    }

    /**
     * 取消通知
     */
    fun cancelNotification(notificationId: Int) {
        NotificationManagerCompat.from(mContext).cancel(notificationId)
    }

    /**
     * 取消所有通知
     */
    fun cancelAllNotifications() {
        NotificationManagerCompat.from(mContext).cancelAll()
    }

    /**
     * 更新进度通知
     */
    fun updateProgress(
        notificationId: Int,
        channelId: String,
        title: String,
        content: String,
        smallIcon: Int,
        maxProgress: Int,
        currentProgress: Int,
        indeterminate: Boolean = false
    ) {
        showProgressNotification(channelId, title, content, smallIcon, maxProgress, currentProgress, indeterminate, notificationId)
    }


    fun checkOverlayPermission(callback: PermissionUtil.ICallback) {
        /*if (!Settings.canDrawOverlays(BaseApp.appContext())) {
            if (System.currentTimeMillis() - NotificationRecorder.getLastSystemAlertShowTime() >= NotifyConst.MIN_INTERVAL_SHOW_SYSTEM_ALERT) {
                PermissionUtil.checkPermission(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, callback)
                NotificationRecorder.setLastSystemAlertShowTime()
            }

        }*/
    }

}

/**
 * 操作按钮数据类
 */
data class NotificationAction(
    val title: String,
    val intent: Intent,
    val smallIcon: Int,
    val requestCode: Int
)