package cc.winboll.studio.powerbell.threads;

import android.content.Context;
import android.os.Message;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.powerbell.handlers.ControlCenterServiceHandler;
import cc.winboll.studio.powerbell.models.AppConfigBean;
import java.lang.ref.WeakReference;

/**
 * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/12/17 13:38
 * @Describe 提醒线程（单例模式）：统一管理充电/耗电提醒逻辑，适配Java7+API30+，发送提醒时同步携带当前电量+充电状态
 */
public class RemindThread extends Thread {
    // ================================== 静态常量（置顶，统一管理魔法值）=================================
    public static final String TAG = "RemindThread";
    private static final long INIT_DELAY_TIME = 500L;       // 初始化延迟（ms，等待服务就绪）
    private static final int MIN_SLEEP_TIME = 500;          // 最小检测间隔（ms，防高频轮询）
    private static final int DEFAULT_SLEEP_TIME = 1000;     // 默认检测间隔（ms）
    private static final long REMIND_INTERVAL = 3000L;      // 重复提醒间隔（ms，防骚扰）
    private static final int CONFIG_RETRY_MAX = 3;          // 配置同步重试次数（兜底）
    private static final int INVALID_BATTERY_VALUE = -1;    // 无效电量标记
    private static final long BACKGROUND_SLEEP_TIME = 5000L;// 后台休眠间隔（ms，减少资源占用）

    // ================================== 单例核心（线程安全，避免复用旧实例）=================================
    private static volatile RemindThread sInstance;

    // ================================== 成员变量（按功能分类，volatile+锁保护）=================================
    // 依赖资源（防内存泄漏）
    private Context mContext;
    private WeakReference<ControlCenterServiceHandler> mwrControlCenterServiceHandler;

    // 线程状态（核心标记，多线程可见）
    private volatile boolean isExist;                     // 退出标记（true=退出）
    private volatile boolean isThreadStarted;             // 启动标记（区分isAlive()）
    private volatile boolean isReminding;                 // 全局提醒开关
    private volatile boolean isRemindTimerRunning;        // 提醒恢复计时器状态

    // 业务配置（实时同步，范围校验）
    private volatile boolean isEnableChargeReminder;      // 充电提醒开关
    private volatile boolean isEnableUsageReminder;       // 耗电提醒开关
    private volatile long sleepTime;                      // 检测间隔（ms，改为long适配大间隔）
    private volatile int chargeReminderValue;             // 充电提醒阈值（0-100）
    private volatile int usageReminderValue;              // 耗电提醒阈值（0-100）
    private volatile int quantityOfElectricity;           // 当前电量（0-100，无效为-1）
    private volatile boolean isCharging;                  // 充电状态标记

    // 辅助变量（并发安全+防重复提醒）
    private volatile long lastRemindTime;                 // 上次提醒时间戳（ms）
    private final Object mLock = new Object();            // 全局锁（保护所有状态变量）

    // ================================== 私有构造器（单例专用，初始化状态+防护泄漏）=================================
    private RemindThread(Context context, ControlCenterServiceHandler handler) {
        LogUtils.d(TAG, "构造线程实例，线程名称：" + getName());
        this.mContext = context.getApplicationContext();
        this.mwrControlCenterServiceHandler = new WeakReference<>(handler);
        resetThreadStateInternal(); // 初始化所有状态，避免脏数据
    }

    // ================================== 单例管理（获取+销毁，彻底释放资源）=================================
    /**
     * 获取单例实例（旧线程停止自动销毁，强制入参校验）
     */
    public static RemindThread getInstance(Context context, ControlCenterServiceHandler handler) {
        LogUtils.d(TAG, "获取单例，当前实例是否存在：" + (sInstance != null));
        if (context == null || handler == null) {
            LogUtils.e(TAG, "致命错误：Context/ControlCenterServiceHandler不能为空");
            throw new IllegalArgumentException("Context and ControlCenterServiceHandler cannot be null");
        }

        // 旧线程停止则销毁，确保新实例有效
        if (sInstance != null && !sInstance.isRunning()) {
            destroyInstance();
            LogUtils.d(TAG, "旧线程已停止，销毁单例准备创建新实例");
        }

        // 双重校验锁创建单例
        if (sInstance == null) {
            synchronized (RemindThread.class) {
                if (sInstance == null) {
                    sInstance = new RemindThread(context, handler);
                    LogUtils.d(TAG, "新线程实例创建成功，线程ID：" + sInstance.getId());
                }
            }
        }
        return sInstance;
    }

