package com.remax.notification.controller

import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Handler
import android.os.Looper
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import com.ama.core.architecture.BaseApp
import com.ama.core.architecture.util.DateUtil
import com.ama.core.architecture.util.permission.PermissionUtil
import com.gamedog.statisticreporter.StatisticUtil
import com.remax.base.ext.canSendNotification
import com.remax.base.report.DataReportManager
import com.remax.notification.NotifyConst
import com.remax.notification.R
import com.remax.notification.builder.GeneralModelManager
import com.remax.notification.builder.GeneralNotificationData
import com.remax.notification.builder.NotificationType
import com.remax.notification.builder.ResidentModelManger
import com.remax.notification.builder.type2notificationId
import com.remax.notification.check.NotificationCheckController
import com.remax.notification.config.NotificationConfigController
import com.remax.notification.newUtil.NotificationRecorder
import com.remax.notification.newUtil.NotificationUtil
import com.remax.notification.receiver.NotificationDeleteReceiver
import com.remax.notification.service.NotificationKeepAliveService
import com.remax.notification.timing.NotificationTimingController
import com.remax.notification.utils.NotiLogger
import com.remax.notification.utils.TimeCheckUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


/**
 * 通知触发控制器
 * 提供常驻通知和普通通知的触发功能
 */
@SuppressLint("StaticFieldLeak", "MissingPermission")
object NotificationTriggerController {

    const val CHANNEL_ID_RESIDENT = "resident_notification"
    const val CHANNEL_ID_GENERAL = "general_notification"
    const val CHANNEL_ID_GENERAL_SILENT = "general_silent_notification"
    const val CHANNEL_ID_BEAUTY = "general_beauty"
    const val CHANNEL_NAME_RESIDENT = "recovery_resident"
    const val CHANNEL_NAME_GENERAL = "recovery_single"
    const val CHANNEL_NAME_GENERAL_SILENT = "recovery_loop"

    const val CHANNEL_NAME_BEAUTY = "beauty_single"

    private var notificationManager: NotificationManagerCompat? = null
    private var context: Context? = null

    // 全局协程作用域，用于异步构建通知
    private val notificationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

    // 重复通知相关（全局单例）
    private var repeatHandler: Handler? = null
    private var repeatRunnable: Runnable? = null
    private var repeatCount: Int = 0
    private var currentNotificationId: Int = 0

    private var mFixTimeHandler: Handler? = null
    private var mFixTimeRunnable: Runnable? = null

    /**
     * 初始化通知通道
     * @param context 上下文
     */
    @SuppressLint("NewApi")
    fun initializeChannels(context: Context) {
        this.context = context
        this.notificationManager = NotificationManagerCompat.from(context)

        // 常驻通知通道
        val residentChannel = NotificationChannel(
            CHANNEL_ID_RESIDENT, CHANNEL_NAME_RESIDENT, NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "for resident notification"
            importance = NotificationManager.IMPORTANCE_HIGH
            setShowBadge(false)
            enableLights(false)
            enableVibration(false)
        }

        // 普通通知通道
        val generalChannel = NotificationChannel(
            CHANNEL_ID_GENERAL, CHANNEL_NAME_GENERAL, NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "for general notification"
            setShowBadge(true)
            enableLights(false)
            enableVibration(false)
        }

        // beauty
        val beautyChannel = NotificationChannel(
            CHANNEL_ID_BEAUTY, CHANNEL_NAME_BEAUTY, NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "for beauty notification"
            setShowBadge(true)
            enableLights(false)
            enableVibration(false)
        }

        // 静音通知通道
        val silentChannel = NotificationChannel(
            CHANNEL_ID_GENERAL_SILENT,
            CHANNEL_NAME_GENERAL_SILENT,
            NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "for silent notification (repeat notifications)"
            setShowBadge(true)
            enableLights(false)
            enableVibration(false)
            setSound(null, null)  // 设置为静音
        }

        notificationManager?.createNotificationChannels(
            listOf(
                residentChannel, generalChannel, silentChannel, beautyChannel
            )
        )
        NotiLogger.d("通知通道创建完成")
    }


