package com.remax.notification.builder

import android.app.ActivityOptions
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Environment
import android.widget.RemoteViews
import com.blankj.utilcode.util.StringUtils
import com.example.features.notification.controller.NotificationRemoteViewsBuilder
import com.remax.base.utils.FileScanner
import com.remax.notification.R
import com.remax.notification.check.NotificationCheckController
import com.remax.notification.config.PushContent
import com.remax.notification.config.PushContentController
import com.remax.notification.newUtil.NotificationDatas
import com.remax.notification.service.NotificationKeepAliveServiceManager
import java.io.File
import java.time.LocalDate
import kotlin.random.Random


enum class NotificationType {
    GENERAL,
    RESIDENT, RESIDENT_RESTORED, RESIDENT_RESTORED_FILE,
    WIDGET_SCREENSHOT_CLEAN,WIDGET_PHOTO_RECOVERY,WIDGET_PHOTO_DOCUMENT,
    // new
    RESIDENT_GOLD, RESIDENT_WITHDRAW, RESIDENT_BOX, RESIDENT_GAME,
}

val type2notificationId = mapOf(
    NotificationType.GENERAL to 10000,
    NotificationType.RESIDENT to 10001,
    NotificationType.RESIDENT_RESTORED to 10002,
    NotificationType.RESIDENT_RESTORED_FILE to 10003,
    NotificationType.WIDGET_SCREENSHOT_CLEAN to 10004,
    NotificationType.WIDGET_PHOTO_RECOVERY to 10005,
    NotificationType.WIDGET_PHOTO_DOCUMENT to 10006,


    // new
    NotificationType.RESIDENT_GOLD to 20001,
    NotificationType.RESIDENT_WITHDRAW to 20002,
    NotificationType.RESIDENT_BOX to 20003,
    NotificationType.RESIDENT_GAME to 20004,
)

val LANDING_NOTIFICATION_ID = "landing_notification_id"
val LANDING_NOTIFICATION_ACTION = "landing_notification_action"
val LANDING_NOTIFICATION_FROM = "landing_notification_from"
val LANDING_NOTIFICATION_TITLE = "landing_notification_title"
val LANDING_NOTIFICATION_CONTENT = "landing_notification_content"

/**
 * 通知数据对象
 */
class GeneralNotificationData(
    val notificationId: Int,
    val contentTitle: String,
    val contentContent: String,
    val contentIntent: PendingIntent? = null,
    val contentView: RemoteViews? = null,
    val bigContentView: RemoteViews? = null,
)

fun entryPointPendingIntent(
    context: Context,
    notificationId: Int,
    applyIntent: ((Intent) -> Unit)? = null,
): PendingIntent {
    val intent = entryPointIntent(context)
    intent.putExtra(LANDING_NOTIFICATION_ID, notificationId)
    applyIntent?.invoke(intent)


    val options = if (Build.VERSION.SDK_INT >= 35) {
        ActivityOptions.makeBasic().apply {
            setPendingIntentCreatorBackgroundActivityStartMode(
                ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
            )
        }.toBundle()
    } else {
        null
    }

    return PendingIntent.getActivity(
        context,
        notificationId,
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        options
    )
}

fun entryPointIntent(context: Context): Intent =
    Intent().apply {
        // 使用 Action 方式跳转，避免直接依赖外部 Activity
        action = "com.remax.notification.ACTION_OPEN_APP"
        addCategory(Intent.CATEGORY_DEFAULT)
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
        // 设置包名，确保跳转到正确的应用
        setPackage(context.packageName)
        // 添加通知来源标识
        putExtra("from_notification", true)
        putExtra("notification_timestamp", System.currentTimeMillis())
    }

/**
 * 重置红点显示状态（用于测试或特殊情况）
 * @param context 上下文
 */
fun resetRedPointStatus(context: Context) {
    try {
        val sharedPreferences =
            context.getSharedPreferences("notification_red_point", Context.MODE_PRIVATE)
        sharedPreferences.edit()
            .remove("has_clicked_today")
            .remove("last_click_date")
            .apply()
    } catch (e: Exception) {
        // 忽略异常
    }
}

/**
 * 检查是否应该显示红点（点击后才隐藏）
 * @param context 上下文
 * @return true 如果应该显示红点，false 如果不应该显示
 */
