package cc.winboll.studio.powerbell.receivers;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.powerbell.models.AppConfigBean;
import cc.winboll.studio.powerbell.models.NotificationMessage;
import cc.winboll.studio.powerbell.services.ControlCenterService;
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
import cc.winboll.studio.powerbell.utils.BatteryUtils;
import cc.winboll.studio.powerbell.utils.NotificationManagerUtils;
import java.lang.ref.WeakReference;

/**
 * 控制中心广播接收器
 * 功能：监听电池状态变化、前台通知更新、配置变更指令
 * 适配：Java7 | API30 | 内存泄漏防护 | 多线程状态同步
 * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/12/19 20:23
 */
public class ControlCenterServiceReceiver extends BroadcastReceiver {
    // ================================== 静态常量区（置顶归类，消除魔法值）=================================
    public static final String TAG = "ControlCenterServiceReceiver";

    // 广播Action常量（带包名前缀防冲突）
    public static final String ACTION_UPDATE_FOREGROUND_NOTIFICATION = "cc.winboll.studio.powerbell.action.ACTION_UPDATE_FOREGROUND_NOTIFICATION";
    public static final String ACTION_APPCONFIG_CHANGED = "cc.winboll.studio.powerbell.action.ACTION_APPCONFIG_CHANGED";
    public static final String EXTRA_APP_CONFIG_BEAN = "extra_app_config_bean";

    // 广播优先级与电量范围常量
    private static final int BROADCAST_PRIORITY = IntentFilter.SYSTEM_HIGH_PRIORITY - 10;
    private static final int BATTERY_LEVEL_MIN = 0;
    private static final int BATTERY_LEVEL_MAX = 100;

    // ================================== 静态状态标记（volatile保证多线程可见性）=================================
    private static volatile int sLastBatteryLevel = -1;  // 上次电量（多线程可见）
    private static volatile boolean sIsCharging = false; // 上次充电状态（多线程可见）

    // ================================== 成员变量区（弱引用防泄漏，按功能分层）=================================
    private WeakReference<ControlCenterService> mwrControlCenterService;
    private boolean isRegistered = false; // 新增：标记广播注册状态，避免冗余操作

    // ================================== 构造方法（初始化弱引用，避免服务强引用泄漏）=================================
    public ControlCenterServiceReceiver(ControlCenterService service) {
        LogUtils.d(TAG, "构造接收器 | service=" + (service != null ? service.getClass().getSimpleName() : "null"));
        this.mwrControlCenterService = new WeakReference<>(service);
    }

    // ================================== 广播核心接收逻辑（入口方法，分Action分发处理）=================================
    @Override
    public void onReceive(Context context, Intent intent) {
        LogUtils.d(TAG, "onReceive: 接收广播 | action=" + (intent != null ? intent.getAction() : "null"));

        // 基础参数校验
        if (context == null || intent == null || intent.getAction() == null) {
            LogUtils.e(TAG, "onReceive: 参数无效（context=" + context + " | intent=" + intent + "），终止处理");
            return;
        }

        // 弱引用获取服务，双重校验服务有效性
        ControlCenterService service = mwrControlCenterService != null ? mwrControlCenterService.get() : null;
        if (service == null || service.isDestroyed()) {
            LogUtils.e(TAG, "onReceive: 服务已销毁或为空（service=" + service + "），注销广播");
            unregisterAction(context);
            return;
        }

        // 分Action处理业务逻辑
        String action = intent.getAction();
        switch (action) {
            case Intent.ACTION_BATTERY_CHANGED:
                handleBatteryStateChanged(service, intent);
                break;
            case ACTION_UPDATE_FOREGROUND_NOTIFICATION:
                handleUpdateForegroundNotification(service);
                break;
            case ACTION_APPCONFIG_CHANGED:
                LogUtils.d(TAG, "onReceive: 开始处理配置更新广播"); // 新增：标记配置广播处理起点
                handleNotifyAppConfigUpdate(service);
                break;
            default:
                LogUtils.w(TAG, "onReceive: 未知Action=" + action);
        }

        LogUtils.d(TAG, "onReceive: 广播处理完成");
    }

    // ================================== 业务处理方法（按功能拆分，强化容错与日志）=================================
    /**
     * 处理电池状态变化广播
     * @param service 控制中心服务实例
     * @param intent  电池状态广播意图
     */
    private void handleBatteryStateChanged(ControlCenterService service, Intent intent) {
        LogUtils.d(TAG, "handleBatteryStateChanged: 解析电池状态 | service=" + service + " | intent=" + intent);
        try {
            // 1. 解析并校验当前电池状态
            boolean currentCharging = BatteryUtils.isCharging(intent);
            int currentBatteryLevel = BatteryUtils.getCurrentBatteryLevel(intent);
            currentBatteryLevel = Math.min(Math.max(currentBatteryLevel, BATTERY_LEVEL_MIN), BATTERY_LEVEL_MAX);
            LogUtils.d(TAG, "handleBatteryStateChanged: 当前状态 | 充电=" + currentCharging + " | 电量=" + currentBatteryLevel + "%");

            // 2. 状态无变化则跳过，减少无效运算
            if (currentCharging == sIsCharging && currentBatteryLevel == sLastBatteryLevel) {
                LogUtils.d(TAG, "handleBatteryStateChanged: 电池状态无变化，跳过处理");
                return;
            }

            // 4. 更新静态缓存状态，保证多线程可见
            sIsCharging = currentCharging;
            sLastBatteryLevel = currentBatteryLevel;
			
			handleNotifyAppConfigUpdate(service);

            LogUtils.d(TAG, "handleBatteryStateChanged: 电池状态处理成功 | 缓存电量=" + sLastBatteryLevel + "% | 缓存充电状态=" + sIsCharging);
        } catch (Exception e) {
            LogUtils.e(TAG, "handleBatteryStateChanged: 处理失败", e);
        }
    }

