use git2::{Commit, Repository};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct CommitInfo {
    pub id: String,
    pub message: String,
    pub author: String,
    pub date: String,
    pub repository: String,
}

#[tauri::command]
pub fn validate_repo_path(path: &str) -> Result<bool, String> {
    match Repository::open(path) {
        Ok(_) => Ok(true),
        Err(e) => Err(format!("无效的Git仓库路径: {}", e)),
    }
}

#[tauri::command]
pub fn get_commits(
    repo_path: &str,
    repo_name: &str,
    author_filter: Option<String>,
    time_range: Option<(i64, i64)>,
) -> Result<Vec<CommitInfo>, String> {
    let repo = match Repository::open(repo_path) {
        Ok(repo) => repo,
        Err(e) => return Err(format!("无法打开仓库: {}", e)),
    };

    let mut revwalk = match repo.revwalk() {
        Ok(revwalk) => revwalk,
        Err(e) => return Err(format!("无法遍历提交历史: {}", e)),
    };

    revwalk
        .push_head()
        .map_err(|e| format!("无法获取HEAD引用: {}", e))?;

    let commits: Result<Vec<CommitInfo>, _> = revwalk
        .filter_map(|id| id.ok())
        .filter_map(|id| repo.find_commit(id).ok())
        .filter(|commit| {
            if let Some(author) = &author_filter {
                if commit.author().email().unwrap_or("") != author {
                    return false;
                }
            }
            if let Some((start, end)) = time_range {
                let commit_time = commit.time().seconds();
                if commit_time < start || commit_time > end {
                    return false;
                }
            }
            true
        })
        .map(|commit: Commit| {
            Ok(CommitInfo {
                id: commit.id().to_string(),
                message: commit.message().unwrap_or("").to_string(),
                author: commit.author().name().unwrap_or("").to_string(),
                date: commit.time().seconds().to_string(),
                repository: repo_name.to_string(),
            })
        })
        .collect();

    commits.map_err(|e: Box<dyn std::error::Error>| format!("处理提交记录时出错: {}", e))
}
