// 全局允许非标准命名风格
#![allow(non_camel_case_types, non_snake_case)]
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use serde::Serialize;
use sysinfo::{System, Disks};
use wmi::{COMLibrary, WMIConnection};
use std::fs;
use std::path::Path;
use std::io::Read; 
use std::process::Command;
use tauri::Emitter;
use chrono::{Duration, FixedOffset, Local, NaiveDate, TimeZone, DateTime};
use minidump::{Minidump, MinidumpException, MinidumpSystemInfo}; 
use std::ops::Deref;

// --- 1. 数据结构 (保持不变) ---

#[derive(Serialize, Clone)]
struct HardwareSummary {
    cpu_name: String,
    sys_vendor: String,
    sys_product: String,
    mobo_vendor: String,
    mobo_product: String,
    memory_total_gb: u64,
    memory_used_gb: u64,
    os_version: String,
    bios_version: String,
    c_drive_total_gb: u64,
    c_drive_used_gb: u64,
}

#[derive(Serialize, Clone)]
struct StorageDevice {
    model: String,
    health_status: String,
    human_explanation: String,
    is_danger: bool,
}

#[derive(Serialize, Clone)]
struct SystemEvent {
    time_generated: String,
    event_id: u32,
    source: String,
    message: String,
    analysis_hint: String,
}

#[derive(Serialize, Clone)]
struct MinidumpInfo {
    found: bool,
    count: usize,
    explanation: String,
}

#[derive(Serialize, Clone)]
struct DriverIssue {
    device_name: String,
    error_code: u32,
    description: String,
}

#[derive(Serialize, Clone)]
struct BatteryInfo {
    health_percentage: u32,
    is_ac_connected: bool,
    explanation: String,
}

#[derive(Serialize, Clone)]
struct BsodFileItem {
    filename: String,
    path: String,
    size_kb: u64,
    created_time: String,
}

#[derive(Serialize, Clone)]
struct BsodAnalysisReport {
    crash_reason: String,      
    crash_address: String,     
    bug_check_code: String,    
    crashing_thread: Option<String>, 
    human_analysis: String,    
    recommendation: String,    
}

// --- WMI 反序列化结构 ---
#[derive(serde::Deserialize, Debug)]
struct Win32_DiskDrive { Model: Option<String>, Status: Option<String> }
#[derive(serde::Deserialize, Debug)]
struct Win32_NTLogEvent { TimeGenerated: String, EventCode: u32, SourceName: String, Message: Option<String> }
#[derive(serde::Deserialize, Debug)]
struct Win32_PnPEntity { Name: Option<String>, ConfigManagerErrorCode: Option<u32> }
#[derive(serde::Deserialize, Debug)]
struct Win32_Battery { DesignCapacity: Option<u32>, FullChargeCapacity: Option<u32>, BatteryStatus: Option<u16> }
#[derive(serde::Deserialize, Debug)]
struct Win32_BIOS { SMBIOSBIOSVersion: Option<String> }
#[derive(serde::Deserialize, Debug)]
struct Win32_BaseBoard { Manufacturer: Option<String>, Product: Option<String> }
#[derive(serde::Deserialize, Debug)]
struct Win32_ComputerSystem { Manufacturer: Option<String>, Model: Option<String> }

// --- 辅助函数 ---
fn get_wmi_query_time(days_ago: i64) -> String {
    let target_date = Local::now() - Duration::days(days_ago);
    target_date.format("%Y%m%d%H%M%S.000000+000").to_string()
}

