use anyhow::Result;
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use std::fs;
use std::path::Path;
use tauri_plugin_http::reqwest::blocking::get;
use walkdir::WalkDir;

use crate::steam;

#[derive(Serialize, Deserialize, Debug)]
pub struct User {
    steam_id64: u64,
    steam_id32: u32,
    account_name: String,
    persona_name: String,
    recent: i32,
    avatar: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct LoginUser {
    steam_id64: u64,
    steam_id32: u32,
    account_name: String,
    persona_name: String,
    remember_password: String,
    wants_offline_mode: String,
    skip_offline_mode_warning: String,
    allow_auto_login: String,
    most_recent: String,
    timestamp: String,
    avatar: String,
    avatar_key: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct LocalUser {
    steam_id32: u32,
    persona_name: String,
    avatar_key: String,
}

pub fn parse_login_users(steam_dir: &str) -> Result<Vec<LoginUser>> {
    let t_path = Path::new(steam_dir).join("config/loginusers.vdf");
    if !t_path.exists() {
        return Ok(Vec::new());
    }

    let data = fs::read_to_string(t_path)?;
    let json_data = super::parse::to_json(&data);
    let kv: HashMap<String, Value> = serde_json::from_str(&json_data)?;

    let mut users = Vec::new();
    for (k, v) in kv {
        let props = v.as_object().unwrap();

        let avatar = if let Some(img) = read_avatar(&steam_dir, &k) {
            img
        } else {
            String::new()
        };

        let id64 = k.parse::<u64>()?;

        let user = LoginUser {
            steam_id32: steam::id::id64_to_32(id64),
            steam_id64: id64,
            account_name: props
                .get("AccountName")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            persona_name: props
                .get("PersonaName")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            remember_password: props
                .get("RememberPassword")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            wants_offline_mode: props
                .get("WantsOfflineMode")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            skip_offline_mode_warning: props
                .get("SkipOfflineModeWarning")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            allow_auto_login: props
                .get("AllowAutoLogin")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            most_recent: props
                .get("MostRecent")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            timestamp: props
                .get("Timestamp")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string(),
            avatar,
            avatar_key: String::new(),
        };

        users.push(user);
    }

    Ok(users)
}

pub fn parse_local_users(steam_dir: &str) -> Result<Vec<LocalUser>> {
    let root = Path::new(steam_dir).join("userdata");
    if !root.exists() {
        return Ok(Vec::new());
    }

    let mut local_users = Vec::new();

    for entry in WalkDir::new(&root) {
        let entry = entry?;
        let path = entry.path();

        // 跳过根目录
        if path == root {
            continue;
        }

        // 只处理目录
        if entry.file_type().is_dir() {
            let id = path.file_name().unwrap().to_str().unwrap();

            // 检查 localconfig.vdf 文件是否存在
            let local_config_path = path.join("config/localconfig.vdf");
            if !local_config_path.exists() {
                continue;
            }

            // 读取并解析 localconfig.vdf 文件
            let data = fs::read_to_string(local_config_path)?;
            let json_data = super::parse::to_json(&data);
            let kv: HashMap<String, Value> = serde_json::from_str(&json_data)?;

            // 获取 friends 节点
            let friends = kv.get("friends").and_then(|v| v.as_object());
            if friends.is_none() {
                continue;
            }

            let friends = friends.unwrap();

            // 获取 PersonaName
            let persona_name = friends
                .get("PersonaName")
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string();

            // 获取 AvatarKey
            let avatar_key = friends
                .get(id)
                .and_then(|v| v.as_object())
                .and_then(|props| props.get("avatar"))
                .and_then(|v| v.as_str())
                .unwrap_or("")
                .to_string();

            // 创建 LocalUser 并加入列表
            local_users.push(LocalUser {
                steam_id32: id.parse::<u32>().unwrap(),
                persona_name,
                avatar_key,
            });

            // 跳过子目录
            WalkDir::new(path).max_depth(1).into_iter().next();
        }
    }

    Ok(local_users)
}

pub fn merge_users(login: Vec<LoginUser>, local: Vec<LocalUser>) -> Vec<User> {
    let mut users = Vec::new();
    for i in login {
        let avatar: String;
        let mut avatar_key = String::new();

        // 匹配获取 avatar_key 在线获取头像使用
        let t_usr: Vec<&LocalUser> = local
            .iter()
            .filter(|j| i.steam_id32 == j.steam_id32)
            .collect();

        if let Some(usr) = t_usr.first() {
            avatar_key = usr.avatar_key.clone();
        }

        // 获取头像的base64 本地头像文件不存在时使用在线api获取
        if i.avatar.is_empty() && !avatar_key.is_empty() {
            avatar = download_avatar(&avatar_key).unwrap_or_default();
        } else {
            avatar = i.avatar;
        }

        users.push(User {
            steam_id64: i.steam_id64,
            steam_id32: i.steam_id32,
            account_name: i.account_name,
            persona_name: i.persona_name,
            recent: i.most_recent.parse().unwrap_or(0),
            avatar,
        });
    }

    // 把第一个recent=1的放在头部
    for (id, usr) in users.iter_mut().enumerate() {
        if usr.recent == 1 {
            let tmp = users.remove(id);
            users.insert(0, tmp);
            break;
        }
    }

    users
}

pub fn get_users(steam_dir: &str) -> Result<Vec<User>> {
    let login_users = parse_login_users(steam_dir)?;
    let local_users = parse_local_users(steam_dir)?;
    let users = merge_users(login_users, local_users);

    Ok(users)
}

fn download_avatar(avatar_key: &str) -> Result<String> {
    // 下载并转换成Base64 "https://avatars.cloudflare.steamstatic.com/" + avatarKey + "_full.jpg"
    let url = format!(
        "https://avatars.cloudflare.steamstatic.com/{}_full.jpg",
        avatar_key
    );
    if let Ok(resp) = get(&url) {
        if let Ok(bytes) = resp.bytes() {
            return Ok(STANDARD.encode(bytes));
        }
    }
    return Err(anyhow::anyhow!("Failed to download avatar"));
}

fn read_avatar(steam_dir: &str, steam_id64: &str) -> Option<String> {
    let t_path = Path::new(steam_dir).join(format!("config\\avatarcache\\{}.png", steam_id64));
    if !t_path.exists() {
        return None;
    }

    if let Ok(img) = fs::read(t_path) {
        Some(STANDARD.encode(img))
    } else {
        None
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_get_users() {
        let users = get_users("D:\\Programs\\Steam").unwrap();
        println!("{:?}", users);
    }
}