private fun shouldShowRedPoint(context: Context): Boolean {
    return try {
        val sharedPreferences =
            context.getSharedPreferences("notification_red_point", Context.MODE_PRIVATE)
        val hasClickedToday = sharedPreferences.getBoolean("has_clicked_today", false)
        val lastClickDate = sharedPreferences.getString("last_click_date", "")
        val today = LocalDate.now().toString()

        // 如果是新的一天，重置点击状态
        if (lastClickDate != today) {
            sharedPreferences.edit()
                .putBoolean("has_clicked_today", false)
                .putString("last_click_date", today)
                .apply()
            return true // 新的一天显示红点
        }

        // 如果今天还没点击过，显示红点
        !hasClickedToday
    } catch (e: Exception) {
        // 异常情况下默认显示红点
        true
    }
}

/**
 * 标记红点已点击（隐藏红点）
 * @param context 上下文
 */
fun markRedPointClicked(context: Context) {
    try {
        val sharedPreferences =
            context.getSharedPreferences("notification_red_point", Context.MODE_PRIVATE)
        val today = LocalDate.now().toString()
        sharedPreferences.edit()
            .putBoolean("has_clicked_today", true)
            .putString("last_click_date", today)
            .apply()

        NotificationKeepAliveServiceManager.startKeepAliveService(context)
    } catch (e: Exception) {
        // 忽略异常
    }
}

/**
 * 计算恢复文件数量
 * @param context 上下文
 * @return 文件数量，如果出错则返回 0
 */
private fun getRecoveredFileCount(context: Context): Int {
    return try {
        val externalStorage = Environment.getExternalStorageDirectory()
        val copyDir = File(externalStorage, FileScanner.COPY_DIR)

        if (!copyDir.exists() || !copyDir.isDirectory) {
            return 0
        }

        var fileCount = 0
        copyDir.listFiles()?.forEach { subDir ->
            if (subDir.isDirectory) {
                subDir.listFiles()?.let { files ->
                    fileCount += files.size
                }
            }
        }
        fileCount
    } catch (e: Exception) {
        // 忽略无权限等异常情况
        0
    }
}

class GeneralModelManager() {

    fun getModel(context: Context,type:NotificationCheckController.NotificationType): GeneralNotificationData {
        val notificationId = type2notificationId[NotificationType.GENERAL] ?: 0
        val data = PushContentController.getNextPushContent()!!
        val title = data.title
        val content = data.desc
        val pendingIntent = entryPointPendingIntent(context, notificationId) {
            it.putExtra(LANDING_NOTIFICATION_ACTION, data.actionType)
            it.putExtra(LANDING_NOTIFICATION_FROM, type.string)
            it.putExtra(LANDING_NOTIFICATION_TITLE, title)
            it.putExtra(LANDING_NOTIFICATION_CONTENT, content)
        }

        val badgeCount = Random.nextInt(1, 100).toString()
        val contentView = NotificationRemoteViewsBuilder(
            context.packageName,
            R.layout.layout_notification_general_12,
            R.layout.layout_notification_general
        )
            .setImageViewResource(
                R.id.iv, when (data.iconType) {
                    PushContent.ICON_TYPE_PHOTO -> R.drawable.ic_noti_photo
                    PushContent.ICON_TYPE_VIDEO -> R.drawable.ic_noti_video
                    PushContent.ICON_TYPE_DOCUMENT -> R.drawable.ic_noti_document
                    PushContent.ICON_TYPE_AUDIO -> R.drawable.ic_noti_audio
                    PushContent.ICON_TYPE_SCREENSHOT -> R.drawable.ic_noti_shot
                    PushContent.ICON_TYPE_RECOVERED -> R.drawable.ic_noti_recover
                    else -> R.drawable.ic_noti_photo
                }
            )
            .setTextViewText(R.id.tvCount, badgeCount)
            .setTextViewText(R.id.tvTitle, title)
            .setTextViewText(R.id.tvDesc, content)
            .setTextViewText(
                R.id.tvAction, when (data.iconType) {
                    PushContent.ICON_TYPE_SCREENSHOT -> StringUtils.getString(R.string.noti_clean)
                    else -> StringUtils.getString(R.string.noti_recovery)
                }
            )
            .build()

        val bigContentView = NotificationRemoteViewsBuilder(
            context.packageName,
            R.layout.layout_notification_general_big_12,
            R.layout.layout_notification_general_big
        )
            .setImageViewResource(
                R.id.iv, when (data.iconType) {
                    PushContent.ICON_TYPE_PHOTO -> R.drawable.ic_noti_photo
                    PushContent.ICON_TYPE_VIDEO -> R.drawable.ic_noti_video
                    PushContent.ICON_TYPE_DOCUMENT -> R.drawable.ic_noti_document
                    PushContent.ICON_TYPE_AUDIO -> R.drawable.ic_noti_audio
                    PushContent.ICON_TYPE_SCREENSHOT -> R.drawable.ic_noti_shot
                    PushContent.ICON_TYPE_RECOVERED -> R.drawable.ic_noti_recover
                    else -> R.drawable.ic_noti_photo
                }
            )
            .setTextViewText(R.id.tvCount, badgeCount)
            .setTextViewText(R.id.tvTitle, title)
            .setTextViewText(R.id.tvDesc, content)
            .setTextViewText(
                R.id.tvAction, when (data.iconType) {
                    PushContent.ICON_TYPE_SCREENSHOT -> StringUtils.getString(R.string.noti_clean)
                    else -> StringUtils.getString(R.string.noti_recovery)
                }
            )
            .build()

        return GeneralNotificationData(
            notificationId = notificationId,
            contentTitle = title,
            contentContent = content,
            contentIntent = pendingIntent,
            contentView = contentView,
            bigContentView = bigContentView
        )
    }
}