fn format_wmi_time(wmi_str: &str) -> String {
    if wmi_str.len() < 25 { return wmi_str.to_string(); }
    let year = wmi_str[0..4].parse::<i32>().unwrap_or(1970);
    let month = wmi_str[4..6].parse::<u32>().unwrap_or(1);
    let day = wmi_str[6..8].parse::<u32>().unwrap_or(1);
    let hour = wmi_str[8..10].parse::<u32>().unwrap_or(0);
    let min = wmi_str[10..12].parse::<u32>().unwrap_or(0);
    let sec = wmi_str[12..14].parse::<u32>().unwrap_or(0);
    let sign = &wmi_str[21..22];
    let offset_val = wmi_str[22..25].parse::<i32>().unwrap_or(0);
    let offset_mins = if sign == "-" { -offset_val } else { offset_val };
    let offset = FixedOffset::east_opt(offset_mins * 60).unwrap_or(FixedOffset::east_opt(0).unwrap());
    let naive_date = NaiveDate::from_ymd_opt(year, month, day).unwrap_or(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap());
    let naive_dt = naive_date.and_hms_opt(hour, min, sec).unwrap_or_default();
    match offset.from_local_datetime(&naive_dt).single() {
        Some(dt) => dt.with_timezone(&Local).format("%Y-%m-%d %H:%M:%S").to_string(),
        None => format!("{}-{:02}-{:02} {:02}:{:02}:{:02}", year, month, day, hour, min, sec)
    }
}

// [扩展] 翻译 BugCheck Code (u32) - 增加了更多常见代码
fn translate_bugcheck_u32(code: u32) -> (String, String) {
    match code {
        // 驱动与内存相关
        0x0000000A => (
            "IRQL_NOT_LESS_OR_EQUAL (0x0A)".to_string(),
            "驱动程序使用了不正确的内存地址。通常由有缺陷的驱动程序（如杀毒软件、虚拟光驱驱动）或硬件兼容性问题引起。建议更新所有驱动程序。"
                .to_string(),
        ),
        0x000000D1 => (
            "DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1)".to_string(),
            "驱动程序尝试访问未分页内存。这是最常见的蓝屏之一，通常是驱动程序冲突或损坏。请检查最近安装的硬件驱动（显卡、网卡等）。"
                .to_string(),
        ),
        0x0000007E | 0x1000007E => (
            "SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (0x7E)".to_string(),
            "系统线程抛出了未捕获的异常。可能是显卡驱动不兼容，或者BIOS设置问题。建议重装显卡驱动，或更新 BIOS。"
                .to_string(),
        ),
        0x0000001E => (
            "KMODE_EXCEPTION_NOT_HANDLED (0x1E)".to_string(),
            "内核模式程序生成了处理器无法捕获的异常。通常是硬件兼容性问题或驱动程序错误。建议检查是否有新安装的硬件。"
                .to_string(),
        ),
        0x00000050 => (
            "PAGE_FAULT_IN_NONPAGED_AREA (0x50)".to_string(),
            "试图访问无效的内存地址。极大概率是内存条故障（接触不良或损坏），或者是防病毒软件/驱动程序冲突。建议运行内存诊断。"
                .to_string(),
        ),
        0x0000001A => (
            "MEMORY_MANAGEMENT (0x1A)".to_string(),
            "严重的内存管理错误。高度怀疑内存条物理故障。建议立即运行 Windows 内存诊断工具，或者尝试拔插/更换内存条。"
                .to_string(),
        ),

        // 硬件与系统核心相关
        0x00000124 => (
            "WHEA_UNCORRECTABLE_ERROR (0x124)".to_string(),
            "硬件发生无法纠正的物理错误。这是纯硬件故障。通常是 CPU 电压不足（缩缸）、超频失败、过热，或者主板/PCIe设备故障。"
                .to_string(),
        ),
        0x00000101 => (
            "CLOCK_WATCHDOG_TIMEOUT (0x101)".to_string(),
            "CPU 核心死锁。系统检测到某个 CPU 核心在规定时间内没有响应。通常是因为 CPU 超频不稳定、电压不足或过热。"
                .to_string(),
        ),
        0x000000EF => (
            "CRITICAL_PROCESS_DIED (0xEF)".to_string(),
            "Windows 核心进程意外终止。通常是系统文件严重损坏或硬盘出现坏道导致无法读取系统文件。建议运行 'sfc /scannow'。"
                .to_string(),
        ),
        0x00000133 => (
            "DPC_WATCHDOG_VIOLATION (0x133)".to_string(),
            "DPC 看门狗超时。系统被某个驱动程序（通常是 SSD 固件、SATA 驱动或无线网卡驱动）卡死太久。建议更新 SSD 固件和主板芯片组驱动。"
                .to_string(),
        ),
        0x00000139 => (
            "KERNEL_SECURITY_CHECK_FAILURE (0x139)".to_string(),
            "内核检测到关键数据结构损坏。通常由内存错误、驱动程序 Bug 或病毒导致。建议检查内存和更新驱动。"
                .to_string(),
        ),

        // 显卡与电源相关
        0x00000116 => (
            "VIDEO_TDR_FAILURE (0x116)".to_string(),
            "显卡响应超时。显卡驱动崩溃且无法恢复。如果你在玩游戏，可能是显卡超频不稳定、电源功率不足或散热硅脂干了。"
                .to_string(),
        ),
        0x00000119 => (
            "VIDEO_SCHEDULER_INTERNAL_ERROR (0x119)".to_string(),
            "显卡调度器内部错误。这表明显卡驱动发送了无效数据，或者是显卡显存（VRAM）出现故障。"
                .to_string(),
        ),
        0x0000009F => (
            "DRIVER_POWER_STATE_FAILURE (0x9F)".to_string(),
            "驱动程序电源状态故障。通常发生在电脑休眠、睡眠或唤醒时。某个设备的驱动程序没有正确响应电源指令。建议检查电源管理设置。"
                .to_string(),
        ),

        // 存储与启动相关
        0x0000007B => (
            "INACCESSIBLE_BOOT_DEVICE (0x7B)".to_string(),
            "无法访问启动设备。通常是 BIOS 中的硬盘模式设置错误（如 AHCI/RAID 切换）或引导扇区损坏。也可能是硬盘物理连接松动。"
                .to_string(),
        ),
        0x00000024 => (
            "NTFS_FILE_SYSTEM (0x24)".to_string(),
            "NTFS 文件系统损坏。这通常意味着硬盘出现坏道或文件系统逻辑错误。建议立即运行 'chkdsk /f /r' 修复磁盘。"
                .to_string(),
        ),
        0x00000154 => (
            "UNEXPECTED_STORE_EXCEPTION (0x154)".to_string(),
            "系统存储组件检测到意外异常。通常指向系统盘（SSD/HDD）出现故障或连接线松动，导致系统无法读取关键数据。"
                .to_string(),
        ),
        
        // 系统服务异常
        0x0000003B => (
            "SYSTEM_SERVICE_EXCEPTION (0x3B)".to_string(),
            "系统服务执行异常。通常与图形驱动程序、系统文件损坏或过时的驱动有关。"
                .to_string(),
        ),
        _ => (
            format!("未知错误代码: 0x{:X}", code),
            "此代码较为罕见，建议手动在搜索引擎中搜索此错误代码。通用排查步骤：1. 更新所有驱动；2. 运行内存诊断；3. 检查系统文件完整性。"
                .to_string(),
        ),
    }
}

