package cc.winboll.studio.powerbell.utils;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.os.Build;
import android.provider.Settings;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.powerbell.MainActivity;
import cc.winboll.studio.powerbell.R;
import cc.winboll.studio.powerbell.models.NotificationMessage;

/**
 * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/12/17 13:42
 * @Describe 通知工具类：统一管理前台服务/电池提醒通知，适配API19-30，Java7兼容，前台服务无铃声，提醒通知用系统默认铃声
 */
public class NotificationManagerUtils {
    // ================================== 静态常量（置顶统一管理，杜绝魔法值）=================================
    public static final String TAG = "NotificationManagerUtils";
    // 通知渠道ID（API26+ 必需，区分通知类型）
    public static final String CHANNEL_ID_FOREGROUND = "cc.winboll.studio.powerbell.channel.foreground";
    public static final String CHANNEL_ID_REMIND = "cc.winboll.studio.powerbell.channel.remind";
    // 通知ID（唯一标识，避免重复）
    public static final int NOTIFY_ID_FOREGROUND_SERVICE = 1001;
    public static final int NOTIFY_ID_REMIND = 1002;
    // 低版本兼容：默认通知图标（API<21 避免显示异常）
    private static final int NOTIFICATION_DEFAULT_ICON = R.drawable.ic_launcher;

    // ================================== 成员变量（私有封装，按依赖优先级排序）=================================
    // 核心上下文（应用级，避免内存泄漏）
    private Context mContext;
    // 系统通知服务（核心依赖）
    private NotificationManager mNotificationManager;
    // 前台服务通知实例（单独持有，便于更新/取消）
    private Notification mForegroundServiceNotify;

    // ================================== 构造方法（初始化核心资源，前置校验）=================================
    public NotificationManagerUtils(Context context) {
        LogUtils.d(TAG, "NotificationManagerUtils init start");
        // 前置校验：Context非空
        if (context == null) {
            LogUtils.e(TAG, "init failed: context is null");
            return;
        }
        // 初始化核心资源
        this.mContext = context.getApplicationContext();
        this.mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        // 初始化通知渠道（API26+ 必需）
        initNotificationChannels();
        LogUtils.d(TAG, "NotificationManagerUtils init success");
    }

    // ================================== 核心初始化方法（通知渠道，API分级适配）=================================
    /**
     * 初始化通知渠道：前台服务渠道（无铃声+无振动）、提醒渠道（系统默认铃声+无振动）
     */
    private void initNotificationChannels() {
        // API<26 无渠道机制，直接返回
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            LogUtils.d(TAG, "initNotificationChannels: API<26, no need channel");
            return;
        }
        // 通知服务为空，避免空指针
        if (mNotificationManager == null) {
            LogUtils.e(TAG, "initNotificationChannels failed: NotificationManager is null");
            return;
        }

