use git2::Repository;
use std::collections::HashMap;
use std::path::PathBuf;

use crate::errors::KamError;
use crate::types::kam_toml::KamToml;
use crate::types::kam_toml::enums::ModuleType;

const KERNELSU_RESERVED_REPO_NAMES: &[&str] = &[
    ".github",
    "submission",
    "developers",
    "modules",
    "org.kernelsu.example",
    "module_release",
];

fn trim_description(input: &str) -> String {
    let trimmed = input.trim();
    if trimmed.chars().count() > 200 {
        let shortened: String = trimmed.chars().take(200).collect();
        format!("{shortened}...")
    } else {
        trimmed.to_string()
    }
}

fn is_readme_description_line(line: &str) -> bool {
    let trimmed = line.trim();
    let lower = trimmed.to_ascii_lowercase();

    if trimmed.len() <= 10
        || trimmed.starts_with('#')
        || trimmed.starts_with("```")
        || trimmed.starts_with("<!--")
        || trimmed.starts_with('!')
        || trimmed.starts_with('|')
        || trimmed.starts_with("---")
        || trimmed.starts_with("***")
        || trimmed.starts_with("===")
    {
        return false;
    }

    if lower.starts_with("<div")
        || lower.starts_with("</div")
        || lower.starts_with("<p")
        || lower.starts_with("</p")
        || lower.starts_with("<img")
        || lower.starts_with("<a ")
        || lower.starts_with("<br")
        || lower.contains("img.shields.io")
        || lower.contains("github.com/")
        || lower.contains("badge")
    {
        return false;
    }

    trimmed
        .chars()
        .any(|c| c.is_alphanumeric() || ('\u{4e00}'..='\u{9fff}').contains(&c))
}

fn extract_readme_description(content: &str) -> Option<String> {
    for line in content.lines() {
        if is_readme_description_line(line) {
            return Some(trim_description(line));
        }
    }
    None
}

// 初始化前的数据结构
// 把各种参数和默认值都收集到这里
/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public struct 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
pub struct PreInitData {
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'path' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub path: PathBuf,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'id' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub id: String,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'name' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub name: String,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'version' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub version: String,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'author' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub author: String,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'description' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub description: String,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'template_vars' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub template_vars: HashMap<String, String>,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'impl_template' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub impl_template: String,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'module_type' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub module_type: ModuleType,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'update_json' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub update_json: Option<String>,
    /// KernelSU module source URL for module.json sourceUrl.
    pub source_url: Option<String>,
    /// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public field 'kam_toml' in 'PreInitData'. Replace with real documentation. (2025-12-30T22:23:21Z)
    pub kam_toml: KamToml,
}