fn translate_bugcheck_str(code_str: &str) -> (String, String) {
    let clean_code = code_str.trim().replace("0x", "");
    if let Ok(code) = u32::from_str_radix(&clean_code, 16) {
        return translate_bugcheck_u32(code);
    }
    (format!("错误代码: {}", code_str), "无法识别的错误代码，建议手动搜索。".to_string())
}

// [公共逻辑] Rust 原生分析
fn analyze_dump_data_native<T>(dump: Minidump<T>) -> Result<BsodAnalysisReport, String> 
where T: Deref<Target = [u8]> 
{
    let (exception_code, exception_address) = match dump.get_stream::<MinidumpException>() {
        Ok(stream) => (
            stream.raw.exception_record.exception_code,
            stream.raw.exception_record.exception_address
        ),
        Err(_) => (0, 0) 
    };

    let sys_info_str = match dump.get_stream::<MinidumpSystemInfo>() {
        Ok(info) => format!("Windows Build {}", info.raw.build_number),
        Err(_) => "Unknown OS".to_string(),
    };

    if exception_code == 0 {
        return Err("未找到异常记录".to_string());
    }

    let (reason_str, recommend) = translate_bugcheck_u32(exception_code);

    Ok(BsodAnalysisReport {
        crash_reason: reason_str,
        crash_address: format!("0x{:X}", exception_address),
        bug_check_code: format!("0x{:X} ({})", exception_code, sys_info_str),
        crashing_thread: None,
        human_analysis: "通过 Rust 原生库分析得出。".to_string(),
        recommendation: recommend,
    })
}

