package cc.winboll.studio.powerbell.activities;

/**
 * @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/10/22 13:21
 * @Describe BatteryReportActivity
 */
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import cc.winboll.studio.powerbell.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cc.winboll.studio.libappbase.LogUtils;

public class BatteryReportActivity extends Activity {
    public static final String TAG = "BatteryReportActivity";

    private RecyclerView rvBatteryReport;
    private BatteryReportAdapter adapter;
    private List<AppBatteryModel> dataList = new ArrayList<AppBatteryModel>(); 
    private List<AppBatteryModel> filteredList = new ArrayList<AppBatteryModel>(); 
    private BroadcastReceiver batteryReceiver;
    private int batteryCapacity = 5400; // 电池容量（mAh）
    private float lastBatteryPercent = 100.0f;
    private long lastCheckTime = System.currentTimeMillis();
    private EditText etSearch;
    private Map<String, Long> appRunTimeCache = new HashMap<String, Long>();
    private Map<String, String> packageToAppNameCache = new HashMap<String, String>();
    private PackageManager mPackageManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_battery_report);
        mPackageManager = getPackageManager();

        // 权限检查（Java7 传统条件判断）
        if (!hasUsageStatsPermission(this)) {
            Toast.makeText(this, "请进入设置-应用-权限-特殊访问权限-使用情况访问权限，开启本应用的权限", Toast.LENGTH_LONG).show();
            startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
            return;
        }

        etSearch = (EditText) findViewById(R.id.et_search); 
        rvBatteryReport = (RecyclerView) findViewById(R.id.rv_battery_report); 
        rvBatteryReport.setLayoutManager(new LinearLayoutManager(this));

        // 初始化流程：新增“加载24小时累计耗电”步骤
        loadAllAppPackage();
        preCacheAllAppNames();
        appRunTimeCache = getAppRunTime();
        updateAppRunTimeToModel();
        calculateInitial24hTotalConsumption(); // 初始化时计算24小时累计耗电
        filteredList.addAll(dataList);
        adapter = new BatteryReportAdapter(this, filteredList, mPackageManager, packageToAppNameCache);
        rvBatteryReport.setAdapter(adapter);

        // 搜索监听（不变）
        etSearch.addTextChangedListener(new TextWatcher() {
				@Override
				public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

				@Override
				public void onTextChanged(CharSequence s, int start, int before, int count) {
					filterAppsByPackageAndName(s.toString());
				}

				@Override
				public void afterTextChanged(Editable s) {}
			});

        // 电池广播：调用修改后的“单次耗电计算+累计累加”方法
        batteryReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                int level = intent.getIntExtra("level", 100);
                int scale = intent.getIntExtra("scale", 100);
                float currentPercent = (float) level / scale * 100;
                LogUtils.d(TAG, "电池百分比变化：" + lastBatteryPercent + " -> " + currentPercent);

                if (currentPercent < lastBatteryPercent) {
                    float dropPercent = lastBatteryPercent - currentPercent;
                    long duration = System.currentTimeMillis() - lastCheckTime;
                    LogUtils.d(TAG, "电池消耗：" + dropPercent + "%，时长：" + duration + "ms");
                    appRunTimeCache = getAppRunTime();
                    updateAppRunTimeToModel();
                    calculateSingleConsumptionAndAccumulate(dropPercent, appRunTimeCache); // 单次+累计逻辑
                }

                lastBatteryPercent = currentPercent;
                lastCheckTime = System.currentTimeMillis();
            }
        };
        registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Java7 显式非空判断
        if (batteryReceiver != null) {
            unregisterReceiver(batteryReceiver);
        }
    }

    /**
     * 加载所有应用（仅获取包名，初始化模型时单次耗电、累计耗电均设为0）
     */
    private void loadAllAppPackage() {
        List<ApplicationInfo> appList = mPackageManager.getInstalledApplications(PackageManager.GET_META_DATA);
        dataList.clear();

        LogUtils.d(TAG, "开始加载应用包名列表，共找到" + appList.size() + "个应用");

        for (ApplicationInfo appInfo : appList) {
            String packageName = appInfo.packageName;
            // 初始化：单次耗电（consumption）=0，累计耗电（totalConsumption）=0，运行时长=0
            dataList.add(new AppBatteryModel(packageName, 0.0f, 0.0f, 0));
        }

        LogUtils.d(TAG, "应用包名列表加载完成，共添加" + dataList.size() + "个包名。");
    }

    /**
     * 预缓存应用名称（逻辑不变）
     */
    private void preCacheAllAppNames() {
        packageToAppNameCache.clear();
        LogUtils.d(TAG, "开始预缓存包名-应用名称映射");

        for (AppBatteryModel model : dataList) {
            String packageName = model.getPackageName();
            String appName = getAppNameByPackage(packageName);
            packageToAppNameCache.put(packageName, appName);
        }

        LogUtils.d(TAG, "预缓存完成，共缓存" + packageToAppNameCache.size() + "个应用名称");
    }

    /**
     * 通过包名获取应用名称（逻辑不变）
     */
    private String getAppNameByPackage(String packageName) {
        try {
            ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName, 0);
            return mPackageManager.getApplicationLabel(appInfo).toString();
        } catch (PackageManager.NameNotFoundException e) {
            LogUtils.e(TAG, "包名" + packageName + "对应的应用未找到：" + e.getMessage());
            return packageName;
        } catch (Exception e) {
            LogUtils.e(TAG, "查询应用名称失败（包名：" + packageName + "）：" + e.getMessage());
            return packageName;
        }
    }

    /**
     * 更新运行时长到模型（逻辑不变）
     */
    private void updateAppRunTimeToModel() {
        int nCount = 0;
        for (AppBatteryModel model : dataList) {
            String packageName = model.getPackageName();
            Long runTime;
            if (appRunTimeCache.containsKey(packageName)) {
                runTime = appRunTimeCache.get(packageName);
                LogUtils.d(TAG, String.format("应用包 %s 运行时长已更新。", packageName));
                nCount++;
            } else {
                runTime = 0L;
            }
            model.setRunTime(runTime);
        }
        LogUtils.d(TAG, String.format("dataList.size() %d， appRunTimeCache.size() %d。", dataList.size(), appRunTimeCache.size()));
        LogUtils.d(TAG, String.format("updateAppRunTimeToModel() 更新的数据量为：%d", nCount));
    }

    /**
     * 【新增】初始化时计算24小时累计耗电（赋值给totalConsumption）
     * 逻辑：基于24小时运行时长占比，分配当前电池容量的理论24小时消耗
     */
    private void calculateInitial24hTotalConsumption() {
        long total24hRunTime = 0;
        // 1. 计算24小时内所有应用总运行时长
        for (Map.Entry<String, Long> entry : appRunTimeCache.entrySet()) {
            total24hRunTime += entry.getValue();
        }
        LogUtils.d(TAG, "24小时内所有应用总运行时长：" + formatRunTime(total24hRunTime));

        // 2. 按运行时长占比分配24小时累计耗电（假设电池满电循环，用总容量近似24小时总消耗）
        for (AppBatteryModel model : dataList) {
            String packageName = model.getPackageName();
            Long app24hRunTime = appRunTimeCache.getOrDefault(packageName, 0L);

            // 计算占比与累计耗电
            float ratio = (total24hRunTime > 0) ? (float) app24hRunTime / total24hRunTime : 0;
            float initialTotalConsumption = batteryCapacity * ratio; // 用电池容量近似24小时总消耗
            model.setTotalConsumption(initialTotalConsumption); // 初始化累计耗电
            LogUtils.d(TAG, String.format("应用包 %s 24小时累计耗电初始化：%.1f mAh", packageName, initialTotalConsumption));
        }
    }

    /**
     * 【核心修改】计算单次耗电（赋值给consumption）+ 累加至累计耗电（totalConsumption = totalConsumption + consumption）
     */
    private void calculateSingleConsumptionAndAccumulate(float dropPercent, Map<String, Long> runTimeMap) {
        long totalSingleRunTime = 0;
        // 1. 计算本次电池下降期间的总运行时长
        for (Map.Entry<String, Long> entry : runTimeMap.entrySet()) {
            totalSingleRunTime += entry.getValue();
        }

        // 2. 遍历计算每个应用的“单次耗电”并“累加至累计”
        for (AppBatteryModel model : dataList) {
            String packageName = model.getPackageName();
            Long appSingleRunTime = runTimeMap.getOrDefault(packageName, 0L);

            // 步骤1：计算本次单次耗电（赋值给consumption）
            float ratio = (totalSingleRunTime > 0) ? (float) appSingleRunTime / totalSingleRunTime : 0;
            float singleConsumption = batteryCapacity * dropPercent / 100 * ratio; // 单次消耗
            model.setConsumption(singleConsumption); // 存储单次耗电

            // 步骤2：累加单次耗电到累计耗电（totalConsumption = 原有累计 + 本次单次）
            float newTotalConsumption = model.getTotalConsumption() + singleConsumption;
            model.setTotalConsumption(newTotalConsumption); // 更新累计耗电

            // 同步运行时长
            model.setRunTime(appSingleRunTime);

            LogUtils.d(TAG, String.format("应用包 %s：单次耗电%.1f mAh，累计耗电%.1f mAh", 
										  packageName, singleConsumption, newTotalConsumption));
        }

        // 3. 按累计耗电排序（从高到低）
        Collections.sort(dataList, new Comparator<AppBatteryModel>() {
				@Override
				public int compare(AppBatteryModel m1, AppBatteryModel m2) {
					return Float.compare(m2.getTotalConsumption(), m1.getTotalConsumption());
				}
			});

        // 4. 重新应用过滤并刷新列表
        filterAppsByPackageAndName(etSearch.getText().toString());
    }

    /**
     * 双维度过滤（逻辑不变）
     */
    private void filterAppsByPackageAndName(String keyword) {
        filteredList.clear();
        if (keyword == null || keyword.isEmpty()) {
            filteredList.addAll(dataList);
        } else {
            String lowerKeyword = keyword.toLowerCase();

            for (AppBatteryModel model : dataList) {
                String packageName = model.getPackageName();
                String packageNameLower = packageName.toLowerCase();
                String appName = packageToAppNameCache.get(packageName);
                String appNameLower = appName.toLowerCase();

                boolean isMatched = packageNameLower.contains(lowerKeyword) 
                    || appNameLower.contains(lowerKeyword);

                if (isMatched) {
                    filteredList.add(model);
                }
            }
        }
        adapter.notifyDataSetChanged();
    }

    /**
     * 获取应用运行时长（逻辑不变，返回24小时运行时长）
     */
    private Map<String, Long> getAppRunTime() {
        Map<String, Long> runTimeMap = new HashMap<String, Long>();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
                android.app.usage.UsageStatsManager manager =
                    (android.app.usage.UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
                long endTime = System.currentTimeMillis();
                long startTime = endTime - 24 * 3600 * 1000; // 近24小时
                List<android.app.usage.UsageStats> statsList = manager.queryUsageStats(
                    android.app.usage.UsageStatsManager.INTERVAL_DAILY, startTime, endTime);

                for (android.app.usage.UsageStats stats : statsList) {
                    long runTimeMs = stats.getTotalTimeInForeground();
                    String packageName = stats.getPackageName();
                    LogUtils.d(TAG, "包名" + packageName + "24小时运行时长：" + formatRunTime(runTimeMs));
                    runTimeMap.put(packageName, runTimeMs);
                    if (packageName.equals("aidepro.top")) {
                        LogUtils.d(TAG, String.format("runTimeMap.put(packageName, runTimeMs) 特殊查询 %s 查询有结果。", packageName));
                    }
                }
            } catch (Exception e) {
                LogUtils.e(TAG, "获取应用运行时长失败：" + e.getMessage());
            }
        }

        LogUtils.d(TAG, String.format("应用运行时长列表数量%d。", runTimeMap.size()));
        return runTimeMap;
    }

    /**
     * 格式化运行时长（逻辑不变）
     */
    private String formatRunTime(long runTimeMs) {
        if (runTimeMs <= 0) {
            return "0秒";
        }
        long seconds = runTimeMs / 1000;
        long hours = seconds / 3600;
        long minutes = (seconds % 3600) / 60;
        seconds = seconds % 60;

        if (hours > 0) {
            return String.format("%d时%d分%d秒", hours, minutes, seconds);
        } else if (minutes > 0) {
            return String.format("%d分%d秒", minutes, seconds);
        } else {
            return String.format("%d秒", seconds);
        }
    }

    /**
     * 权限检查（逻辑不变）
     */
    private boolean hasUsageStatsPermission(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return false;
        }

        android.app.usage.UsageStatsManager manager =
            (android.app.usage.UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        if (manager == null) {
            return false;
        }

        long endTime = System.currentTimeMillis();
        long startTime = endTime - 1000 * 60;
        List<android.app.usage.UsageStats> statsList = manager.queryUsageStats(
            android.app.usage.UsageStatsManager.INTERVAL_DAILY, startTime, endTime);

        return statsList != null && !statsList.isEmpty();
    }

    /**
     * 【核心修改】数据模型：明确字段含义
     * - consumption：单次耗电（两次电池广播间的消耗，float类型便于计算）
     * - totalConsumption：累计耗电（24小时初始化值+后续单次累加，显示用）
     */
    public static class AppBatteryModel {
        private String packageName;    // 应用包名（核心标识）
        private float consumption;     // 单次耗电（mAh，float类型）
        private float totalConsumption;// 累计耗电（mAh，显示+排序用）
        private long runTime;          // 运行时长（ms）

		// Java7 显式构造：初始化单次耗电、累计耗电为0
        public AppBatteryModel(String packageName, float consumption, float totalConsumption, long runTime) {
            this.packageName = packageName;
            this.consumption = consumption; // 单次耗电初始为0
            this.totalConsumption = totalConsumption; // 累计耗电初始为0（后续初始化时赋值）
            this.runTime = runTime;
        }

        // Getter/Setter：覆盖所有字段，确保数据操作正常
        public String getPackageName() {
            return packageName;
        }

        public float getConsumption() {
            return consumption; // 获取单次耗电
        }

        public void setConsumption(float consumption) {
            this.consumption = consumption; // 设置单次耗电
        }

        public float getTotalConsumption() {
            return totalConsumption; // 获取累计耗电（显示用）
        }

        public void setTotalConsumption(float totalConsumption) {
            this.totalConsumption = totalConsumption; // 设置累计耗电（初始化/累加用）
        }

        public long getRunTime() {
            return runTime;
        }

        public void setRunTime(long runTime) {
            this.runTime = runTime;
        }
    }

    /**
     * RecyclerView 适配器：仅显示累计耗电（totalConsumption），逻辑适配模型修改
     */
    public static class BatteryReportAdapter extends RecyclerView.Adapter<BatteryReportAdapter.ViewHolder> {
        private Context mContext;
        private List<AppBatteryModel> mDataList;
        private PackageManager mPm;
        private Map<String, String> mPackageToNameCache;

        // Java7 显式构造：接收名称缓存，确保显示时高效获取应用名
        public BatteryReportAdapter(Context context, List<AppBatteryModel> dataList, 
                                    PackageManager pm, Map<String, String> packageToNameCache) {
            this.mContext = context;
            this.mDataList = dataList;
            this.mPm = pm;
            this.mPackageToNameCache = packageToNameCache;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            // 加载系统列表项布局（text1显示应用名，text2显示累计耗电+时长）
            View itemView = LayoutInflater.from(mContext)
                .inflate(android.R.layout.simple_list_item_2, parent, false);
            return new ViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // Java7 显式非空判断：避免空指针异常
            if (mDataList == null || mDataList.isEmpty() || position >= mDataList.size()) {
                holder.tvAppName.setText("未知应用");
                holder.tvConsumption.setText("累计耗电：0.0 mAh | 运行时长：0秒");
                return;
            }

            AppBatteryModel model = mDataList.get(position);
            String packageName = model.getPackageName();
            String appName = "";

            // 优先从缓存获取应用名：减少PackageManager调用，提升性能
            if (mPackageToNameCache != null && mPackageToNameCache.containsKey(packageName)) {
                appName = mPackageToNameCache.get(packageName);
            } else {
                // 缓存无数据时兜底查询，并同步更新缓存
                try {
                    ApplicationInfo appInfo = mPm.getApplicationInfo(packageName, 0);
                    appName = mPm.getApplicationLabel(appInfo).toString();
                    if (mPackageToNameCache != null) {
                        mPackageToNameCache.put(packageName, appName);
                    }
                } catch (PackageManager.NameNotFoundException e) {
                    appName = packageName; // 包名不存在时用包名兜底
                    LogUtils.e("Adapter", "包名" + packageName + "对应的应用未找到：" + e.getMessage());
                } catch (Exception e) {
                    appName = packageName; // 其他异常时用包名兜底
                    LogUtils.e("Adapter", "查询应用名称失败（包名：" + packageName + "）：" + e.getMessage());
                }
            }

            // 显示逻辑：仅展示累计耗电（totalConsumption），隐藏单次耗电
            holder.tvAppName.setText(appName);
            // 格式化运行时长 + 累计耗电（保留1位小数，提升可读性）
            String runTimeStr = ((BatteryReportActivity) mContext).formatRunTime(model.getRunTime());
            String totalConsumptionText = String.format("累计耗电：%.1f mAh | 运行时长：%s",
														model.getTotalConsumption(), runTimeStr);
            holder.tvConsumption.setText(totalConsumptionText);

            // 显示优化：文字颜色区分（避免所有应用均标蓝，仅示例可按需修改）
            holder.tvAppName.setTextColor(mContext.getResources().getColor(android.R.color.black));
            holder.tvConsumption.setTextColor(mContext.getResources().getColor(android.R.color.darker_gray));

            // 调整文字大小：适配手机屏幕，提升可读性
            holder.tvAppName.setTextSize(16);
            holder.tvConsumption.setTextSize(14);
        }

        // 获取列表长度：Java7 三元运算符判断空值，避免空指针
        @Override
        public int getItemCount() {
            return mDataList == null ? 0 : mDataList.size();
        }

        /**
         * ViewHolder：绑定系统布局控件，与显示逻辑对应
         */
        public static class ViewHolder extends RecyclerView.ViewHolder {
            TextView tvAppName;     // 显示应用名称
            TextView tvConsumption; // 显示累计耗电 + 运行时长

            // Java7 显式构造：绑定控件ID（系统布局固定ID：text1、text2）
            public ViewHolder(View itemView) {
                super(itemView);
                tvAppName = (TextView) itemView.findViewById(android.R.id.text1);
                tvConsumption = (TextView) itemView.findViewById(android.R.id.text2);
            }
        }
    }
}