    /**
     * 通用通知触发方法
     * @param notificationType 通知类型
     * @param modelBuilder 通知数据构建函数
     * @param notificationBuilder 通知对象构建函数
     * @param onNotificationSent 通知发送完成回调
     */
    private fun triggerNotification(
        notificationType: String,
        modelBuilder: (Context) -> GeneralNotificationData,
        notificationBuilder: (GeneralNotificationData) -> Notification,
        onNotificationSent: ((GeneralNotificationData, Notification) -> Unit)? = null
    ) {
        val context = context ?: return
        val notificationManager = notificationManager ?: return

        // 使用全局协程异步构建通知
        notificationScope.launch {
            try {
                // 在 IO 线程中构建通知数据
                val notificationData = withContext(Dispatchers.IO) {
                    modelBuilder(context)
                }

                // 在 IO 线程中构建通知对象
                val notification = withContext(Dispatchers.IO) {
                    notificationBuilder(notificationData)
                }

                // 切换到主线程执行 notify
                withContext(Dispatchers.Main) {
                    notificationManager.notify(notificationData.notificationId, notification)
                    NotiLogger.d("${notificationType}发送成功，ID: ${notificationData.notificationId}")

                    // 调用通知完成回调
                    onNotificationSent?.invoke(notificationData, notification)
                }

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

            } catch (e: Exception) {
                NotiLogger.e("发送${notificationType}失败", e)
            }
        }
    }

    /**
     * 检查是否应该启用重复通知
     * @return 是否启用重复通知
     */
    private fun shouldEnableRepeatNotification(): Boolean {
        val configController = NotificationConfigController

        // 检查是否开启重复通知策略
        if (configController.getHoverDurationStrategySwitch() != 1) {
            return false
        }

        val loopCount = configController.getHoverDurationLoopCount()
        if (loopCount <= 0) {
            return false
        }

        return true
    }

    /**
     * 获取重复通知的循环次数
     * @return 循环次数
     */
    private fun getRepeatLoopCount(): Int {
        return NotificationConfigController.getHoverDurationLoopCount()
    }

    /**
     * 检查并启动重复通知
     * @param notificationId 通知ID
     * @param notification 通知对象
     */
    private fun checkAndStartRepeatNotification(notificationData: GeneralNotificationData,
                                                notification: Notification,
                                                type: NotificationCheckController.NotificationType) {
        // 检查是否应该启用重复通知
        if (!shouldEnableRepeatNotification()) {
            return
        }

        val loopCount = getRepeatLoopCount()

        // 停止之前的重复任务
        stopRepeatNotification()

        NotiLogger.d("开始重复通知，ID: ${notificationData.notificationId}，循环次数: $loopCount")

        // 初始化重复计数
        repeatCount = 0
        currentNotificationId = notificationData.notificationId

        // 创建 Handler
        repeatHandler = Handler(Looper.getMainLooper())


        // 创建重复任务
        repeatRunnable = object : Runnable {
            override fun run() {
                val maxCount = getRepeatLoopCount()

                if (repeatCount < maxCount) {
                    // 执行重复通知
                    notificationManager?.notify(currentNotificationId, notification)
                    NotiLogger.d("重复通知执行，ID: $currentNotificationId，第${repeatCount + 1}次")

                    // 增加计数
                    repeatCount++

                    // 埋点
                    generalTrack(type, notificationData)

                    // 4秒后再次执行
                    repeatHandler?.postDelayed(this, 1 * NotifyConst.MIN_INTERVAL_UNIT)
                } else {
                    // 达到最大次数，停止重复
                    stopRepeatNotification()
                    NotiLogger.d("重复通知完成，ID: $currentNotificationId，总次数: $maxCount")
                }
            }
        }

        // 4秒后开始第一次重复
        repeatHandler?.postDelayed(repeatRunnable!!, 4000)
    }


    private fun checkAndStartFixTimeNotification() {

        stopFixTimeNotification()

        mFixTimeHandler = Handler(Looper.getMainLooper())

        mFixTimeRunnable = object : Runnable {
            override fun run() {
                val lastFixNotifiShowMs = NotificationRecorder.getLastNotifyShowTime(NotificationCheckController.NotificationType.FIXTIMEPOINT.string)
                if (TimeCheckUtil.isTargetTime() && (DateUtil.getCurTimeMs() - lastFixNotifiShowMs > 60000)) {
                    NotificationTimingController.getInstance().triggerNotificationIfAllowed(NotificationCheckController.NotificationType.FIXTIMEPOINT)
                    NotificationRecorder.saveLastNotifyShowTime(NotificationCheckController.NotificationType.FIXTIMEPOINT.string, DateUtil.getCurTimeMs())
                    NotiLogger.d("固定时间节点通知，第${repeatCount + 1}次")
                }

                if (TimeCheckUtil.isDifferentHour()) {
                    // 更新常驻通知，主要是宝箱任务hour
                    NotificationKeepAliveService.updateNotification(BaseApp.appContext())
                }

                mFixTimeHandler?.postDelayed(this, 1000)
            }
        }

        mFixTimeHandler?.postDelayed(mFixTimeRunnable!!, 1000)
    }


    /**
     * 停止重复通知
     */
    fun stopRepeatNotification() {
        repeatHandler?.removeCallbacks(repeatRunnable ?: return)
        repeatHandler = null
        repeatRunnable = null
        repeatCount = 0

        NotiLogger.d("停止重复通知")
    }

