// License module - FREE VERSION (no activation required)
// All license checks always return activated status.

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct LicenseInfo {
    pub machine_code: String,
    pub expire_date: String,
    pub activated: bool,
    pub trial_remaining: i64,
    pub trial_total: i64,
    pub tampered: bool,
    pub is_trial: bool,
}

/// Generate machine code from hardware info (kept for compatibility)
#[tauri::command]
pub fn get_machine_code() -> Result<String, String> {
    let mut parts = Vec::new();

    #[cfg(target_os = "windows")]
    {
        if let Ok(output) = std::process::Command::new("wmic")
            .args(["cpu", "get", "processorid"]).output()
        {
            let s = String::from_utf8_lossy(&output.stdout);
            for line in s.lines().skip(1) {
                let t = line.trim();
                if !t.is_empty() { parts.push(t.to_string()); break; }
            }
        }
        if let Ok(output) = std::process::Command::new("wmic")
            .args(["diskdrive", "get", "serialnumber"]).output()
        {
            let s = String::from_utf8_lossy(&output.stdout);
            for line in s.lines().skip(1) {
                let t = line.trim();
                if !t.is_empty() { parts.push(t.to_string()); break; }
            }
        }
        if let Ok(output) = std::process::Command::new("wmic")
            .args(["baseboard", "get", "serialnumber"]).output()
        {
            let s = String::from_utf8_lossy(&output.stdout);
            for line in s.lines().skip(1) {
                let t = line.trim();
                if !t.is_empty() { parts.push(t.to_string()); break; }
            }
        }
    }

    #[cfg(not(target_os = "windows"))]
    {
        if let Ok(id) = std::fs::read_to_string("/etc/machine-id") {
            parts.push(id.trim().to_string());
        }
        if let Ok(cpuinfo) = std::fs::read_to_string("/proc/cpuinfo") {
            for line in cpuinfo.lines() {
                if line.starts_with("model name") || line.starts_with("Serial") {
                    if let Some(v) = line.split(':').nth(1) {
                        parts.push(v.trim().to_string());
                        break;
                    }
                }
            }
        }
        if let Ok(hostname) = std::process::Command::new("hostname").output() {
            parts.push(String::from_utf8_lossy(&hostname.stdout).trim().to_string());
        }
    }

    if parts.is_empty() {
        return Err("Unable to generate machine code".to_string());
    }

    let raw = parts.join("-");
    let hash = simple_hash(&raw);
    Ok(hash)
}

/// Always succeeds - no activation needed
#[tauri::command]
pub fn activate_license(_activate_code: String) -> Result<String, String> {
    Ok("软件已永久免费，无需激活".to_string())
}

/// Always returns activated status - software is free
#[tauri::command]
pub fn check_license() -> Result<LicenseInfo, String> {
    let machine = get_machine_code()?;
    Ok(LicenseInfo {
        machine_code: machine,
        expire_date: "永久有效".to_string(),
        activated: true,
        trial_remaining: 99999,
        trial_total: 99999,
        tampered: false,
        is_trial: false,
    })
}

fn simple_hash(input: &str) -> String {
    use std::collections::hash_map::DefaultHasher;
    use std::hash::{Hash, Hasher};
    let mut hasher = DefaultHasher::new();
    input.hash(&mut hasher);
    format!("{:016X}", hasher.finish())
}
/// Stub - no longer needed (software is free)
pub fn generate_activation(_machine_code: &str, _days: u32) -> String {
    String::new()
}