use std::process::Command;

use crate::api::WorkItemIdentifier;

/// Result of attempting to infer a work item identifier from the current git branch.
/// Names every outcome so callers can provide specific error messages for each case.
pub enum BranchInference {
    /// A work item identifier was found in the branch name (e.g. "feat/NRO-123-auth" -> NRO-123)
    Resolved(WorkItemIdentifier),
    /// The current directory is not a git repo, git is not installed, or HEAD is detached
    NotInGitRepo,
    /// A git branch was found but it does not contain a recognizable work item identifier
    NoIdentifierInBranch(String),
}

/// Reads the current git branch name and attempts to extract a work item identifier
/// by scanning for an UPPERCASE-DIGITS pattern (e.g. NRO-123 in "feat/NRO-123-add-auth").
/// Falls back gracefully when not in a git repo or when the branch has no identifier.
pub fn infer_work_item_from_branch() -> BranchInference {
    let git_output = match Command::new("git")
        .args(["branch", "--show-current"])
        .output()
    {
        Ok(command_output) => command_output,
        Err(_io_error) => return BranchInference::NotInGitRepo,
    };

    if !git_output.status.success() {
        return BranchInference::NotInGitRepo;
    }

    let branch_text = match String::from_utf8(git_output.stdout) {
        Ok(valid_text) => valid_text,
        Err(_encoding_error) => return BranchInference::NotInGitRepo,
    };

    let branch_name = branch_text.trim();
    if branch_name.is_empty() {
        return BranchInference::NotInGitRepo;
    }

    match WorkItemIdentifier::try_extract_from_branch(branch_name) {
        Option::Some(identifier) => BranchInference::Resolved(identifier),
        Option::None => BranchInference::NoIdentifierInBranch(branch_name.to_owned()),
    }
}