    fun stopFixTimeNotification() {
        mFixTimeHandler?.removeCallbacks(mFixTimeRunnable ?: return)
        mFixTimeHandler = null
        mFixTimeRunnable = null
        NotiLogger.d("停止时间节点通知")
    }

    fun triggerResidentNotification() {
        if (context?.canSendNotification() == true) {
            triggerNotification(
                notificationType = "常驻通知",
                modelBuilder = { context -> ResidentModelManger().getModel(context) },
                notificationBuilder = { data -> resident(data) },
                onNotificationSent = { notificationData, notification ->
                    residentTrack(notificationData)
                })
        }
    }

    fun triggerGeneralNotification(
        type: NotificationCheckController.NotificationType, onNotificationSent: (() -> Unit)? = null
    ) {
        if (context?.canSendNotification() == true) {
            triggerNotification(
                notificationType = "常规通知",
                modelBuilder = { context -> GeneralModelManager().getModel(context, type) },
                notificationBuilder = { data -> general(data) },
                onNotificationSent = { notificationData, notification ->
                    onNotificationSent?.invoke()
                    generalTrack(type, notificationData)
                    // 检查是否需要重复通知
                    checkAndStartRepeatNotification(notificationData, notification, type)
                })
        }
    }

    fun triggerFixTimeNotification() {
        checkAndStartFixTimeNotification()
    }

    private fun resident(model: GeneralNotificationData) =
        NotificationCompat.Builder(context!!, CHANNEL_ID_RESIDENT)
            .setColor(ContextCompat.getColor(context!!, R.color.noti_color))
            .setSmallIcon(R.drawable.ic_noti_icon)
            .setContentTitle(model.contentTitle)
            .setContentText(model.contentContent)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setGroup(CHANNEL_ID_RESIDENT + model.notificationId)
            .setContentIntent(model.contentIntent).setCustomContentView(model.contentView)
            .setCustomBigContentView(model.contentView).setOngoing(true).setSilent(true).build()

