use anyhow::{bail, Result};
use std::process::Command;

use crate::git::cli::GitCli;

impl GitCli {
    pub fn log(&self, repo_path: &str) -> Result<Vec<crate::app::state::CommitEntry>> {
        let output = Command::new("git")
            .args([
                "-C", repo_path,
                "log", "--oneline", "-n", "50",
                "--format=%H|%h|%s|%an|%ar"
            ])
            .output()?;

        if !output.status.success() {
            bail!(
                "git log failed (exit {}): {}",
                output.status,
                String::from_utf8_lossy(&output.stderr)
            );
        }

        let text = String::from_utf8_lossy(&output.stdout);
        let mut commits = Vec::new();
        for line in text.lines() {
            let parts: Vec<&str> = line.splitn(5, '|').collect();
            if parts.len() >= 5 {
                commits.push(crate::app::state::CommitEntry {
                    hash: parts[0].to_string(),
                    short_hash: parts[1].to_string(),
                    message: parts[2].to_string(),
                    author: parts[3].to_string(),
                });
            }
        }
        Ok(commits)
    }

    pub fn log_with_graph(&self, repo_path: &str, limit: usize) -> Result<String> {
        let output = Command::new("git")
            .args([
                "-C", repo_path,
                "log", "--graph", "--oneline", "--decorate", "--all",
                &format!("-n{}", limit)
            ])
            .output()?;

        if !output.status.success() {
            bail!(
                "git log --graph failed: {}",
                String::from_utf8_lossy(&output.stderr)
            );
        }
        Ok(String::from_utf8_lossy(&output.stdout).into_owned())
    }

    pub fn show_commit(&self, repo_path: &str, hash: &str) -> Result<String> {
        let output = Command::new("git")
            .args(["-C", repo_path, "show", "--stat", hash])
            .output()?;

        if !output.status.success() {
            bail!(
                "git show failed: {}",
                String::from_utf8_lossy(&output.stderr)
            );
        }
        Ok(String::from_utf8_lossy(&output.stdout).into_owned())
    }

}