class FixTimeModelManager() {

    fun getModel(context: Context,type:NotificationCheckController.NotificationType): GeneralNotificationData {
        val notificationId = type2notificationId[NotificationType.GENERAL] ?: 0
        val data = PushContentController.getNextPushContent()!!
        val title = data.title
        val content = data.desc
        val pendingIntent = entryPointPendingIntent(context, notificationId) {
            it.putExtra(LANDING_NOTIFICATION_ACTION, data.actionType)
            it.putExtra(LANDING_NOTIFICATION_FROM, type.string)
            it.putExtra(LANDING_NOTIFICATION_TITLE, title)
            it.putExtra(LANDING_NOTIFICATION_CONTENT, content)
        }

        val badgeCount = Random.nextInt(1, 100).toString()
        val contentView = NotificationRemoteViewsBuilder(
            context.packageName,
            R.layout.layout_notification_beauty_12,
            R.layout.layout_notification_beauty
        )
            .setImageViewResource(
                R.id.iv, when (data.iconType) {
                    PushContent.ICON_TYPE_PHOTO -> R.drawable.ic_noti_photo
                    PushContent.ICON_TYPE_VIDEO -> R.drawable.ic_noti_video
                    PushContent.ICON_TYPE_DOCUMENT -> R.drawable.ic_noti_document
                    PushContent.ICON_TYPE_AUDIO -> R.drawable.ic_noti_audio
                    PushContent.ICON_TYPE_SCREENSHOT -> R.drawable.ic_noti_shot
                    PushContent.ICON_TYPE_RECOVERED -> R.drawable.ic_noti_recover
                    else -> R.drawable.ic_noti_photo
                }
            )
            .setTextViewText(R.id.tvCount, badgeCount)
            .setTextViewText(R.id.tvTitle, title)
            .setTextViewText(R.id.tvDesc, content)
            .setTextViewText(
                R.id.tvAction, when (data.iconType) {
                    PushContent.ICON_TYPE_SCREENSHOT -> StringUtils.getString(R.string.noti_clean)
                    else -> StringUtils.getString(R.string.noti_recovery)
                }
            )
            .build()

        val bigContentView = NotificationRemoteViewsBuilder(
            context.packageName,
            R.layout.layout_notification_beauty_12,
            R.layout.layout_notification_beauty
        )
            .setImageViewResource(
                R.id.iv, when (data.iconType) {
                    PushContent.ICON_TYPE_PHOTO -> R.drawable.ic_noti_photo
                    PushContent.ICON_TYPE_VIDEO -> R.drawable.ic_noti_video
                    PushContent.ICON_TYPE_DOCUMENT -> R.drawable.ic_noti_document
                    PushContent.ICON_TYPE_AUDIO -> R.drawable.ic_noti_audio
                    PushContent.ICON_TYPE_SCREENSHOT -> R.drawable.ic_noti_shot
                    PushContent.ICON_TYPE_RECOVERED -> R.drawable.ic_noti_recover
                    else -> R.drawable.ic_noti_photo
                }
            )
            .setTextViewText(R.id.tvCount, badgeCount)
            .setTextViewText(R.id.tvTitle, title)
            .setTextViewText(R.id.tvDesc, content)
            .setTextViewText(
                R.id.tvAction, when (data.iconType) {
                    PushContent.ICON_TYPE_SCREENSHOT -> StringUtils.getString(R.string.noti_clean)
                    else -> StringUtils.getString(R.string.noti_recovery)
                }
            )
            .build()

        return GeneralNotificationData(
            notificationId = notificationId,
            contentTitle = title,
            contentContent = content,
            contentIntent = pendingIntent,
            contentView = contentView,
            bigContentView = bigContentView
        )
    }
}