// [修复] BlueScreenView 外部调用分析 (使用有损 UTF-8 转换)
fn analyze_with_bluescreenview(dump_path: &Path) -> Result<BsodAnalysisReport, String> {
    let bsv_exe = "BlueScreenView.exe"; 
    
    let mut temp_csv_path = std::env::temp_dir();
    temp_csv_path.push(format!("bsod_report_{}.csv", chrono::Utc::now().timestamp_millis()));

    // BlueScreenView.exe /LoadFrom 3 /SingleDumpFile <DumpFilePath> /scomma <OutFile>
    let status = Command::new(bsv_exe)
        .arg("/LoadFrom")
        .arg("3") 
        .arg("/SingleDumpFile")
        .arg(dump_path.to_string_lossy().to_string()) 
        .arg("/scomma")
        .arg(temp_csv_path.to_string_lossy().to_string())
        .status();

    if status.is_err() {
        return Err("未找到 BlueScreenView.exe，或没有以管理员运行。".to_string());
    }

    // [修改] 使用 fs::read 读取原始字节，然后有损转换为 String
    // 这样即使文件是 UTF-16 或者包含非法 UTF-8 字符，也不会 panic
    let content_bytes = fs::read(&temp_csv_path).map_err(|_| "BlueScreenView 分析未生成有效数据。".to_string())?;
    let _ = fs::remove_file(temp_csv_path); 

    // 1. 简单判断：如果包含很多 0 字节，可能是 UTF-16，尝试手动过滤 0 (简单粗暴但对 CSV 有效)
    // 2. 或者直接 lossy 转换，虽然 UTF-16 会乱码，但 CSV crate 有时能容忍乱码分隔符
    // 最稳妥的方式其实是先尝试 UTF-16LE 转换逻辑（但我们刚才移除了 encoding_rs），
    // 所以这里我们用一个简单的技巧：如果文件头两个字节是 FF FE，手动跳过 BOM
    
    let content_string = if content_bytes.len() > 2 && content_bytes[0] == 0xFF && content_bytes[1] == 0xFE {
        // 简易 UTF-16LE 转 UTF-8 (只针对 ASCII 字符有效，对中文可能会乱码，但在这个场景下够用了)
        // BlueScreenView 的列名和关键 hex 代码都是 ASCII
        let mut s = String::new();
        for i in (2..content_bytes.len()).step_by(2) {
            if i+1 < content_bytes.len() {
                // 取低位字节，忽略高位 0x00
                let c = content_bytes[i] as char;
                s.push(c);
            }
        }
        s
    } else {
        String::from_utf8_lossy(&content_bytes).to_string()
    };

    let mut rdr = csv::ReaderBuilder::new()
        .has_headers(false) 
        .from_reader(content_string.as_bytes());

    for result in rdr.records() {
        if let Ok(record) = result {
            if record.len() > 15 {
                // 跳过 Header 行
                if &record[0] == "Dump File" { continue; }

                let bug_check_string = &record[2];
                let bug_check_code = &record[3];
                let caused_by_driver = &record[8]; 
                let crash_addr = if record.len() > 15 { &record[15] } else { "N/A" };

                let (human, recommend) = translate_bugcheck_str(bug_check_code);
                
                let final_reason = if !bug_check_string.is_empty() { bug_check_string.to_string() } else { human };

                return Ok(BsodAnalysisReport {
                    crash_reason: final_reason,
                    crash_address: crash_addr.to_string(),
                    bug_check_code: bug_check_code.to_string(),
                    crashing_thread: Some(format!("Driver: {}", caused_by_driver)),
                    human_analysis: format!("BlueScreenView 分析结果：崩溃可能由驱动程序 [{}] 引起。", caused_by_driver),
                    recommendation: recommend,
                });
            }
        }
    }

    Err("BlueScreenView 输出为空或格式无法识别。".to_string())
}

// 辅助函数：检查文件头签名并返回类型
enum DumpType {
    Minidump,
    KernelDump, // PAGEDU64 / PAGE
    Unknown,
}