    /**
     * 处理配置变更通知，同步缓存状态到配置
     * @param service 控制中心服务实例
     */
    private void handleNotifyAppConfigUpdate(ControlCenterService service) {
        LogUtils.d(TAG, "handleNotifyAppConfigUpdate: 同步缓存状态到配置 | service=" + service);
        try {
            // 加载最新配置
            AppConfigBean latestConfig = AppConfigUtils.getInstance(service).loadAppConfig();
            if (latestConfig == null) { // 新增：配置空指针防护
                LogUtils.e(TAG, "handleNotifyAppConfigUpdate: 最新配置为空，终止处理");
                return;
            }
            LogUtils.d(TAG, "handleNotifyAppConfigUpdate: 加载最新配置 | 充电阈值=" + latestConfig.getChargeReminderValue() + " | 耗电阈值=" + latestConfig.getUsageReminderValue());

            // 同步缓存的电池状态到配置
            latestConfig.setCurrentBatteryValue(sLastBatteryLevel);
            latestConfig.setIsCharging(sIsCharging);
            service.notifyAppConfigUpdate(latestConfig);

            LogUtils.d(TAG, "handleNotifyAppConfigUpdate: 配置同步成功 | 缓存电量=" + sLastBatteryLevel + "% | 充电状态=" + sIsCharging);
            LogUtils.d(TAG, "handleNotifyAppConfigUpdate: 配置更新广播处理完成"); // 新增：标记配置广播处理终点
        } catch (Exception e) {
            LogUtils.e(TAG, "handleNotifyAppConfigUpdate: 处理失败", e);
        }
    }

    /**
     * 处理前台服务通知更新
     * @param service 控制中心服务实例
     */
    private void handleUpdateForegroundNotification(ControlCenterService service) {
        LogUtils.d(TAG, "handleUpdateForegroundNotification: 更新前台通知 | service=" + service);
        try {
            NotificationManagerUtils notifyUtils = service.getNotificationManager();
            NotificationMessage notifyMsg = service.getForegroundNotifyMsg();

            // 非空校验，避免空指针
            if (notifyUtils == null || notifyMsg == null) {
                LogUtils.e(TAG, "handleUpdateForegroundNotification: 通知工具类或消息为空（notifyUtils=" + notifyUtils + " | notifyMsg=" + notifyMsg + "）");
                return;
            }

            notifyUtils.updateForegroundServiceNotify(notifyMsg);
            LogUtils.d(TAG, "handleUpdateForegroundNotification: 前台通知更新成功 | 通知标题=" + notifyMsg.getTitle());
        } catch (Exception e) {
            LogUtils.e(TAG, "handleUpdateForegroundNotification: 处理失败", e);
        }
    }

    // ================================== 广播注册/注销（强化容错，避免重复操作）=================================
    /**
     * 注册广播接收器
     * @param context 上下文
     */
    public void registerAction(Context context) {
        LogUtils.d(TAG, "registerAction: 注册广播接收器 | context=" + context);
        if (context == null || isRegistered) { // 新增：已注册则跳过
            LogUtils.e(TAG, "registerAction: 上下文为空或已注册，注册失败");
            return;
        }

        try {
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
            filter.addAction(ACTION_UPDATE_FOREGROUND_NOTIFICATION);
            filter.addAction(ACTION_APPCONFIG_CHANGED);
            filter.setPriority(BROADCAST_PRIORITY);

            context.registerReceiver(this, filter);
            isRegistered = true; // 标记为已注册
            LogUtils.d(TAG, "registerAction: 广播注册成功 | 优先级=" + BROADCAST_PRIORITY);
        } catch (Exception e) {
            LogUtils.e(TAG, "registerAction: 注册失败", e);
        }
    }

    /**
     * 注销广播接收器
     * @param context 上下文
     */
    public void unregisterAction(Context context) {
        LogUtils.d(TAG, "unregisterAction: 注销广播接收器 | context=" + context);
        if (context == null || !isRegistered) { // 新增：未注册则跳过
            LogUtils.e(TAG, "unregisterAction: 上下文为空或未注册，注销失败");
            return;
        }

        try {
            context.unregisterReceiver(this);
            isRegistered = false; // 标记为未注册
            LogUtils.d(TAG, "unregisterAction: 广播注销成功");
        } catch (IllegalArgumentException e) {
            LogUtils.w(TAG, "unregisterAction: 广播未注册，跳过注销");
        } catch (Exception e) {
            LogUtils.e(TAG, "unregisterAction: 注销失败", e);
        }
    }

    // ================================== 资源释放与Getter方法（按需开放，防泄漏）=================================
    /**
     * 主动释放资源，避免内存泄漏
     */
    public void release() {
        LogUtils.d(TAG, "release: 释放广播接收器资源");
        // 清空弱引用，帮助GC回收
        if (mwrControlCenterService != null) {
            mwrControlCenterService.clear();
            mwrControlCenterService = null;
            LogUtils.d(TAG, "release: 弱引用已清空");
        }
        // 重置静态状态缓存
        sLastBatteryLevel = -1;
        sIsCharging = false;
        LogUtils.d(TAG, "release: 静态状态缓存已重置");
    }

    /**
     * 获取上次记录的电池电量
     * @return 电量值（0-100），未初始化返回-1
     */
    public static int getLastBatteryLevel() {
        return sLastBatteryLevel;
    }

    /**
     * 获取上次记录的充电状态
     * @return true=充电中，false=未充电
     */
    public static boolean isLastCharging() {
        return sIsCharging;
    }
}