class ResidentModelManger {

    fun getModel(context: Context): GeneralNotificationData {
        val cashNum = NotificationDatas.getResidentDatas().getCashNumber()
        var cashStr = if (hasDecimalPart(cashNum)) String.format("%.2f", cashNum) else cashNum.toString()

        val contentView = NotificationRemoteViewsBuilder(
            context.packageName,
            R.layout.layout_notification_resident_12,
            R.layout.layout_notification_resident
        ).setTextViewText(R.id.tv_resident_gold, NotificationDatas.getResidentDatas().getGoldNumber().toString())
            .setTextViewText(R.id.tv_resident_cash, "R$" + cashStr)
            .setTextViewText(R.id.tv_resident_box, NotificationDatas.getResidentDatas().getBoxRestTimeStr())
            .setOnClickPendingIntent(
                R.id.resident_gold, entryPointPendingIntent(context,
                    type2notificationId[NotificationType.RESIDENT_GOLD] ?: 0
                ) {
                    it.putExtra(LANDING_NOTIFICATION_ACTION, PushContent.ACTION_TYPE_GOLD)
                    it.putExtra(LANDING_NOTIFICATION_FROM, NotificationCheckController.NotificationType.RESIDENT.string)
                })
            .setOnClickPendingIntent(
                R.id.resident_cash, entryPointPendingIntent(context,
                    type2notificationId[NotificationType.RESIDENT_WITHDRAW] ?: 0
                ) {
                    it.putExtra(LANDING_NOTIFICATION_ACTION, PushContent.ACTION_TYPE_WITHDRAW)
                    it.putExtra(LANDING_NOTIFICATION_FROM, NotificationCheckController.NotificationType.RESIDENT.string)
                })
            .setOnClickPendingIntent(
                R.id.resident_box, entryPointPendingIntent(context,
                    type2notificationId[NotificationType.RESIDENT_BOX] ?: 0
                ) {
                    it.putExtra(LANDING_NOTIFICATION_ACTION, PushContent.ACTION_TYPE_BOX)
                    it.putExtra(LANDING_NOTIFICATION_FROM, NotificationCheckController.NotificationType.RESIDENT.string)
                })

            .setOnClickPendingIntent(
                R.id.resident_game, entryPointPendingIntent(context,
                    type2notificationId[NotificationType.RESIDENT_GAME] ?: 0
                ) {
                    it.putExtra(LANDING_NOTIFICATION_ACTION, PushContent.ACTION_TYPE_GAME)
                    it.putExtra(LANDING_NOTIFICATION_FROM, NotificationCheckController.NotificationType.RESIDENT.string)
                })
            .build()

        return GeneralNotificationData(
            notificationId = type2notificationId[NotificationType.RESIDENT] ?: 0,
            contentTitle = StringUtils.getString(R.string.noti_resident_title),
            contentContent = StringUtils.getString(R.string.noti_resident_service_running),
            contentIntent = null,
            contentView = contentView,
            bigContentView = null
        )
    }

    fun hasDecimalPart(number: Double): Boolean {
        return Math.abs(number % 1) > 1e-10
    }
}