fn check_dump_signature(sig: &[u8]) -> DumpType {
    if sig.len() < 4 { return DumpType::Unknown; }
    if sig.starts_with(b"MDMP") { return DumpType::Minidump; }
    if sig.starts_with(b"PAGE") { return DumpType::KernelDump; }
    DumpType::Unknown
}

// --- 命令：列出 Minidump 文件 ---
#[tauri::command]
async fn list_minidumps() -> Result<Vec<BsodFileItem>, String> {
    let path = Path::new("C:\\Windows\\Minidump");
    let mut files = Vec::new();

    if path.exists() {
        if let Ok(entries) = fs::read_dir(path) {
            for entry in entries {
                if let Ok(entry) = entry {
                    let metadata = entry.metadata().ok();
                    let created = metadata.as_ref()
                        .and_then(|m| m.modified().ok()) 
                        .map(|t| {
                            let dt: DateTime<Local> = t.into();
                            dt.format("%Y-%m-%d %H:%M:%S").to_string()
                        })
                        .unwrap_or("Unknown".to_string());
                    
                    let size = metadata.as_ref().map(|m| m.len() / 1024).unwrap_or(0);

                    files.push(BsodFileItem {
                        filename: entry.file_name().to_string_lossy().to_string(),
                        path: entry.path().to_string_lossy().to_string(),
                        size_kb: size,
                        created_time: created,
                    });
                }
            }
        }
    }
    files.sort_by(|a, b| b.created_time.cmp(&a.created_time));
    Ok(files)
}

// --- 命令：分析指定路径的 Minidump ---
#[tauri::command]
async fn analyze_minidump(filepath: String) -> Result<BsodAnalysisReport, String> {
    let path = Path::new(&filepath);
    
    let mut file = fs::File::open(path).map_err(|e| format!("无法打开文件: {}", e))?;
    let mut header = [0u8; 4];
    
    let dump_type = if let Ok(_) = file.read_exact(&mut header) {
        check_dump_signature(&header)
    } else {
        DumpType::Unknown
    };

    match dump_type {
        DumpType::Minidump => {
            if let Ok(dump) = Minidump::read_path(path) {
                if let Ok(report) = analyze_dump_data_native(dump) {
                    return Ok(report);
                }
            }
            analyze_with_bluescreenview(path)
        },
        DumpType::KernelDump => {
            analyze_with_bluescreenview(path)
        },
        DumpType::Unknown => Err("无效的文件签名。不是有效的 Windows Dump 文件。".to_string())
    }
}

// 命令：分析二进制内容的 Minidump
#[tauri::command]
async fn analyze_minidump_bytes(file_content: Vec<u8>) -> Result<BsodAnalysisReport, String> {
    if file_content.is_empty() {
        return Err("导入的文件内容为空".to_string());
    }

    let dump_type = check_dump_signature(&file_content);

    match dump_type {
        DumpType::Minidump => {
            let native_result = Minidump::read(file_content.clone())
                .map_err(|e| e.to_string())
                .and_then(|dump| analyze_dump_data_native(dump));

            if let Ok(report) = native_result {
                return Ok(report);
            }
        },
        DumpType::KernelDump => {
            // 直接回退
        },
        DumpType::Unknown => return Err("无效的文件签名。请确认这是 .dmp 文件。".to_string())
    }

    let mut temp_dump_path = std::env::temp_dir();
    temp_dump_path.push(format!("temp_dump_{}.dmp", chrono::Utc::now().timestamp_millis()));
    
    if let Err(_) = fs::write(&temp_dump_path, &file_content) {
        return Err("无法写入临时文件进行分析".to_string());
    }

    let bsv_result = analyze_with_bluescreenview(&temp_dump_path);
    
    let _ = fs::remove_file(temp_dump_path); 

    bsv_result
}