// 准备初始化数据，在创建项目之前
// 这里主要是处理各种参数、默认值、git信息等
/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'prepare_init'. Replace with real documentation. (2025-12-30T22:23:21Z)
///
/// # Errors
/// Returns `Err(KamError)` if filesystem operations, archive extraction,
/// Git discovery, template parsing, or other initialization steps fail.
///
/// Note: This function is intentionally large and performs several I/O and
/// heuristics; a follow-up refactor should split responsibilities into
/// smaller units and add more specific `# Errors` documentation for each case.
// TEMPORARY: allow this lint while we perform a staged refactor.
// TODO: split `prepare_init` into smaller helpers, add finer-grained `# Errors`
/// documentation for each helper, and remove this allowance.
#[allow(clippy::too_many_lines)]
pub fn prepare_init(args: &super::InitArgs) -> Result<PreInitData, KamError> {
    let current_dir = std::env::current_dir()?;
    // 交互模式下name可能为空，默认用"."（当前目录）
    let project_name_raw = args.name.as_deref().unwrap_or(".");
    let project_path: PathBuf = if project_name_raw.starts_with('/')
        || project_name_raw.starts_with('\\')
        || project_name_raw.contains(':')
    {
        PathBuf::from(project_name_raw)
    } else {
        current_dir.join(project_name_raw)
    };

    // 检查冲突的标志
    // --tmpl 和 -t/--template 是互斥的，不能同时用
    let type_flags = [args.tmpl, args.template.is_some()]
        .iter()
        .filter(|&&x| x)
        .count();
    if type_flags > 1 {
        return Err(KamError::InvalidModuleType(
            "Cannot specify multiple module types: --tmpl, -t/--template".to_string(),
        ));
    }

    // 确定模块类型和模板
    // -t/--template 支持：
    //  1) 完整的模板ID（如 "kam_template" 或 "kam_template.tar.gz"）
    //  2) 简短的builtin ID（如 "kam", "meta", "ak3"），会自动映射到 "<id>_template"
    //  3) 本地路径或压缩包（如 /path/to/template.tar.gz 或 https://.../template.tar.gz）
    //
    // 注意：这里不再强制添加 "_template" 后缀，直接传原始输入
    // 让下一阶段的 impl_mod/template manager 来做智能发现
    let (module_type, impl_template) = if args.tmpl {
        (ModuleType::Template, "tmpl_template".to_string())
    } else if let Some(t) = &args.template {
        // Pass raw string. Discovery logic in `impl_mod.rs` will handle suffixing if needed.
        (ModuleType::Kam, t.clone())
    } else {
        // 默认是kam模块
        (ModuleType::Kam, "kam_template".to_string())
    };

    // 解析模板变量（从 --var 参数）
    let mut template_vars = crate::template::TemplateManager::parse_template_vars(&args.var)?;

    let version = args.version.as_deref().unwrap_or("v1.0.0");

    // 早点发现Git信息，可以用来做默认值（id、author、repo URL等）
    let mut git_author: Option<String> = None;
    let mut git_repo_url: Option<String> = None;
    let mut git_branch: Option<String> = None;
    let mut git_repo_name: Option<String> = None;
    let mut git_owner: Option<String> = None;

    // 尝试发现git仓库
    if let Ok(repo) = Repository::discover(&current_dir) {
        // 获取 git user.name
        if let Ok(cfg) = repo.config()
            && let Ok(name) = cfg.get_string("user.name")
        {
            git_author = Some(name);
        }

        // 获取 remote URL
        if let Ok(remote) = repo.find_remote("origin")
            && let Ok(url) = remote.url()
        {
            git_repo_url = Some(url.to_string());
        }
        // 如果没找到origin，就用第一个可用的remote
        if git_repo_url.is_none()
            && let Ok(remotes) = repo.remotes()
            && let Ok(Some(name)) = remotes.get(0)
            && let Ok(remote) = repo.find_remote(name)
            && let Ok(url) = remote.url()
        {
            git_repo_url = Some(url.to_string());
        }

        // 从 remote URL 解析 owner 和 repo name
        if let Some(ref url) = git_repo_url
            && let Some((owner, repo_name)) = parse_git_remote_url(url)
        {
            git_owner = Some(owner);
            git_repo_name = Some(repo_name);
        }

        // 获取当前分支名
        if let Ok(head) = repo.head()
            && let Ok(name) = head.name()
        {
            // 尝试从 refs/heads/xxx 提取分支名
            if let Some(stripped) = name.strip_prefix("refs/heads/") {
                git_branch = Some(stripped.to_string());
            } else if let Ok(branch_name) = head.shorthand() {
                // 如果已经是简短名称，直接使用
                git_branch = Some(branch_name.to_string());
            }
        }
    }

    // 默认分支名，如果无法获取则使用 "main"
    let default_branch = git_branch.as_deref().unwrap_or("main");

    // 智能推断项目名称：优先使用 git 仓库名，其次目录名
    let project_name_str = args.project_name.as_ref().map_or_else(
        || {
            // 优先使用 detected git 仓库名（如果有），否则从路径或当前目录提取
            git_repo_name.as_ref().map_or_else(
                || {
                    if project_name_raw == "." {
                        // 从当前目录名提取
                        let dir_name = current_dir
                            .file_name()
                            .and_then(|s| s.to_str())
                            .unwrap_or("Example Module Name")
                            .to_string();
                        let mut name = dir_name.replace(['_', '-'], " ");
                        if let Some(first_char) = name.chars().next() {
                            let mut chars: Vec<char> = name.chars().collect();
                            chars[0] = first_char.to_uppercase().next().unwrap_or(first_char);
                            name = chars.into_iter().collect();
                        }
                        name
                    } else {
                        // 从路径提取目录名并美化
                        let dir_name = std::path::Path::new(project_name_raw)
                            .file_name()
                            .and_then(|s| s.to_str())
                            .unwrap_or(project_name_raw)
                            .to_string();
                        let mut name = dir_name.replace(['_', '-'], " ");
                        if let Some(first_char) = name.chars().next() {
                            let mut chars: Vec<char> = name.chars().collect();
                            chars[0] = first_char.to_uppercase().next().unwrap_or(first_char);
                            name = chars.into_iter().collect();
                        }
                        name
                    }
                },
                |repo_name| {
                    // 将仓库名转换为更友好的显示名称（去掉下划线/横线，首字母大写等）
                    let mut name = repo_name.clone();
                    // 简单的美化：将下划线和横线替换为空格，并首字母大写
                    name = name.replace(['_', '-'], " ");
                    // 简单的首字母大写（只处理第一个单词）
                    if let Some(first_char) = name.chars().next() {
                        let mut chars: Vec<char> = name.chars().collect();
                        chars[0] = first_char.to_uppercase().next().unwrap_or(first_char);
                        name = chars.into_iter().collect();
                    }
                    name
                },
            )
        },
        std::clone::Clone::clone,
    );

    // 智能推断描述：优先从 README.md 提取，其次使用默认值
    let description_str = args.description.as_ref().map_or_else(
        || {
            // 尝试从 README.md 提取描述
            let readme_paths = [
                current_dir.join("README.md"),
                current_dir.join("README"),
                current_dir.join("readme.md"),
            ];

            let mut extracted_desc: Option<String> = None;
            for readme_path in &readme_paths {
                if let Ok(content) = std::fs::read_to_string(readme_path) {
                    extracted_desc = extract_readme_description(&content);
                    if extracted_desc.is_some() {
                        break;
                    }
                }
            }

            extracted_desc.unwrap_or_else(|| match module_type {
                ModuleType::Kam => "Describe your module here".to_string(),
                ModuleType::Template => "Describe your template here".to_string(),
            })
        },
        std::clone::Clone::clone,
    );
    template_vars.insert("project_name".to_string(), project_name_str.clone());
    template_vars.insert("description".to_string(), description_str.clone());
    template_vars.insert("metamodule".to_string(), args.metamodule.to_string());

    // 确定ID：优先用 --id，没有就用git repo名（如果检测到仓库且name不是'.'），再没有就用文件夹名
    let id = args.id.as_ref().map_or_else(
        || {
            if project_name_raw == "." {
                // if git repo identified, prefer repo name
                git_repo_url
                    .as_ref()
                    .and_then(|repo_url| {
                        parse_git_remote_url(repo_url.as_str()).map(|(_owner, repo_name)| repo_name)
                    })
                    .unwrap_or_else(|| {
                        std::env::current_dir()
                            .ok()
                            .and_then(|p| {
                                p.file_name()
                                    .and_then(|s| s.to_str())
                                    .map(ToString::to_string)
                            })
                            .unwrap_or_else(|| "Example Module Name".to_string())
                    })
            } else {
                // Extract basename from path (e.g., "/tmp/test_kam_init" -> "test_kam_init")
                std::path::Path::new(project_name_raw)
                    .file_name()
                    .and_then(|s| s.to_str())
                    .unwrap_or(project_name_raw)
                    .to_string()
            }
        },
        std::clone::Clone::clone,
    );

    if id.is_empty() {
        return Err(KamError::InvalidConfig(
            "Module ID cannot be empty".to_string(),
        ));
    }

    // KernelSU Modules Repo requires repository names to match module.prop id.
    // Valid names must match ^[a-zA-Z][a-zA-Z0-9._-]+$.
    let mut id_chars = id.chars();
    let id_first_valid = id_chars.next().is_some_and(|c| c.is_ascii_alphabetic());
    let id_rest_valid = id_chars
        .clone()
        .all(|c| c.is_ascii_alphanumeric() || c == '.' || c == '-' || c == '_');
    if !id_first_valid || !id_rest_valid || id.len() < 2 {
        return Err(KamError::InvalidConfig(format!(
            "Invalid module ID '{id}': KernelSU Modules Repo IDs must match ^[a-zA-Z][a-zA-Z0-9._-]+$"
        )));
    }

    if KERNELSU_RESERVED_REPO_NAMES.contains(&id.as_str()) {
        return Err(KamError::InvalidConfig(format!(
            "Invalid module ID '{id}': this repository name is reserved by KernelSU Modules Repo"
        )));
    }

    // 确定author，优先级：命令行参数 > git user.name > 全局配置 > 默认值
    // 全局配置位于 Kam 家目录下的 config.toml (可通过 `KAM_HOME` 环境变量覆盖，默认为 ~/.kam)
    let mut global_author: Option<String> = None;
    if let Ok(cfg_home) = crate::utils::kam_home_dir() {
        let cfg_path = cfg_home.join("config.toml");
        if cfg_path.exists()
            && let Ok(content) = std::fs::read_to_string(&cfg_path)
            && let Ok(v) = toml::from_str::<toml::Value>(&content)
            && let Some(prop) = v.get("prop")
            && let Some(author_val) = prop.get("author")
            && let Some(s) = author_val.as_str()
        {
            global_author = Some(s.to_string());
        }
    }

    let author = args.author.as_deref().map_or_else(
        || {
            git_author
                .or(global_author)
                .unwrap_or_else(|| "Your Name".to_string())
        },
        ToString::to_string,
    );

    let update_json_val = args
        .update_json
        .clone()
        .or_else(|| crate::types::kam_toml::sections::PropSection::default().updateJson);

    // 创建初始的KamToml，用默认值
    let mut kam_toml = KamToml::new_with_current_timestamp(
        id.clone(),
        project_name_str.clone(),
        version.to_string(),
        Some(author),
        description_str.clone(),
        update_json_val,
        None,
    );

    // 设置name和description（允许后续覆盖）
    kam_toml.prop.name.clone_from(&project_name_str);
    kam_toml.prop.description.clone_from(&description_str);
    kam_toml.prop.metamodule = args.metamodule;

    let update_json = kam_toml.prop.updateJson.clone();

    if let Some(uj) = &update_json {
        template_vars.insert("update_json".to_string(), uj.clone());
    }

    // 设置zipUrl和changelog的默认值（用id）
    template_vars
        .entry("zipUrl".to_string())
        .or_insert_with(|| {
            format!("https://github.com/user/repo/releases/latest/download/{id}.zip")
        });
    template_vars
        .entry("changelog".to_string())
        .or_insert_with(|| {
            "https://raw.githubusercontent.com/user/repo/branch/CHANGELOG.md".to_string()
        });

    // 如果发现了git仓库，就用更智能的默认值
    let mut inferred_source_url: Option<String> = None;

    if let Some(repo_url) = git_repo_url {
        // 从remote URL解析出owner/repo
        if let (Some(owner), Some(repo_name)) = (git_owner, git_repo_name) {
            inferred_source_url = Some(format!("https://github.com/{owner}/{repo_name}"));
            // 如果update_json没设置，就用raw.githubusercontent的默认值（使用实际分支名）
            if kam_toml.prop.updateJson.is_none() {
                let default_update = format!(
                    "https://raw.githubusercontent.com/{owner}/{repo_name}/{default_branch}/update.json"
                );
                kam_toml.prop.updateJson = Some(default_update.clone());
                template_vars.insert("update_json".to_string(), default_update);
            }

            // 如果zipUrl和changelog还是默认值，就用仓库相关的值替换
            template_vars
                .entry("zipUrl".to_string())
                .or_insert_with(|| {
                    format!(
                        "https://github.com/{owner}/{repo_name}/releases/latest/download/{id}.zip"
                    )
                });
            template_vars
                .entry("changelog".to_string())
                .or_insert_with(|| {
                    format!("https://raw.githubusercontent.com/{owner}/{repo_name}/{default_branch}/CHANGELOG.md")
                });

            // 设置mmrl的repo section（如果有的话），填充更多字段
            kam_toml
                .mmrl
                .get_or_insert_with(crate::types::kam_toml::sections::MmrlSection::default);
            if let Some(mmrl) = &mut kam_toml.mmrl {
                if mmrl.repo.is_none() {
                    mmrl.repo = Some(crate::types::kam_toml::sections::RepoSection::default());
                }
                if let Some(repo) = &mut mmrl.repo {
                    // 设置仓库 URL
                    repo.repository = Some(args.source_url.clone().unwrap_or(repo_url));

                    // 设置 homepage（GitHub 仓库主页）
                    if repo.homepage.as_ref().is_none_or(String::is_empty) {
                        repo.homepage = Some(format!("https://github.com/{owner}/{repo_name}"));
                    }

                    // 设置 readme URL
                    if repo.readme.as_ref().is_none_or(String::is_empty) {
                        repo.readme = Some(format!(
                            "https://raw.githubusercontent.com/{owner}/{repo_name}/{default_branch}/README.md"
                        ));
                    }

                    // 设置 issues URL
                    if repo.issues.as_ref().is_none_or(String::is_empty) {
                        repo.issues =
                            Some(format!("https://github.com/{owner}/{repo_name}/issues"));
                    }

                    // 设置 documentation URL（如果有 docs 目录或 README）
                    if repo.documentation.as_ref().is_none_or(String::is_empty) {
                        repo.documentation = Some(format!(
                            "https://github.com/{owner}/{repo_name}/blob/{default_branch}/README.md",
                        ));
                    }

                    // 检测并设置许可证信息
                    if repo.license.as_ref().is_none_or(String::is_empty) {
                        // 尝试从 LICENSE 文件检测许可证类型
                        let license_paths = [
                            current_dir.join("LICENSE"),
                            current_dir.join("LICENSE.txt"),
                            current_dir.join("LICENSE.md"),
                            current_dir.join("license"),
                        ];

                        for license_path in &license_paths {
                            if let Ok(content) = std::fs::read_to_string(license_path) {
                                // 简单的许可证类型检测
                                let content_upper = content.to_uppercase();
                                if content_upper.contains("MIT") {
                                    repo.license = Some("MIT".to_string());
                                    repo.license_file = Some(
                                        license_path
                                            .file_name()
                                            .and_then(|s| s.to_str())
                                            .map_or_else(
                                                || "LICENSE".to_string(),
                                                ToString::to_string,
                                            ),
                                    );
                                    break;
                                } else if content_upper.contains("APACHE")
                                    && content_upper.contains("2.0")
                                {
                                    repo.license = Some("Apache-2.0".to_string());
                                    repo.license_file = Some(
                                        license_path
                                            .file_name()
                                            .and_then(|s| s.to_str())
                                            .map_or_else(
                                                || "LICENSE".to_string(),
                                                ToString::to_string,
                                            ),
                                    );
                                    break;
                                } else if content_upper.contains("GPL")
                                    && content_upper.contains("3.0")
                                {
                                    repo.license = Some("GPL-3.0".to_string());
                                    repo.license_file = Some(
                                        license_path
                                            .file_name()
                                            .and_then(|s| s.to_str())
                                            .map_or_else(
                                                || "LICENSE".to_string(),
                                                ToString::to_string,
                                            ),
                                    );
                                    break;
                                } else if content_upper.contains("GPL")
                                    && content_upper.contains("2.0")
                                {
                                    repo.license = Some("GPL-2.0".to_string());
                                    repo.license_file = Some(
                                        license_path
                                            .file_name()
                                            .and_then(|s| s.to_str())
                                            .map_or_else(
                                                || "LICENSE".to_string(),
                                                ToString::to_string,
                                            ),
                                    );
                                    break;
                                } else if content_upper.contains("BSD")
                                    && content_upper.contains('3')
                                {
                                    repo.license = Some("BSD-3-Clause".to_string());
                                    repo.license_file = Some(
                                        license_path
                                            .file_name()
                                            .and_then(|s| s.to_str())
                                            .map_or_else(
                                                || "LICENSE".to_string(),
                                                ToString::to_string,
                                            ),
                                    );
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    let source_url = args.source_url.clone().or(inferred_source_url);
    if let Some(source_url) = &source_url {
        kam_toml
            .mmrl
            .get_or_insert_with(crate::types::kam_toml::sections::MmrlSection::default);
        if let Some(mmrl) = &mut kam_toml.mmrl {
            if mmrl.repo.is_none() {
                mmrl.repo = Some(crate::types::kam_toml::sections::RepoSection::default());
            }
            if let Some(repo) = &mut mmrl.repo {
                repo.repository = Some(source_url.clone());
            }
        }
        template_vars.insert("source_url".to_string(), source_url.clone());
    }

    // 返回初始化数据，所有信息都准备好了
    Ok(PreInitData {
        path: project_path,
        id,
        name: project_name_str,
        version: version.to_string(),
        // author可能是None，用空字符串作为默认值
        // 虽然可能不太优雅，但至少不会panic
        author: kam_toml
            .prop
            .author
            .as_ref()
            .unwrap_or(&String::new())
            .clone(),
        description: description_str,
        update_json: kam_toml.prop.updateJson.clone(),
        source_url,
        template_vars,
        impl_template,
        module_type,
        kam_toml,
    })
    // 这个函数终于写完了，虽然有点长但逻辑还算清晰
    // TODO: 也许可以拆分成更小的函数？不过暂时先这样
}

// 解析git remote URL，提取owner和repo
// 支持：
// - git@github.com:owner/repo.git
// - https://github.com/owner/repo.git
fn parse_git_remote_url(remote: &str) -> Option<(String, String)> {
    let s = remote.trim();
    let s = if s.starts_with("git@") {
        // 把 git@ 格式转成 https:// 格式
        s.find(':').map_or_else(
            || s.to_string(),
            |idx| {
                let host = &s[4..idx];
                let path = &s[idx + 1..];
                format!("https://{host}/{path}")
            },
        )
    } else {
        s.to_string()
    };

    // 去掉scheme（https:// 或 http://）
    let path_start = s.find("//").map_or(0, |idx| idx + 2);
    let path = &s[path_start..];
    let parts: Vec<&str> = path.split('/').collect();
    if parts.len() >= 3 {
        let owner = parts[1].to_string();
        let mut repo = parts[2].to_string();
        // 去掉 .git 后缀 (case-insensitive)
        if std::path::Path::new(&repo)
            .extension()
            .and_then(|e| e.to_str())
            .is_some_and(|ext| ext.eq_ignore_ascii_case("git"))
        {
            repo.truncate(repo.len() - 4);
        }
        return Some((owner, repo));
    }
    None
}

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

    #[test]
    fn readme_description_skips_centered_html_header() {
        let readme = r#"<div align="center">

# MagicNet

![badge](https://img.shields.io/badge/test-pass-green)

MagicNet is a KernelSU network module for Android devices.
"#;

        assert_eq!(
            extract_readme_description(readme).as_deref(),
            Some("MagicNet is a KernelSU network module for Android devices.")
        );
    }
}