        // 1. 前台服务渠道（低优先级，后台保活无打扰）
        NotificationChannel foregroundChannel = new NotificationChannel(
			CHANNEL_ID_FOREGROUND,
			"电池服务保活",
			NotificationManager.IMPORTANCE_LOW
        );
        foregroundChannel.setDescription("电池监测服务后台运行，无声音、无振动");
        foregroundChannel.enableLights(false);
        foregroundChannel.enableVibration(false);
        foregroundChannel.setSound(null, null); // 强制无铃声
        foregroundChannel.setShowBadge(false);
        foregroundChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);

        // 2. 电池提醒渠道（中优先级，系统默认铃声，无振动）
        NotificationChannel remindChannel = new NotificationChannel(
			CHANNEL_ID_REMIND,
			"电池状态提醒",
			NotificationManager.IMPORTANCE_DEFAULT
        );
        remindChannel.setDescription("电池满电/低电量提醒，系统默认铃声，无振动");
        remindChannel.enableLights(true);
        remindChannel.enableVibration(false);
		remindChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), Notification.AUDIO_ATTRIBUTES_DEFAULT);
        remindChannel.setShowBadge(false);
        remindChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);

        // 注册渠道到系统
        mNotificationManager.createNotificationChannel(foregroundChannel);
        mNotificationManager.createNotificationChannel(remindChannel);
        LogUtils.d(TAG, "initNotificationChannels success: foreground+remind channel created");
    }

    // ================================== 对外核心方法（前台服务通知：启动/更新/取消）=================================
    /**
     * 启动前台服务通知（API30适配，无铃声）
     */
    public void startForegroundServiceNotify(Service service, NotificationMessage message) {
        LogUtils.d(TAG, "startForegroundServiceNotify start, notifyId: " + NOTIFY_ID_FOREGROUND_SERVICE);
        // 前置校验：参数非空
        if (service == null || message == null || mNotificationManager == null) {
            LogUtils.e(TAG, "startForegroundServiceNotify failed: param is null");
            return;
        }

        // 构建前台通知
        mForegroundServiceNotify = buildForegroundNotification(message);
        if (mForegroundServiceNotify == null) {
            LogUtils.e(TAG, "startForegroundServiceNotify failed: build notify null");
            return;
        }

        // 启动前台服务（API30无FOREGROUND_SERVICE_TYPE限制，全版本通用）
        try {
            service.startForeground(NOTIFY_ID_FOREGROUND_SERVICE, mForegroundServiceNotify);
            LogUtils.d(TAG, "startForegroundServiceNotify success");
        } catch (Exception e) {
            LogUtils.e(TAG, "startForegroundServiceNotify exception", e);
        }
    }

    /**
     * 更新前台服务通知内容（复用通知ID，保持无铃声）
     */
    public void updateForegroundServiceNotify(NotificationMessage message) {
        LogUtils.d(TAG, "updateForegroundServiceNotify start, notifyId: " + NOTIFY_ID_FOREGROUND_SERVICE);
        if (message == null || mNotificationManager == null) {
            LogUtils.e(TAG, "updateForegroundServiceNotify failed: param is null");
            return;
        }

        mForegroundServiceNotify = buildForegroundNotification(message);
        if (mForegroundServiceNotify == null) {
            LogUtils.e(TAG, "updateForegroundServiceNotify failed: build notify null");
            return;
        }

        try {
            mNotificationManager.notify(NOTIFY_ID_FOREGROUND_SERVICE, mForegroundServiceNotify);
            LogUtils.d(TAG, "updateForegroundServiceNotify success");
        } catch (Exception e) {
            LogUtils.e(TAG, "updateForegroundServiceNotify exception", e);
        }
    }

    /**
     * 取消前台服务通知（Service销毁时调用）
     */
    public void cancelForegroundServiceNotify() {
        LogUtils.d(TAG, "cancelForegroundServiceNotify start, notifyId: " + NOTIFY_ID_FOREGROUND_SERVICE);
        cancelNotification(NOTIFY_ID_FOREGROUND_SERVICE);
        mForegroundServiceNotify = null; // 置空释放
        LogUtils.d(TAG, "cancelForegroundServiceNotify success");
    }

    // ================================== 对外核心方法（电池提醒通知：发送）=================================
    /**
     * 发送电池提醒通知（系统默认铃声，无振动）
     */
    public void showRemindNotification(Context context, NotificationMessage message) {
        LogUtils.d(TAG, "showRemindNotification start, notifyId: " + NOTIFY_ID_REMIND);
        if (context == null || message == null || mNotificationManager == null) {
            LogUtils.e(TAG, "showRemindNotification failed: param is null");
            return;
        }

        Notification remindNotify = buildRemindNotification(context, message);
        if (remindNotify == null) {
            LogUtils.e(TAG, "showRemindNotification failed: build notify null");
            return;
        }

        try {
            mNotificationManager.notify(NOTIFY_ID_REMIND, remindNotify);
            LogUtils.d(TAG, "showRemindNotification success");
        } catch (Exception e) {
            LogUtils.e(TAG, "showRemindNotification exception", e);
        }
    }

    // ================================== 对外工具方法（通知取消：单个/全部）=================================
    /**
     * 取消指定ID的通知
     */
    public void cancelNotification(int notifyId) {
        if (mNotificationManager == null) {
            LogUtils.e(TAG, "cancelNotification failed: NotificationManager is null");
            return;
        }
        try {
            mNotificationManager.cancel(notifyId);
            LogUtils.d(TAG, "cancelNotification success, notifyId: " + notifyId);
        } catch (Exception e) {
            LogUtils.e(TAG, "cancelNotification exception, notifyId: " + notifyId, e);
        }
    }

    /**
     * 取消所有通知（兜底场景使用）
     */
    public void cancelAllNotifications() {
        if (mNotificationManager == null) {
            LogUtils.e(TAG, "cancelAllNotifications failed: NotificationManager is null");
            return;
        }
        try {
            mNotificationManager.cancelAll();
            LogUtils.d(TAG, "cancelAllNotifications success");
        } catch (Exception e) {
            LogUtils.e(TAG, "cancelAllNotifications exception", e);
        }
    }

    // ================================== 内部辅助方法（通知构建：前台服务通知）=================================
    /**
     * 构建前台服务通知（全版本无铃声+无振动）
     */
    private Notification buildForegroundNotification(NotificationMessage message) {
        if (message == null || mContext == null) {
            LogUtils.e(TAG, "buildForegroundNotification failed: param is null");
            return null;
        }

        // 内容兜底
        String title = message.getTitle() != null && !message.getTitle().isEmpty() ? message.getTitle() : "电池服务运行中";
        String content = message.getContent() != null && !message.getContent().isEmpty() ? message.getContent() : "后台监测电池状态";

        Notification.Builder builder;
        // API分级构建
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // API26+：绑定前台渠道（渠道已配置无铃声）
            builder = new Notification.Builder(mContext, CHANNEL_ID_FOREGROUND);
        } else {
            // API<26：直接构建，手动禁用铃声振动
            builder = new Notification.Builder(mContext);
            builder.setSound(null);
            builder.setVibrate(new long[]{0});
            builder.setDefaults(0);
        }

        // 通用配置
        builder.setSmallIcon(NOTIFICATION_DEFAULT_ICON)
			.setContentTitle(title)
			.setContentText(content)
			.setAutoCancel(false)
			.setOngoing(true) // 不可手动关闭
			.setWhen(System.currentTimeMillis())
			.setContentIntent(createJumpPendingIntent(mContext, 0));

        // API21+ 新增大图标+主题色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            builder.setLargeIcon(getAppIcon(mContext))
				.setColor(mContext.getResources().getColor(R.color.colorPrimary))
				.setPriority(Notification.PRIORITY_LOW);
        }

        return builder.build();
    }

    // ================================== 内部辅助方法（通知构建：电池提醒通知）=================================
    /**
     * 构建电池提醒通知（全版本系统默认铃声+无振动）
     */
    private Notification buildRemindNotification(Context context, NotificationMessage message) {
        if (context == null || message == null) {
            LogUtils.e(TAG, "buildRemindNotification failed: param is null");
            return null;
        }

        // 内容兜底
        String title = message.getTitle() != null && !message.getTitle().isEmpty() ? message.getTitle() : "电池状态提醒";
        String content = message.getContent() != null && !message.getContent().isEmpty() ? message.getContent() : "电池状态异常，请及时处理";

        Notification.Builder builder;
        // API分级构建
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // API26+：绑定提醒渠道（渠道已配置默认铃声）
            builder = new Notification.Builder(context, CHANNEL_ID_REMIND);
        } else {
            // API<26：手动配置默认铃声，关闭振动
            builder = new Notification.Builder(context);
            builder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI) // 显式默认铃声
				.setVibrate(new long[]{0})
				.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND);
        }

        // 通用配置
        builder.setSmallIcon(NOTIFICATION_DEFAULT_ICON)
			.setContentTitle(title)
			.setContentText(content)
			.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), Notification.AUDIO_ATTRIBUTES_DEFAULT)
			.setAutoCancel(true) // 点击关闭
			.setOngoing(false)
			.setWhen(System.currentTimeMillis())
			.setContentIntent(createJumpPendingIntent(context, 1));

        // API21+ 新增大图标+主题色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            builder.setLargeIcon(getAppIcon(context))
				.setColor(context.getResources().getColor(R.color.colorPrimary))
				.setPriority(Notification.PRIORITY_DEFAULT);
        }

        return builder.build();
    }

    // ================================== 内部辅助方法（创建跳转PendingIntent，API30安全适配）=================================
    /**
     * 创建跳转MainActivity的PendingIntent，API23+ 添加IMMUTABLE标记（避免安全异常）
     */
    private PendingIntent createJumpPendingIntent(Context context, int requestCode) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

        // API23+ 必需添加IMMUTABLE，适配API30安全规范
        int flags = PendingIntent.FLAG_UPDATE_CURRENT;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            flags |= PendingIntent.FLAG_IMMUTABLE;
        }

        return PendingIntent.getActivity(context, requestCode, intent, flags);
    }

    // ================================== 内部辅助方法（获取APP图标，异常兜底）=================================
    /**
     * 获取APP图标，失败返回默认图标
     */
    private Bitmap getAppIcon(Context context) {
        try {
            PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return BitmapFactory.decodeResource(context.getResources(), pkgInfo.applicationInfo.icon);
        } catch (PackageManager.NameNotFoundException e) {
            LogUtils.e(TAG, "getAppIcon exception", e);
            return BitmapFactory.decodeResource(context.getResources(), NOTIFICATION_DEFAULT_ICON);
        }
    }

    // ================================== 对外 getter 方法（仅前台通知实例，只读）=================================
    public Notification getForegroundServiceNotify() {
        return mForegroundServiceNotify;
    }

    // ================================== 资源释放方法（避免内存泄漏）=================================
    /**
     * 释放资源，销毁时调用
     */
    public void release() {
        LogUtils.d(TAG, "release start");
        cancelForegroundServiceNotify();
        mNotificationManager = null;
        mContext = null;
        LogUtils.d(TAG, "release success");
    }
}