    private fun general(model: GeneralNotificationData): Notification {
        // 根据重复通知配置选择通道
        val channelId = if (shouldEnableRepeatNotification()) {
            CHANNEL_ID_GENERAL_SILENT  // 使用静音通道
        } else {
            CHANNEL_ID_GENERAL // 使用普通通道
        }

        // 创建删除监听 Intent
        val deleteIntent = Intent(context, NotificationDeleteReceiver::class.java).apply {
            action = "com.remax.notification.ACTION_NOTIFICATION_DELETE"
        }
        val deletePendingIntent = PendingIntent.getBroadcast(
            context,
            System.currentTimeMillis().toInt(),
            deleteIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val builder = NotificationCompat.Builder(context!!, channelId)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setColor(ContextCompat.getColor(context!!, R.color.noti_color))
            .setSmallIcon(R.drawable.ic_noti_icon).setAutoCancel(true)
            .setGroup("push_" + System.currentTimeMillis()).setContentText(model.contentTitle)
            .setContentIntent(model.contentIntent).setDeleteIntent(deletePendingIntent)  // 设置删除监听
            .setCustomContentView(model.contentView).setCustomBigContentView(model.bigContentView)

        // 记录使用的通道
        if (shouldEnableRepeatNotification()) {
            NotiLogger.d("使用静音通道发送通知: $channelId")
        } else {
            NotiLogger.d("使用普通通道发送通知: $channelId")
        }

        return builder.apply {
            if (Build.VERSION.SDK_INT >= 31) {
                setCustomHeadsUpContentView(model.contentView)
            }
        }.build()
    }

    private fun fixTime(model: GeneralNotificationData): Notification {
        // 根据重复通知配置选择通道
        val channelId = CHANNEL_ID_BEAUTY

        // 创建删除监听 Intent
        val deleteIntent = Intent(context, NotificationDeleteReceiver::class.java).apply {
            action = "com.remax.notification.ACTION_NOTIFICATION_DELETE"
        }
        val deletePendingIntent = PendingIntent.getBroadcast(
            context,
            System.currentTimeMillis().toInt(),
            deleteIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val builder = NotificationCompat.Builder(context!!, channelId)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setColor(ContextCompat.getColor(context!!, R.color.noti_color))
            .setSmallIcon(R.drawable.ic_noti_icon).setAutoCancel(true)
            .setGroup("push_" + System.currentTimeMillis()).setContentText(model.contentTitle)
            .setContentIntent(model.contentIntent).setDeleteIntent(deletePendingIntent)  // 设置删除监听
            .setCustomContentView(model.contentView).setCustomBigContentView(model.bigContentView)

        // 记录使用的通道
        NotiLogger.d("使用普通通道发送通知: $channelId")

        return builder.apply {
            if (Build.VERSION.SDK_INT >= 31) {
                setCustomHeadsUpContentView(model.contentView)
            }
        }.build()
    }

    /**
     * 取消通知
     * @param notificationId 通知ID
     */
    fun cancelNotification(notificationId: Int) {
        // 停止重复通知
        stopRepeatNotification()

        // 取消通知
        notificationManager?.cancel(notificationId)
        NotiLogger.d("通知已取消，ID: $notificationId")
    }

    /**
     * 取消所有通知
     */
    fun cancelAllNotifications() {
        // 停止重复通知
        stopRepeatNotification()

        // 取消所有通知
        notificationManager?.cancelAll()
        NotiLogger.d("所有通知已取消")
    }

    /**
     * 检查并确保常驻通知存在
     * 如果通知中心不存在常驻通知，则触发常驻通知
     */
    @SuppressLint("MissingPermission")
    fun ensureResidentNotificationExists() {
        val notificationManager = notificationManager ?: return
        val residentNotificationId = type2notificationId[NotificationType.RESIDENT] ?: 0

        // 使用协程异步执行
        notificationScope.launch {
            try {
                // 检查通知中心是否存在指定ID的通知
                val activeNotifications = notificationManager.activeNotifications
                val hasResidentNotification =
                    activeNotifications.any { it.id == residentNotificationId }

                if (!hasResidentNotification) {
                    NotiLogger.d("通知中心不存在常驻通知(ID: $residentNotificationId)，尝试触发常驻通知")
                    triggerResidentNotification()
                } else {
                    NotiLogger.d("通知中心已存在常驻通知(ID: $residentNotificationId)")
                }
            } catch (e: Exception) {
                NotiLogger.e("检查常驻通知状态失败", e)
                // 检查失败时，为了安全起见，触发常驻通知
                triggerResidentNotification()
            }
        }
    }


    /**
     * 获取常驻通知的ID
     * @return 常驻通知ID
     */
    fun getResidentNotificationId(): Int = type2notificationId[NotificationType.RESIDENT] ?: 0

    /**
     * 构建常驻通知
     * @param context 上下文
     * @return 常驻通知对象
     */
    fun buildResidentNotification(context: Context): Notification {
        val residentModel = ResidentModelManger().getModel(context)
        if(context.canSendNotification()){
            residentTrack(residentModel)
        }
        return resident(residentModel)
    }

    private fun residentTrack(residentModel: GeneralNotificationData) {
        DataReportManager.reportData(
            "Notific_Show", mapOf(
                "Notific_Type" to 4,
                "Notific_Position" to 2,
                "Notific_Priority" to "PRIORITY_DEFAULT",
                "event_id" to "permanent",
                "title" to residentModel.contentTitle,
                "text" to residentModel.contentContent,
            )
        )
    }

    private fun generalTrack(
        type: NotificationCheckController.NotificationType,
        notificationData: GeneralNotificationData
    ) {
        DataReportManager.reportData(
            "Notific_Show", mapOf(
                "Notific_Type" to when (type) {
                    NotificationCheckController.NotificationType.UNLOCK -> 1
                    NotificationCheckController.NotificationType.BACKGROUND -> 1
                    NotificationCheckController.NotificationType.FIXTIMEPOINT -> 1
                    NotificationCheckController.NotificationType.KEEPALIVE -> 1
                    NotificationCheckController.NotificationType.FCM -> 3
                    else -> 4
                },
                "Notific_Position" to 1,
                "Notific_Priority" to "PRIORITY_MAX",
                "event_id" to "customer_general_style",
                "title" to notificationData.contentTitle,
                "text" to notificationData.contentContent,
            )
        )
    }

    private fun fixTimeTrack(
        type: NotificationCheckController.NotificationType,
        notificationData: GeneralNotificationData
    ) {
        DataReportManager.reportData(
            "Notific_Show", mapOf(
                "Notific_Type" to when (type) {
                    NotificationCheckController.NotificationType.UNLOCK -> 1
                    NotificationCheckController.NotificationType.BACKGROUND -> 1
                    NotificationCheckController.NotificationType.FIXTIMEPOINT -> 1
                    NotificationCheckController.NotificationType.KEEPALIVE -> 1
                    NotificationCheckController.NotificationType.FCM -> 3
                    else -> 4
                },
                "Notific_Position" to 1,
                "Notific_Priority" to "PRIORITY_MAX",
                "event_id" to "customer_general_style",
                "title" to notificationData.contentTitle,
                "text" to notificationData.contentContent,
            )
        )
    }
}