// --- 现有命令：run_diagnosis (保持不变) ---
#[tauri::command]
async fn run_diagnosis(window: tauri::Window) -> Result<(), String> {
    std::thread::spawn(move || {
        // ... (保持原有逻辑不变，占位符) ...
        {
            let mut sys = System::new();
            sys.refresh_memory();
            sys.refresh_cpu();
            let wmi_con = WMIConnection::new(COMLibrary::new().unwrap()).ok();
            let mut bios_ver = "Unknown".to_string();
            let mut mobo_vendor = "Unknown".to_string();
            let mut mobo_product = "Unknown".to_string();
            let mut sys_vendor = "Unknown".to_string();
            let mut sys_product = "Unknown".to_string();
            if let Some(con) = &wmi_con {
                if let Ok(results) = con.raw_query::<Win32_BIOS>("SELECT SMBIOSBIOSVersion FROM Win32_BIOS") {
                    if let Some(bios) = results.first() { bios_ver = bios.SMBIOSBIOSVersion.clone().unwrap_or_default(); }
                }
                if let Ok(results) = con.raw_query::<Win32_BaseBoard>("SELECT Manufacturer, Product FROM Win32_BaseBoard") {
                    if let Some(board) = results.first() {
                        mobo_vendor = board.Manufacturer.clone().unwrap_or_default();
                        mobo_product = board.Product.clone().unwrap_or_default();
                    }
                }
                if let Ok(results) = con.raw_query::<Win32_ComputerSystem>("SELECT Manufacturer, Model FROM Win32_ComputerSystem") {
                    if let Some(cs) = results.first() {
                        sys_vendor = cs.Manufacturer.clone().unwrap_or_default();
                        sys_product = cs.Model.clone().unwrap_or_default();
                    }
                }
            }
            let mut c_total = 0u64;
            let mut c_used = 0u64;
            let disks = Disks::new_with_refreshed_list();
            for disk in &disks {
                if disk.mount_point().to_string_lossy().starts_with("C:") {
                    c_total = disk.total_space() / 1024 / 1024 / 1024;
                    let free = disk.available_space() / 1024 / 1024 / 1024;
                    c_used = c_total - free;
                    break;
                }
            }
            let cpu_brand = if let Some(cpu) = sys.cpus().first() { cpu.brand().trim().to_string() } else { "Unknown CPU".to_string() };
            let hardware = HardwareSummary {
                cpu_name: cpu_brand, sys_vendor, sys_product, mobo_vendor, mobo_product,
                memory_total_gb: sys.total_memory() / 1024 / 1024 / 1024,
                memory_used_gb: sys.used_memory() / 1024 / 1024 / 1024,
                os_version: System::long_os_version().unwrap_or("Unknown".to_string()),
                bios_version: bios_ver,
                c_drive_total_gb: c_total, c_drive_used_gb: c_used,
            };
            let _ = window.emit("report-hardware", hardware);
        }
        let wmi_con = WMIConnection::new(COMLibrary::new().unwrap()).ok();
        {
            let mut storage = Vec::new();
            if let Some(con) = &wmi_con {
                let query = "SELECT Model, Status FROM Win32_DiskDrive";
                if let Ok(results) = con.raw_query::<Win32_DiskDrive>(query) {
                    for disk in results {
                        let status = disk.Status.unwrap_or("Unknown".to_string());
                        let (explanation, is_danger) = match status.as_str() {
                            "OK" => ("健康".to_string(), false),
                            "Pred Fail" => ("预测即将损坏".to_string(), true),
                            _ => ("状态异常".to_string(), true),
                        };
                        storage.push(StorageDevice {
                            model: disk.Model.unwrap_or("Generic Disk".to_string()),
                            health_status: status,
                            human_explanation: explanation,
                            is_danger,
                        });
                    }
                }
            }
            let _ = window.emit("report-storage", storage);
        }
        {
            let mut driver_issues = Vec::new();
            if let Some(con) = &wmi_con {
                let query = "SELECT Name, ConfigManagerErrorCode FROM Win32_PnPEntity WHERE ConfigManagerErrorCode <> 0";
                if let Ok(results) = con.raw_query::<Win32_PnPEntity>(query) {
                    for dev in results {
                        let code = dev.ConfigManagerErrorCode.unwrap_or(0);
                        let desc = match code {
                            10 => "设备无法启动 (Code 10)。通常是驱动不兼容。",
                            28 => "驱动程序未安装 (Code 28)。",
                            43 => "硬件报告问题已被停止 (Code 43)。显卡常见，可能虚焊。",
                            _ => "设备状态异常。",
                        };
                        driver_issues.push(DriverIssue {
                            device_name: dev.Name.unwrap_or("未知设备".to_string()),
                            error_code: code, description: desc.to_string(),
                        });
                    }
                }
            }
            let _ = window.emit("report-drivers", driver_issues);
        }
        {
            let mut minidump = MinidumpInfo { found: false, count: 0, explanation: "无蓝屏记录".to_string() };
            if let Ok(entries) = fs::read_dir("C:\\Windows\\Minidump") {
                let count = entries.count();
                if count > 0 {
                    minidump = MinidumpInfo {
                        found: true, count, explanation: format!("发现 {} 次蓝屏崩溃", count),
                    };
                }
            }
            let _ = window.emit("report-minidumps", minidump);
        }
        {
            let mut battery_info = None;
            if let Some(con) = &wmi_con {
                if let Ok(results) = con.raw_query::<Win32_Battery>("SELECT DesignCapacity, FullChargeCapacity, BatteryStatus FROM Win32_Battery") {
                    if let Some(bat) = results.first() {
                        let design = bat.DesignCapacity.unwrap_or(0);
                        let full = bat.FullChargeCapacity.unwrap_or(0);
                        let status = bat.BatteryStatus.unwrap_or(0);
                        if design > 0 {
                            let health = ((full as f64 / design as f64) * 100.0) as u32;
                            let ac_plugged = status == 2 || status == 6 || status == 1;
                            let explain = if health < 60 { "电池老化严重，建议更换，否则可能导致供电不稳。".to_string() } else { "电池状态良好。".to_string() };
                            battery_info = Some(BatteryInfo {
                                health_percentage: health, is_ac_connected: ac_plugged, explanation: explain,
                            });
                        }
                    }
                }
            }
            let _ = window.emit("report-battery", battery_info);
        }
        {
            let mut events = Vec::new();
            if let Some(con) = &wmi_con {
                let start_time_str = get_wmi_query_time(30);
                let query = format!(
                    "SELECT TimeGenerated, EventCode, SourceName, Message FROM Win32_NTLogEvent WHERE Logfile = 'System' AND TimeGenerated >= '{}' AND (EventCode = 41 OR EventCode = 18 OR EventCode = 19 OR EventCode = 7 OR EventCode = 1001 OR EventCode = 4101)",
                    start_time_str
                );
                if let Ok(results) = con.raw_query::<Win32_NTLogEvent>(&query) {
                    for event in results {
                        let mut is_target_event = false;
                        let mut hint = String::new();
                        if event.EventCode == 41 && event.SourceName == "Microsoft-Windows-Kernel-Power" {
                            is_target_event = true; hint = "系统意外断电 (电源/强关)".to_string();
                        } else if (event.EventCode == 18 || event.EventCode == 19) && event.SourceName == "Microsoft-Windows-WHEA-Logger" {
                            is_target_event = true; hint = "WHEA 硬件致命错误 (CPU/超频/PCIe)".to_string();
                        } else if event.EventCode == 7 && (event.SourceName == "Disk" || event.SourceName == "disk") {
                            is_target_event = true; hint = "硬盘出现坏道 (Disk Bad Block)".to_string();
                        } else if event.EventCode == 1001 && event.SourceName == "BugCheck" {
                            is_target_event = true; hint = "系统发生蓝屏死机 (BSOD)".to_string();
                        } else if event.EventCode == 4101 && event.SourceName == "Display" {
                            is_target_event = true; hint = "显卡驱动停止响应并已恢复 (TDR)".to_string();
                        }
                        if is_target_event {
                            events.push(SystemEvent {
                                time_generated: format_wmi_time(&event.TimeGenerated),
                                event_id: event.EventCode,
                                source: event.SourceName,
                                message: event.Message.unwrap_or("无详细信息".to_string()),
                                analysis_hint: hint,
                            });
                        }
                        // [修改] 移除了数量限制，让它获取所有符合条件的日志
                    }
                }
            }
            let _ = window.emit("report-events", events);
        }
        let _ = window.emit("diagnosis-finished", ());
    });
    Ok(())
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![run_diagnosis, list_minidumps, analyze_minidump, analyze_minidump_bytes])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}