    /**
     * 销毁单例（安全停止线程+释放资源，避免内存泄漏）
     */
    public static void destroyInstance() {
        LogUtils.d(TAG, "开始销毁线程单例");
        synchronized (RemindThread.class) {
            if (sInstance != null) {
                sInstance.stopThread();
                sInstance.releaseResources();
                sInstance = null;
                LogUtils.d(TAG, "线程单例销毁完成");
            } else {
                LogUtils.w(TAG, "单例已为空，跳过销毁");
            }
        }
    }

    // ================================== 线程核心逻辑（run方法，高效退出+异常容错）=================================
    @Override
    public void run() {
        LogUtils.d(TAG, "线程启动，ID：" + Thread.currentThread().getId() + "，状态：" + getState());
        // 防止run方法重复执行
        synchronized (mLock) {
            if (isThreadStarted || isExist) {
                LogUtils.e(TAG, "线程已启动/待退出，禁止重复执行run");
                return;
            }
            isThreadStarted = true;
            lastRemindTime = 0;
        }

        // 配置同步重试（失败则兜底默认值）
        boolean configValid = syncConfigRetry();
        if (!configValid) {
            LogUtils.e(TAG, "配置同步失败，使用默认阈值兜底启动");
        }

        // 初始化延迟（等待服务就绪）
        try {
            LogUtils.d(TAG, "初始化延迟" + INIT_DELAY_TIME + "ms");
            Thread.sleep(INIT_DELAY_TIME);
            if (isExist) {
                LogUtils.d(TAG, "延迟期间收到退出指令，线程终止");
                cleanThreadState();
                return;
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            LogUtils.e(TAG, "初始化延迟被中断，线程终止", e);
            cleanThreadState();
            return;
        }

        // 核心检测循环（快速退出+并发安全）
        LogUtils.d(TAG, "进入电量检测循环，间隔：" + sleepTime + "ms");
        while (!isExist) {
            try {
                if (isExist) break;

                // 核心防护：提醒关闭/电量无效，直接休眠（跳过提醒检测）
                synchronized (mLock) {
                    // 提醒关闭/电量无效：正常休眠，不检测
                    if (!isReminding || quantityOfElectricity == INVALID_BATTERY_VALUE) {
                        safeSleep(sleepTime);
                        continue;
                    }
                    // 电量超出范围：修正为无效，休眠重试
                    if (quantityOfElectricity < 0 || quantityOfElectricity > 100) {
                        LogUtils.w(TAG, "电量无效（" + quantityOfElectricity + "），标记为无效值");
                        quantityOfElectricity = INVALID_BATTERY_VALUE;
                        safeSleep(sleepTime);
                        continue;
                    }
                }

                // 锁保护核心提醒逻辑（仅提醒开启+电量有效时执行）
                synchronized (mLock) {
                    if (isExist || !isReminding || quantityOfElectricity == INVALID_BATTERY_VALUE) {
                        safeSleep(sleepTime);
                        continue;
                    }

                    // 防重复提醒（间隔未到/计时器运行中）
                    long currentTime = System.currentTimeMillis();
                    if ((currentTime - lastRemindTime < REMIND_INTERVAL) || isRemindTimerRunning) {
                        safeSleep(sleepTime);
                        continue;
                    }

                    // 充电提醒触发（携带当前电量+充电状态发送）
                    if (isCharging && isEnableChargeReminder && quantityOfElectricity >= chargeReminderValue) {
                        LogUtils.d(TAG, "触发充电提醒：充电中，电量" + quantityOfElectricity + "≥阈值" + chargeReminderValue);
                        sendNotificationMessage("+", quantityOfElectricity, isCharging);
                        lastRemindTime = currentTime;
                        startRemindRecoveryTimer();
                    }
                    // 耗电提醒触发（携带当前电量+充电状态发送）
                    else if (!isCharging && isEnableUsageReminder && quantityOfElectricity <= usageReminderValue) {
                        LogUtils.d(TAG, "触发耗电提醒：未充电，电量" + quantityOfElectricity + "≤阈值" + usageReminderValue);
                        sendNotificationMessage("-", quantityOfElectricity, isCharging);
                        lastRemindTime = currentTime;
                        startRemindRecoveryTimer();
                    }
                }

                safeSleep(sleepTime);
            } catch (Exception e) {
                LogUtils.e(TAG, "线程运行异常，休眠重试", e);
                safeSleep(sleepTime);
            }
        }

        // 退出清理
        cleanThreadState();
        LogUtils.d(TAG, "线程循环退出，ID：" + Thread.currentThread().getId());
    }

    // ================================== 核心业务辅助方法（配置同步+消息发送+计时器）=================================
    /**
     * 配置同步重试（确保阈值有效，失败兜底）
     */
    private boolean syncConfigRetry() {
        int retryCount = 0;
        while (retryCount < CONFIG_RETRY_MAX) {
            synchronized (mLock) {
                if ((chargeReminderValue >= 0 && chargeReminderValue <= 100)
					&& (usageReminderValue >= 0 && usageReminderValue <= 100)) {
                    LogUtils.d(TAG, "配置同步成功，重试次数：" + retryCount);
                    return true;
                }
            }
            LogUtils.w(TAG, "配置未同步，重试次数：" + (retryCount + 1));
            try {
                Thread.sleep(1000);
                retryCount++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                LogUtils.e(TAG, "配置重试被中断", e);
                return false;
            }
        }
        // 兜底默认阈值（避免无效值触发提醒）
        synchronized (mLock) {
            chargeReminderValue = (chargeReminderValue < 0 || chargeReminderValue > 100) ? 80 : chargeReminderValue;
            usageReminderValue = (usageReminderValue < 0 || usageReminderValue > 100) ? 20 : usageReminderValue;
            quantityOfElectricity = INVALID_BATTERY_VALUE; // 兜底电量设为无效，防止误触发
            LogUtils.e(TAG, "配置重试失败，兜底阈值：充电" + chargeReminderValue + "，耗电" + usageReminderValue + "RuntimeException : Config sync failed.");
        }
        return false;
    }

    /**
     * 发送提醒消息（携带当前电量+充电状态，弱引用Handler+Message复用，防泄漏）
     * @param type 提醒类型（+：充电提醒，-：耗电提醒）
     * @param battery 当前电量（0-100）
     * @param isCharging 当前充电状态（true=充电中）
     */
    private void sendNotificationMessage(String type, int battery, boolean isCharging) {
        LogUtils.d(TAG, "准备发送提醒消息：类型=" + type + "，电量=" + battery + "，充电状态=" + isCharging);
        // 双重防护：线程退出/提醒关闭，跳过发送
        if (isExist || !isReminding) {
            LogUtils.d(TAG, "线程退出/提醒关闭，跳过发送");
            return;
        }

        ControlCenterServiceHandler handler = mwrControlCenterServiceHandler != null ? mwrControlCenterServiceHandler.get() : null;
        if (handler == null) {
            LogUtils.w(TAG, "Handler已回收，发送失败");
            return;
        }

        // 构建消息：what=提醒标识，obj=类型，arg1=当前电量，arg2=充电状态（0=未充电，1=充电中）
        Message message = Message.obtain(handler, ControlCenterServiceHandler.MSG_REMIND_TEXT);
        message.obj = type;
        message.arg1 = battery;
        message.arg2 = isCharging ? 1 : 0; // boolean转int（兼容Java7）
        try {
            handler.sendMessage(message);
            LogUtils.d(TAG, "提醒消息发送成功：类型=" + type + "，电量=" + battery + "，充电状态=" + isCharging);
        } catch (Exception e) {
            LogUtils.e(TAG, "消息发送异常", e);
            if (message != null) message.recycle();
        }
    }

    /**
     * 启动提醒恢复计时器（防重复提醒，弱引用线程+锁保护）
     */
    private void startRemindRecoveryTimer() {
        LogUtils.d(TAG, "启动提醒恢复计时器，间隔：" + REMIND_INTERVAL + "ms");
        synchronized (mLock) {
            if (isExist || isRemindTimerRunning || sInstance != this) {
                LogUtils.w(TAG, "计时器启动条件不满足，跳过");
                return;
            }
            isReminding = false;
            isRemindTimerRunning = true;
        }

        final WeakReference<RemindThread> threadRef = new WeakReference<>(this);
        new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						Thread.sleep(REMIND_INTERVAL);
						RemindThread thread = threadRef.get();
						if (thread == null || thread.isExist || sInstance != thread) {
							LogUtils.d(TAG, "线程已销毁，不恢复提醒");
							return;
						}

						synchronized (thread.mLock) {
							// 仅线程存活+有启用提醒时，才恢复提醒
							if (!thread.isExist && sInstance == thread
                                && (thread.isEnableChargeReminder || thread.isEnableUsageReminder)) {
								thread.isReminding = true;
								LogUtils.d(TAG, "提醒功能恢复开启");
							}
						}
					} catch (InterruptedException e) {
						Thread.currentThread().interrupt();
						LogUtils.e(TAG, "计时器被中断", e);
					} finally {
						RemindThread thread = threadRef.get();
						if (thread != null) {
							synchronized (thread.mLock) {
								if (sInstance == thread) thread.isRemindTimerRunning = false;
							}
						}
						LogUtils.d(TAG, "提醒恢复计时器执行完成");
					}
				}
			}, "RemindRecoveryTimer").start();
    }

    // ================================== 线程控制方法（停止+休眠+状态清理）=================================
    /**
     * 安全停止线程（快速退出+中断休眠）
     */
    public void stopThread() {
        LogUtils.d(TAG, "开始停止线程，当前状态：" + getState());
        synchronized (mLock) {
            isExist = true;
            isReminding = false;
            isRemindTimerRunning = false;
        }
        if (isAlive()) {
            interrupt();
            LogUtils.d(TAG, "线程已中断，加速退出");
        }
        if (sInstance == this) sInstance = null;
    }

    /**
     * 废弃方法（统一用stopThread）
     */
    @Deprecated
    public void forceStopThread() {
        LogUtils.w(TAG, "forceStopThread已废弃，请调用stopThread");
        stopThread();
    }

    /**
     * 安全休眠（保留中断标记，确保退出逻辑生效）
     */
    private void safeSleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            LogUtils.w(TAG, "休眠被中断，线程准备退出");
        }
    }

    /**
     * 清理线程运行状态（退出后重置所有标记）
     */
    private void cleanThreadState() {
        LogUtils.d(TAG, "清理线程运行状态");
        synchronized (mLock) {
            isReminding = false;
            isExist = true;
            isThreadStarted = false;
            isRemindTimerRunning = false;
            lastRemindTime = 0;
            quantityOfElectricity = INVALID_BATTERY_VALUE; // 重置为无效电量，防残留
        }
        if (isAlive()) interrupt();
        if (sInstance == this) sInstance = null;
    }

    // ================================== 状态重置方法（初始化+运行时重置）=================================
    /**
     * 初始状态重置（构造器专用）
     */
    private void resetThreadStateInternal() {
        LogUtils.d(TAG, "重置线程初始状态");
        synchronized (mLock) {
            // 线程状态
            isExist = false;
            isReminding = false;
            isThreadStarted = false;
            isRemindTimerRunning = false;
            lastRemindTime = 0;
            // 业务配置
            isEnableChargeReminder = false;
            isEnableUsageReminder = false;
            sleepTime = DEFAULT_SLEEP_TIME;
            chargeReminderValue = -1;
            usageReminderValue = -1;
            quantityOfElectricity = INVALID_BATTERY_VALUE; // 初始设为无效
            isCharging = false;
        }
    }

    /**
     * 运行时状态重置（外部调用，不重置配置）
     */
    public void resetThreadState() {
        LogUtils.d(TAG, "重置线程运行状态");
        synchronized (mLock) {
            isExist = false;
            isRemindTimerRunning = false;
            lastRemindTime = 0;
            isReminding = (isEnableChargeReminder || isEnableUsageReminder); // 根据开关自动开启提醒
        }
        LogUtils.d(TAG, "运行状态重置完成，全局提醒：" + isReminding);
    }

    // ================================== 配置同步方法（完整同步配置，原子操作+无效电量防护）=================================
    /**
     * 同步应用配置（参数校验+范围限制，立即生效）
     */
    public void setAppConfigBean(AppConfigBean config) {
        if (config == null) {
            LogUtils.e(TAG, "配置Bean为空，同步失败");
            synchronized (mLock) {
                quantityOfElectricity = INVALID_BATTERY_VALUE; // 配置为空，标记电量无效
            }
            return;
        }
        LogUtils.d(TAG, "开始同步配置：充电阈值" + config.getChargeReminderValue() + "，耗电阈值" + config.getUsageReminderValue() + "，当前电量" + config.getCurrentBatteryValue());
        synchronized (mLock) {
            // 同步开关
            isEnableChargeReminder = config.isEnableChargeReminder();
            isEnableUsageReminder = config.isEnableUsageReminder();
            // 同步阈值（0-100限制）
            chargeReminderValue = Math.min(Math.max(config.getChargeReminderValue(), 0), 100);
            usageReminderValue = Math.min(Math.max(config.getUsageReminderValue(), 0), 100);
            // 同步检测间隔（≥最小间隔）
            sleepTime = Math.max(config.getBatteryDetectInterval(), MIN_SLEEP_TIME);
            // 同步电池状态（校验有效，无效则标记为-1）
            int currentBattery = config.getCurrentBatteryValue();
            quantityOfElectricity = (currentBattery >= 0 && currentBattery <= 100) ? currentBattery : INVALID_BATTERY_VALUE;
            isCharging = config.isCharging();
            // 提醒开关：根据配置自动开启
            isReminding = (isEnableChargeReminder || isEnableUsageReminder);
        }
        LogUtils.d(TAG, "配置同步完成：检测间隔" + sleepTime + "ms，全局提醒" + isReminding + "，当前电量" + quantityOfElectricity);
    }

    // ================================== Setter/Getter（锁保护，线程安全+精准日志）=================================
    public boolean isExist() {
        synchronized (mLock) {
            return isExist;
        }
    }

    public void setIsExist(boolean isExist) {
        synchronized (mLock) {
            this.isExist = isExist;
            LogUtils.d(TAG, "设置线程退出标记：" + isExist);
        }
    }

    public boolean isReminding() {
        synchronized (mLock) {
            return isReminding;
        }
    }

    public void setIsReminding(boolean isReminding) {
        synchronized (mLock) {
            this.isReminding = isReminding;
            LogUtils.d(TAG, "设置全局提醒开关：" + this.isReminding);
        }
    }

    public boolean isThreadStarted() {
        synchronized (mLock) {
            return isThreadStarted;
        }
    }

    public boolean isEnableUsageReminder() {
        synchronized (mLock) {
            return isEnableUsageReminder;
        }
    }

    public void setIsEnableUsageReminder(boolean isEnableUsageReminder) {
        synchronized (mLock) {
            this.isEnableUsageReminder = isEnableUsageReminder;
            isReminding = (isEnableChargeReminder || isEnableUsageReminder);
            LogUtils.d(TAG, "设置耗电提醒开关：" + isEnableUsageReminder + "，全局提醒：" + isReminding);
        }
    }

    public boolean isEnableChargeReminder() {
        synchronized (mLock) {
            return isEnableChargeReminder;
        }
    }

    public void setIsEnableChargeReminder(boolean isEnableChargeReminder) {
        synchronized (mLock) {
            this.isEnableChargeReminder = isEnableChargeReminder;
            isReminding = (isEnableChargeReminder || isEnableUsageReminder);
            LogUtils.d(TAG, "设置充电提醒开关：" + isEnableChargeReminder + "，全局提醒：" + isReminding);
        }
    }

    public long getSleepTime() {
        synchronized (mLock) {
            return sleepTime;
        }
    }

    public void setSleepTime(long sleepTime) {
        synchronized (mLock) {
            this.sleepTime = Math.max(sleepTime, MIN_SLEEP_TIME);
            LogUtils.d(TAG, "设置检测间隔：" + this.sleepTime + "ms");
        }
    }

    public int getChargeReminderValue() {
        synchronized (mLock) {
            return chargeReminderValue;
        }
    }

    public void setChargeReminderValue(int chargeReminderValue) {
        synchronized (mLock) {
            this.chargeReminderValue = Math.min(Math.max(chargeReminderValue, 0), 100);
            LogUtils.d(TAG, "设置充电提醒阈值：" + this.chargeReminderValue);
        }
    }

    public int getUsageReminderValue() {
        synchronized (mLock) {
            return usageReminderValue;
        }
    }

    public void setUsageReminderValue(int usageReminderValue) {
        synchronized (mLock) {
            this.usageReminderValue = Math.min(Math.max(usageReminderValue, 0), 100);
            LogUtils.d(TAG, "设置耗电提醒阈值：" + this.usageReminderValue);
        }
    }

    public int getQuantityOfElectricity() {
        synchronized (mLock) {
            return quantityOfElectricity;
        }
    }

    public void setQuantityOfElectricity(int quantityOfElectricity) {
        synchronized (mLock) {
            this.quantityOfElectricity = Math.min(Math.max(quantityOfElectricity, 0), 100);
            LogUtils.d(TAG, "更新当前电量：" + this.quantityOfElectricity);
        }
    }

    public boolean isCharging() {
        synchronized (mLock) {
            return isCharging;
        }
    }

    public void setIsCharging(boolean isCharging) {
        synchronized (mLock) {
            this.isCharging = isCharging;
            LogUtils.d(TAG, "更新充电状态：" + isCharging);
        }
    }

    // ================================== 核心状态判断（Service依赖，精准校验）=================================
    public boolean isRunning() {
        synchronized (mLock) {
            boolean running = !isExist && isThreadStarted && isAlive();
            LogUtils.d(TAG, "线程运行状态：" + running + "（退出：" + isExist + "，已启动：" + isThreadStarted + "，存活：" + isAlive() + "）");
            return running;
        }
    }

    // ================================== 资源释放（彻底断开引用，防内存泄漏）=================================
    public void releaseResources() {
        LogUtils.d(TAG, "开始释放线程资源");
        synchronized (mLock) {
            mContext = null;
            if (mwrControlCenterServiceHandler != null) {
                mwrControlCenterServiceHandler.clear();
                mwrControlCenterServiceHandler = null;
            }
            cleanThreadState();
        }
        LogUtils.d(TAG, "线程资源释放完成");
    }

    // ================================== 调试辅助（toString，打印核心状态）=================================
    @Override
    public String toString() {
        return "RemindThread{" +
			"threadId=" + getId() +
			", threadName='" + getName() + '\'' +
			", isRunning=" + isRunning() +
			", isReminding=" + isReminding() +
			", chargeThreshold=" + getChargeReminderValue() +
			", usageThreshold=" + getUsageReminderValue() +
			", currentBattery=" + getQuantityOfElectricity() +
			", isCharging=" + isCharging() +
			", sleepTime=" + getSleepTime() + "ms" +
			'}';
    }
}

